Delete all sau đó insert hay update, insert cách nào tốt hơn?

Hiện mình có 1 list danh sách có 7 column và n records. Có thể add thêm và xóa records vào.
Và 1 button save all.
Chỉ khi click button save all mới thật sự lưu xuống Database.
Câu hỏi của mình là nên delete hết các records, sau đó insert mới.
Hay là sẽ update các records cũ và insert records mới?

Cách nào performance tốt hơn?

Theo ý kiến cá nhân thì nghiên về hướng delete all sau đó insert, bởi vì làm vậy đơn giản hơn. Đỡ tốn công vừa insert vừa update vừa delete

2 Likes

upsert :smiley: nhé, chứ xóa hết chịu j nổi.

5 Likes

Hi Nhat,

Về câu hỏi của cậu:

Tớ không nghĩ có ai trả lời được, vì performance phụ thuộc vào nhiều yếu tố:

  • Database engine (e.g: record của cậu bị lock theo record hay theo table…)
  • Cách tổ chức của dữ liệu (e.g: cách index dữ liệu…)
  • Số lượng record trong DB
  • Phần cứng (disk format…)

Với mỗi yếu tố, cậu sẽ có cách xử lý khác nhau. Vậy nên không có câu trả lời cho cậu nếu như cậu muốn hỏi về performance.

Đơn giản không đồng nghĩa với performance cao phải ko cậu? :slight_smile:


Tuy nhiên, trong TH của cậu, tớ nghĩ:

  • Cậu cần dùng transaction trong TH này. Thử nghĩ xem, nếu cậu delete hết data, rồi insert fail, cậu có bị đuổi không? :smile:
  • Nên delete + insert. Update sẽ lock write ít nhất record mà cậu đang thao tác, tệ hơn là lock write cả bảng với 1 số DB engine. Tuy nhiên, nếu cậu nhận thấy DB của cậu có phần cứng không tốt, chạy chậm khi high I/O, cậu có thể cân nhắc dùng update.
    Ngoài ra, upsert cũng là 1 sự lựa chọn tốt, miễn là cậu dùng transaction.

Performance sẽ thường là yếu tố cuối cùng cậu cân nhắc. An toàn, chính xác là nhất!

Hi vọng suggestion này giúp cậu :smile:

7 Likes

Yes, Mình hiểu ý bạn. Nhưng bạn nói câu này:

Cậu cần dùng transaction trong TH này. Thử nghĩ xem, nếu cậu delete hết data, rồi insert fail, cậu có bị đuổi không?

Ý câu này là nếu dùng trasaction thì sẽ tránh được TH mất dữ liệu.
Khi lỗi thì sẽ rollback lại được. Vậy thì delete và insert có vấn đề gì nhỉ?


Link cho bạn nào cần

2 Likes

Sao ko chọn những record nào thay đổi rồi upsert? Vì có phải record cũng cần lưu bản mới đâu ?

2 Likes

Nếu dùng transaction cậu sẽ tránh bị thiếu nhất quán dữ liệu.
Nếu cậu không dùng, dữ liệu của cậu hoàn toàn có thể bị không nhất quán nếu cậu đang delete dở/insert dở, dẫn tới việc lần tiếp theo cậu có thể insert phải record đã tồn tại rồi. Dễ hiểu phải không? :smiley:
Và cậu đúng, khi lỗi sẽ rollback lại được.

Oh, giờ tớ đã hiểu cậu đang nói về SQL (có vẻ như là MySQL). Và tớ nghĩ benchmark mà anh bạn reply trong câu hỏi ở link cậu share ở trên có lẽ còn thiếu 1 phần: cậu có thể delete nhiều record trong 1 câu delete, và cũng có thể bulk insert nhiều record cùng lúc -> giảm số lượng request tới DB.
Đồng thời anh bạn ấy cũng không nói rõ DB engine anh ấy dùng là gì (tớ đoán là InnoDB thôi :smile: ).

2 Likes

Tớ nghĩ đó cũng là 1 cách tốt cậu à :smiley: Thay vì delete + insert, giờ cậu có select + update + insert.
Tớ đoán implement lúc này sẽ hơi phức tạp chút, nên bạn ấy mới dùng delete + insert (lý do thuần tuý về simple implementation, không phải do performance).

2 Likes

Chọn record để thay đổi nằm ở frontend mà liên quan đến database đâu, m chưa thấy ae nào chơi kiểu delete hết rồi insert lại. :))
sửa 100 records mà tổng có 1 triệu records thì tính sao :))

5 Likes

Bạn không nói rõ là bạn lập trình trên desktop hay lập trình web. Khi mình mới đến với lập trình mình cũng loay hoay với mấy cái table. Khi nạp dữ liệu lên từ CSDL thì khi người ta sửa cái gì đó, họ bấm nút save xuống mình lại cập nhật xuống cả đống những cái không liên quan, lúc đó kể cả lập trình desktop và web đều làm như vậy, đơn giản vì lười và nghĩ rằng có lẽ mỗi trang có vài chục dòng (record sẽ ghi vào DB) thì cũng chẳng đáng là bao.

Nhưng một ngày kia, hệ thống nằm quay đơ bởi vì với 50 người nhập liệu cùng lúc, trong số đó có người sợ cúp điện hay ngứa tay gì đó nên họ cứ bấm nút save sau mỗi lần sửa xong một record. Vậy là mình đành ngồi suy nghĩ rằng phải làm cách nào đó để biết rằng dòng nào thực sự thay đổi dữ liệu thì mới save, còn những dòng khác cứ để im đó. Sau đó còn phát hiện ra điều khá thú vị đó là việc ghi và việc đọc gần như không gây xáo rộn lẫn nhau, cho nên những biểu ghi nào được cập nhật mình sẽ insert vào một table mới hoàn toàn, không hề đụng gì đến cái table cũ kia, đến nửa đêm thì mình mới cho nó chạy một script viết riêng cho việc merge cái table đó với cái table đã đọc lên để sửa.

Túm lại là nghĩ sao cứ làm vậy, một ngày nào đó sẽ trả một giá đắt vì lười suy nghĩ rồi sẽ có cách.

7 Likes

Hi An,

Thực ra là tớ đã từng thấy implement đó trên production rồi cậu :smiley:
Dĩ nhiên, solution đó chỉ áp dụng cho trường hợp không có quá nhiều record được target 1 lúc, đồng thời implementation sử dụng delete on multiple row using where clause & bulk insert query để thao tác -> cậu chỉ cần 2 queries cho tất cả thao tác, và nó cũng khá nhanh.

Nice point! Với TH đó, tớ nghĩ, một cách hợp lý, upsert sẽ là solution phù hợp.
Mỗi solution sẽ có pros/cons, và không thể áp dụng cho mọi TH. There is no silver bullet. Tớ nghĩ việc của kỹ sư nên là đánh giá solution đó theo mỗi TH cụ thể, từ đó lựa chọn ra solution phù hợp.

3 Likes

Ý em là người ta có thể thêm xóa, delete dòng thoải mái trên table, sau đó bấm save all thì mới thực hiện lưu xuông db. E không muốn kiêm tra data nào đã được delete, data nào update, data nào thêm mới nên xóa hết add lại cho tiện phải không?

3 Likes

Sợ đuổi việc không dám chơi kiểu delete ::))
Anh em trẻ khoẻ muốn thử cảm giác mạnh nhỉ ::))

4 Likes

@Ta_Nh_t

=> Nếu chỉ là quan tâm performance và simple thì tất nhiên Delete All rồi Insert là tốt nhất rồi. :laughing:

Tuy nhiên ở đây bài toán bạn đưa ra không nói rõ có yêu cầu về toàn vẹn dữ liệu, có xảy ra việc concurrent inserts không hoặc độ lớn của dữ liệu ra sao.

Nên các ý kiến từ nhiều góc độ khác nhau của các bạn ở trên là giá trị và nên tham khảo.

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?