Xóa vật lý so với logic / mềm của bản ghi cơ sở dữ liệu?


116

Lợi thế của việc thực hiện xóa hợp lý / mềm bản ghi (tức là đặt cờ cho biết bản ghi bị xóa) trái ngược với việc xóa bản ghi thực sự hoặc vật lý là gì?

Đây có phải là thông lệ?

Điều này có an toàn không?


22
Sử dụng xóa dấu thời gian, không sử dụng cờ.
Dave Jarvis

@DaveJarvis, bạn có thể giải thích tại sao sử dụng dấu thời gian là cách tiếp cận tốt hơn cho cờ không?
C Henry

4
Cờ không cung cấp bất kỳ thông tin nào về thời điểm hàng bị xóa. Thông tin tạm thời có nhiều cách sử dụng, bao gồm cả gỡ lỗi hệ thống.
Dave Jarvis

Câu trả lời:


70

Ưu điểm là bạn lưu giữ lịch sử (tốt cho việc kiểm tra) và bạn không phải lo lắng về việc xếp tầng xóa thông qua nhiều bảng khác nhau trong cơ sở dữ liệu tham chiếu đến hàng bạn đang xóa. Bất lợi là bạn phải viết bất kỳ phương pháp báo cáo / hiển thị nào để tính đến cờ.

Theo như nếu nó là một thực tế phổ biến - tôi sẽ nói là có, nhưng với bất cứ điều gì bạn sử dụng nó phụ thuộc vào nhu cầu kinh doanh của bạn.

CHỈNH SỬA: Suy nghĩ của người bất lợi khác - Nếu bạn có các chỉ mục duy nhất trên bảng, các bản ghi bị xóa sẽ vẫn chiếm bản ghi "một", vì vậy bạn cũng phải viết mã cho khả năng đó (ví dụ: bảng Người dùng có chỉ mục duy nhất trên tên người dùng; Một bản ghi đã bị xóa sẽ vẫn chặn tên người dùng đã xóa cho các bản ghi mới. Làm việc này, bạn có thể gắn GUID vào cột tên người dùng đã xóa, nhưng đó là một cách giải quyết rất khó hiểu mà tôi không khuyên dùng. Có thể trong trường hợp đó, nó sẽ tốt hơn là chỉ nên có một quy tắc rằng một khi tên người dùng được sử dụng, nó không bao giờ có thể được thay thế.)


Hiển thị dưới dạng người dùng Đang hoạt động / Đã hủy kích hoạt =) Một lưu ý khác nếu nó là một chỉ mục duy nhất (giả sử ở đây bạn có nghĩa là cơ sở dữ liệu đang kiểm soát chỉ mục duy nhất) bạn có nghĩa là gì - nó sẽ vẫn chặn tên người dùng đã bị xóa cho các bản ghi mới ??
Coops

@CodeBlend - Như tôi đã mô tả ở trên, nếu bạn có bảng Người dùng với chỉ mục duy nhất trên cột Tên người dùng, thì nếu bạn thực hiện xóa mềm / logic trên người dùng có tên "Chris Shaffer" thì tên người dùng đó sẽ không khả dụng cho một người mới người dùng để tạo tài khoản mới, trong khi nếu bạn thực hiện xóa cứng / thực thì tên người dùng sẽ khả dụng trở lại.
Chris Shaffer

À, tôi đang nghĩ về hàng chứ không phải tên của người dùng (tên người dùng). Nếu bạn muốn duy trì lịch sử đầy đủ, vì vậy nếu có 'đơn đặt hàng' hoặc thứ gì đó được liên kết với người dùng đó, thì bạn phải thực hiện xóa mềm / logic.
Coops

11
@ChrisShaffer Ngoài ra, thay vì GUID, người ta có thể chọn chỉ lập chỉ mục các hàng không bị xóa. Ví dụ: CREATE UNIQUE INDEX ... WHERE DELETED_AT is null(trong PostgreSQL) và sau đó tất cả các hàng có bất kỳ ngày xóa nào đều không được lập chỉ mục. (Họ có thể được đưa vào một chỉ số không duy nhất để thay thế.)
KajMagnus

6
@Chris Shaffer: Trích dẫn "bạn không cần phải lo lắng về việc xếp tầng xóa thông qua nhiều bảng khác nhau". Không đúng, bạn sẽ phải chuyển tiếp xóa mềm theo cách thủ công, đây là một điều rất khó khăn và gây ra sự mâu thuẫn. Đây thực sự là một bất lợi, bởi vì không còn thực thi mối quan hệ trọng điểm đối ngoại. Bạn sẽ sớm kết thúc với dữ liệu-rác.
Stefan Steiger

27

Các phép xóa hợp lý có phổ biến không? Vâng, tôi đã thấy điều này ở nhiều nơi. Chúng có an toàn không? Điều đó thực sự phụ thuộc vào chúng có kém an toàn hơn khi dữ liệu có trước khi bạn xóa nó không?

Khi tôi là Trưởng nhóm kỹ thuật, tôi yêu cầu nhóm của chúng tôi phải giữ mọi phần dữ liệu, vào thời điểm đó tôi biết rằng chúng tôi sẽ sử dụng tất cả dữ liệu đó để xây dựng các ứng dụng BI khác nhau, mặc dù vào thời điểm đó chúng tôi không biết các yêu cầu sẽ như thế nào. là. Mặc dù điều này là tốt từ quan điểm kiểm toán, khắc phục sự cố và báo cáo (Đây là trang web thương mại điện tử / công cụ cho các giao dịch B2B và nếu ai đó sử dụng một công cụ, chúng tôi muốn ghi lại nó ngay cả khi tài khoản của họ sau đó đã bị tắt), nó đã có một số nhược điểm.

Nhược điểm bao gồm (không bao gồm những người khác đã được đề cập):

  1. Hiệu suất Hàm ý của việc lưu giữ tất cả dữ liệu đó, Chúng tôi phát triển các chiến lược lưu trữ khác nhau. Ví dụ: một khu vực của ứng dụng đã gần tạo ra khoảng 1Gb dữ liệu mỗi tuần.
  2. Chi phí lưu giữ dữ liệu tăng theo thời gian, trong khi dung lượng đĩa rẻ, số lượng cơ sở hạ tầng để lưu giữ và quản lý địa hình dữ liệu cả trực tuyến và ngoại tuyến là rất nhiều. Cần rất nhiều đĩa để dự phòng và thời gian của mọi người để đảm bảo các bản sao lưu đang di chuyển nhanh chóng, v.v.

Khi quyết định sử dụng logic, xóa vật lý hoặc lưu trữ, tôi sẽ tự hỏi mình những câu hỏi sau:

  1. Đây là dữ liệu có thể cần được chèn lại vào bảng. Ví dụ: Tài khoản người dùng phù hợp với danh mục này vì bạn có thể kích hoạt hoặc hủy kích hoạt tài khoản người dùng. Nếu đây là trường hợp, một phép xóa hợp lý có ý nghĩa nhất.
  2. Có bất kỳ giá trị nội tại nào trong việc lưu trữ dữ liệu không? Nếu vậy thì bao nhiêu dữ liệu sẽ được tạo ra. Tùy thuộc vào điều này, tôi sẽ thực hiện xóa hợp lý hoặc thực hiện chiến lược lưu trữ. Hãy nhớ rằng bạn luôn có thể lưu trữ các bản ghi đã xóa một cách hợp lý.

Trong ví dụ về tài khoản người dùng của bạn, sẽ tốt nếu giữ những người dùng đã kích hoạt và đã hủy kích hoạt trong các bảng riêng biệt? Ví dụ. Activatedbảng và Deactivatedlược đồ bảng - Id,Name,etc..Hàng vào Activated- 1001,Smith007,etc...Khi anh ta bị hủy kích hoạt, sau đó chúng ta có thể xóa tất cả trừ cột ID cho thợ rèn Activatedvà thêm anh ta vào Deactivated.
Erran Morad

Di chuyển tất cả dữ liệu có lợi gì nếu bạn bỏ Id và hàng? Có thể nếu hồ sơ của bạn rất lớn nhưng tôi sẽ coi đó như một sự tối ưu hóa vi mô.
JoshBerke

Chúc may mắn với các ràng buộc khóa ngoại xếp tầng nếu bạn đang di chuyển dữ liệu quanh các bảng.
CAD bloke

20

Có thể hơi muộn nhưng tôi khuyên mọi người nên kiểm tra bài đăng trên blog của Pinal Dave về xóa logic / mềm:

Tôi chỉ không thích kiểu thiết kế [xóa mềm] này chút nào. Tôi tin tưởng chắc chắn vào kiến ​​trúc nơi chỉ dữ liệu cần thiết nên nằm trong một bảng duy nhất và dữ liệu vô dụng sẽ được chuyển sang một bảng được lưu trữ. Thay vì theo sau cột isDeleted, tôi đề xuất sử dụng hai bảng khác nhau: một bảng có các đơn đặt hàng và một bảng có các đơn đặt hàng đã xóa. Trong trường hợp đó, bạn sẽ phải bảo trì cả bàn, nhưng trên thực tế, nó rất dễ bảo trì. Khi bạn viết câu lệnh UPDATE vào cột isDeleted, hãy viết CHÈN VÀO bảng khác và XÓA nó khỏi bảng gốc. Nếu tình huống là khôi phục, hãy viết một CHÈN VÀO VÀ XÓA khác theo thứ tự ngược lại. Nếu bạn lo lắng về một giao dịch không thành công, hãy bọc mã này trong GIAO DỊCH.

Những lợi thế của bảng nhỏ hơn câu bảng lớn hơn trong các tình huống được mô tả ở trên là gì?

  • Một bảng nhỏ hơn dễ bảo trì
  • Các hoạt động xây dựng lại chỉ mục nhanh hơn nhiều
  • Di chuyển dữ liệu lưu trữ sang một nhóm tệp khác sẽ giảm tải cho nhóm tệp chính (xem xét rằng tất cả các nhóm tệp đều nằm trên hệ thống khác nhau) - điều này cũng sẽ tăng tốc độ sao lưu.
  • Thống kê sẽ được cập nhật thường xuyên do kích thước nhỏ hơn và điều này sẽ ít tốn tài nguyên hơn.
  • Kích thước của chỉ mục sẽ nhỏ hơn
  • Hiệu suất của bảng sẽ được cải thiện với kích thước bảng nhỏ hơn.

16
Làm thế nào bạn sẽ chăm sóc các khóa nước ngoài bằng cách sử dụng phương pháp như vậy? Có thể có 1, 10 hoặc nhiều bảng khác tham chiếu đến bản ghi đang bị xóa và chuyển sang bảng khác!
sam360

@ sam360 - đó là một thách thức lớn. Thành thật mà nói, cá nhân tôi đã thất bại trong việc triển khai khuyến nghị trên trong các dự án của mình, vì xử lý PK và mối quan hệ giữa các bảng. Thật không may, không có một ví dụ thực tế nào trong bài báo đó. Tôi đang nghiên cứu một giải pháp trong một trong những dự án của mình, nếu nó thực hiện tốt, tôi sẽ chia sẻ mã với bạn ...
Tohid

đó là những gì được gọi là ? thay vì xóa mềm?
eugene

1
@eugene - Tôi không biết bất kỳ thuật ngữ cụ thể nào cho giải pháp này. Đó là một hàng thực sự "xóa" và giữ các bản ghi đã xóa trong cách tiếp cận bảng "lưu trữ" , nếu nó có ý nghĩa với bạn.
Tohid

1
Tôi tin rằng, "Di chuyển các dữ liệu lưu trữ khác filegroup" có thể được thực hiện như phân vùng trong Oracle, vì vậy người ta có những lợi ích nêu trên ...
Betlista

14

Tôi là nhà phát triển NoSQL và trong công việc cuối cùng của mình, tôi đã làm việc với dữ liệu luôn quan trọng đối với ai đó và nếu dữ liệu đó bị xóa do vô tình vào cùng ngày được tạo, tôi sẽ không thể tìm thấy dữ liệu đó trong lần sao lưu cuối cùng từ hôm qua! Trong tình huống đó, tính năng xóa mềm luôn được lưu trong ngày.

Tôi đã xóa mềm bằng cách sử dụng dấu thời gian, đăng ký ngày tài liệu bị xóa:

IsDeleted = 20150310  //yyyyMMdd

Chủ nhật hàng tuần, một quy trình đi trên cơ sở dữ liệu và kiểm tra IsDeletedthực địa. Nếu sự khác biệt giữa ngày hiện tại và dấu thời gian lớn hơn N ngày, tài liệu sẽ bị xóa. Xem xét tài liệu vẫn có sẵn trên một số bản sao lưu, nó là an toàn để làm điều đó.

BIÊN TẬP: Trường hợp sử dụng NoSQL này là về các tài liệu lớn được tạo trong cơ sở dữ liệu, hàng chục hoặc hàng trăm chúng mỗi ngày, nhưng không phải hàng nghìn hoặc hàng triệu. Nói chung, chúng là các tài liệu với trạng thái, dữ liệu và tệp đính kèm của các quy trình dòng công việc. Đó là lý do tại sao có khả năng người dùng xóa một tài liệu quan trọng. Người dùng này có thể là người có đặc quyền Quản trị viên hoặc có thể là chủ sở hữu của tài liệu, chỉ để nêu tên một số người.

TL; DR Trường hợp sử dụng của tôi không phải là Dữ liệu lớn. Trong trường hợp đó, bạn sẽ cần một cách tiếp cận khác.


9

Một mẫu tôi đã sử dụng là tạo bảng nhân bản và đính kèm trình kích hoạt trên bảng chính, vì vậy tất cả các lần xóa (và cập nhật nếu muốn) đều được ghi lại trong bảng nhân bản.

Điều này cho phép bạn "xây dựng lại" các bản ghi đã xóa / thay đổi và bạn vẫn có thể xóa trong bảng chính và giữ cho nó "sạch" - nó cũng cho phép tạo chức năng "hoàn tác" và bạn cũng có thể ghi lại ngày, giờ và người dùng đã thực hiện hành động trong bảng phản chiếu (vô giá trong các tình huống săn phù thủy).

Ưu điểm khác là không có khả năng vô tình bao gồm các bản ghi đã xóa khi truy vấn ngoài bản ghi chính trừ khi bạn cố tình gặp rắc rối khi bao gồm các bản ghi từ bảng nhân bản (bạn có thể muốn hiển thị trực tiếp và các bản ghi đã xóa).

Một ưu điểm khác là bảng nhân bản có thể được xóa một cách độc lập, vì nó không nên có bất kỳ tham chiếu khóa ngoại thực tế nào, làm cho thao tác này tương đối đơn giản so với việc xóa khỏi bảng chính sử dụng xóa mềm nhưng vẫn có các kết nối tham chiếu đến các bảng khác.

Những lợi thế nào khác? - tuyệt vời nếu bạn có một loạt các lập trình viên làm việc trong dự án, đọc trên cơ sở dữ liệu với kỹ năng hỗn hợp và chú ý đến mức độ chi tiết, bạn không phải thức đêm hy vọng rằng một trong số họ không quên không xóa hồ sơ (lol, Không bao gồm Hồ sơ đã xóa = Đúng), dẫn đến những thứ như phóng đại nói rằng khách hàng có sẵn vị thế tiền mặt mà sau đó họ sẽ mua một số cổ phiếu (ví dụ như trong hệ thống giao dịch), khi bạn làm việc với hệ thống giao dịch, bạn sẽ nhanh chóng tìm ra giá trị của các giải pháp mạnh mẽ, mặc dù chúng có thể có "chi phí" ban đầu cao hơn một chút.

Các trường hợp ngoại lệ:
- như một hướng dẫn, hãy sử dụng tính năng xóa mềm cho dữ liệu "tham chiếu" như người dùng, danh mục, v.v. và xóa cứng đối với bảng phản chiếu cho dữ liệu kiểu "thực tế", tức là lịch sử giao dịch.


5

Tôi thường sử dụng tính năng xóa hợp lý - tôi thấy chúng hoạt động tốt khi bạn cũng lưu trữ liên tục dữ liệu 'đã xóa' vào một bảng đã lưu trữ (có thể được tìm kiếm nếu cần) do đó không có cơ hội ảnh hưởng đến hiệu suất của ứng dụng.

Nó hoạt động tốt vì bạn vẫn có dữ liệu nếu bạn đã từng được kiểm toán. Nếu bạn xóa nó về mặt vật lý, nó sẽ biến mất !


5

Tôi là một fan hâm mộ lớn của việc xóa hợp lý, đặc biệt là đối với ứng dụng Line of Business hoặc trong ngữ cảnh của tài khoản người dùng. Lý do của tôi rất đơn giản: đôi khi tôi không muốn người dùng có thể sử dụng hệ thống nữa (vì vậy tài khoản bị đánh dấu là đã bị xóa), nhưng nếu chúng tôi xóa người dùng, chúng tôi sẽ mất tất cả công việc của họ và những thứ tương tự.

Một tình huống phổ biến khác là người dùng có thể được tạo lại một thời gian sau khi bị xóa. Đó là một trải nghiệm tuyệt vời hơn cho người dùng khi có tất cả dữ liệu của họ hiện tại như trước khi chúng bị xóa, thay vì phải tạo lại nó.

Tôi thường nghĩ đến việc xóa người dùng nhiều hơn là "đình chỉ" họ vô thời hạn. Bạn không bao giờ biết khi nào họ cần quay lại một cách hợp pháp.


Chúng ta không nên sử dụng một cái gì đó như kích hoạt / hủy kích hoạt tài khoản thay vì xóa hợp lý ở đây? @ jon-dewees
Eagle_Eye

4

Tôi hầu như luôn luôn xóa mềm và đây là lý do tại sao:

  • bạn có thể khôi phục dữ liệu đã xóa nếu khách hàng yêu cầu bạn làm như vậy. Nhiều khách hàng hài lòng hơn với tính năng xóa mềm. Khôi phục dữ liệu cụ thể từ các bản sao lưu rất phức tạp
  • kiểm tra isdeletedmọi nơi không phải là một vấn đề, bạn phải kiểm tra bằng cách useridnào (nếu cơ sở dữ liệu chứa dữ liệu từ nhiều người dùng). Bạn có thể thực thi kiểm tra bằng mã, bằng cách đặt hai kiểm tra đó trên một chức năng riêng biệt (hoặc sử dụng các chế độ xem)
  • xóa duyên dáng. Người dùng hoặc quy trình xử lý nội dung đã xóa sẽ tiếp tục "nhìn thấy" nội dung đó cho đến khi họ nhấn lần làm mới tiếp theo. Đây là một tính năng rất đáng mong đợi nếu một tiến trình đang xử lý một số dữ liệu bị xóa đột ngột
  • đồng bộ hóa: nếu bạn cần thiết kế cơ chế đồng bộ hóa giữa cơ sở dữ liệu và ứng dụng dành cho thiết bị di động, bạn sẽ thấy xóa mềm dễ thực hiện hơn nhiều

@Jim lưu giữ dữ liệu vào cơ sở dữ liệu, nó không phải là bất hợp pháp. sẽ là bất hợp pháp nếu bạn giữ hồ sơ ngay cả sau khi khách hàng yêu cầu bạn xóa dữ liệu của chính họ. Xóa mềm hoàn toàn tương thích với GDPR: theo yêu cầu, chỉ cần ghi đè dữ liệu hợp lý bằng dữ liệu trống. Hơn nữa, nếu người dùng xóa bản ghi, họ có thể muốn hoàn tác hành động sau này hoặc khôi phục dữ liệu bằng cách nào đó ... điều đó không có nghĩa là anh ta / cô ta muốn dữ liệu biến mất hoàn toàn khỏi cơ sở dữ liệu
Gianluca Ghettini

3

Re: "Cái này có an toàn không?" - điều đó tùy thuộc vào ý bạn.

Nếu bạn muốn nói rằng bằng cách thực hiện xóa vật lý, bạn sẽ ngăn không cho bất kỳ ai tìm thấy dữ liệu đã xóa , thì vâng, điều đó ít nhiều đúng; bạn an toàn hơn khi xóa dữ liệu nhạy cảm cần xóa về mặt vật lý, vì điều đó có nghĩa là dữ liệu đó vĩnh viễn biến mất khỏi cơ sở dữ liệu. (Tuy nhiên, hãy nhận biết rằng có thể có các bản sao khác của dữ liệu được đề cập, chẳng hạn như trong một bản sao lưu hoặc nhật ký giao dịch, hoặc một phiên bản được ghi lại từ khi chuyển tiếp, ví dụ như trình đánh hơi gói - chỉ vì bạn xóa khỏi cơ sở dữ liệu của mình đảm bảo nó không được lưu ở một nơi khác.)

Nếu ý bạn là bằng cách xóa hợp lý, dữ liệu của bạn sẽ an toàn hơn vì bạn sẽ không bao giờ mất bất kỳ dữ liệu nào , điều đó cũng đúng. Điều này tốt cho các tình huống kiểm toán; Tôi có xu hướng thiết kế theo cách này vì nó thừa nhận một thực tế cơ bản rằng một khi dữ liệu được tạo ra, nó sẽ không bao giờ thực sự biến mất (đặc biệt nếu nó từng có khả năng được lưu trong bộ nhớ cache bởi một công cụ tìm kiếm trên internet). Tất nhiên, một kịch bản kiểm toán thực tế yêu cầu không chỉ xóa logic mà còn phải ghi nhật ký các cập nhật, cùng với thời gian thay đổi và tác nhân thực hiện thay đổi.

Nếu bạn có nghĩa là dữ liệu sẽ không rơi vào tay của bất kỳ ai không được phép nhìn thấy nó, thì điều đó hoàn toàn phụ thuộc vào ứng dụng của bạn và cấu trúc bảo mật của nó. Về mặt đó, xóa logic không an toàn hơn hoặc kém hơn bất kỳ thứ gì khác trong cơ sở dữ liệu của bạn.


3

Tôi hoàn toàn không đồng ý với cách xóa hợp lý vì bạn có nhiều lỗi.

Trước hết các truy vấn, mỗi truy vấn phải quan tâm đến trường IsDeleted và khả năng lỗi trở nên cao hơn với các truy vấn phức tạp.

Thứ hai về hiệu suất: hãy tưởng tượng một bảng có 100000 recs chỉ có 3 hoạt động, bây giờ nhân số này cho các bảng trong cơ sở dữ liệu của bạn; một vấn đề hiệu suất khác là xung đột có thể xảy ra với các bản ghi mới với các bản ghi cũ (đã bị xóa).

Ưu điểm duy nhất tôi thấy là lịch sử của các bản ghi, nhưng có những phương pháp khác để đạt được kết quả này, ví dụ như bạn có thể tạo một bảng ghi nhật ký nơi bạn có thể lưu thông tin: có thể TableName,OldValues,NewValues,Date,User,[..]ở đâu và viết chi tiết vào biểu mẫu này ; [..] hoặc lưu trữ thông tin dưới dạng .*Valuesvarcharfieldname : valuexml

Tất cả điều này có thể đạt được thông qua mã hoặc Trình kích hoạt nhưng bạn chỉ là MỘT bảng với tất cả lịch sử của bạn. Một tùy chọn khác là xem liệu công cụ cơ sở dữ liệu được chỉ định có hỗ trợ riêng cho việc theo dõi thay đổi hay không, ví dụ: trên cơ sở dữ liệu SQL Server có SQL Track Data Change.


3

Tôi đã từng thực hiện xóa mềm, chỉ để giữ các bản ghi cũ. Tôi nhận ra rằng người dùng không bận tâm xem các bản ghi cũ thường xuyên như tôi nghĩ. Nếu người dùng muốn xem các bản ghi cũ, họ chỉ có thể xem từ kho lưu trữ hoặc bảng kiểm tra, phải không? Vậy, lợi thế của xóa mềm là gì? Nó chỉ dẫn đến câu lệnh truy vấn phức tạp hơn, v.v.

Sau đây là những thứ tôi đã triển khai, trước khi tôi quyết định không xóa mềm nữa:

  1. thực hiện kiểm toán, để ghi lại tất cả các hoạt động (thêm, sửa, xóa). Đảm bảo rằng không có khóa ngoại nào được liên kết để kiểm tra và đảm bảo bảng này được bảo mật và không ai có thể xóa ngoại trừ quản trị viên.

  2. xác định bảng nào được coi là "bảng giao dịch", rất có thể nó sẽ được lưu giữ trong thời gian dài và rất có thể người dùng muốn xem các bản ghi hoặc báo cáo trong quá khứ. Ví dụ; giao dịch mua. Bảng này không nên chỉ giữ id của bảng chính (chẳng hạn như dept-id), mà còn giữ thông tin bổ sung như tên dưới dạng tham chiếu (chẳng hạn như dept-name) hoặc bất kỳ trường cần thiết nào khác để báo cáo.

  3. Thực hiện bản ghi "hoạt động / không hoạt động" hoặc "bật / tắt" hoặc "ẩn / hiện" của bảng chính. Vì vậy, thay vì xóa bản ghi, người dùng có thể vô hiệu hóa / không hoạt động bản ghi chính. Nó an toàn hơn nhiều theo cách này.

Chỉ là ý kiến ​​hai xu của tôi.


2

Xóa hợp lý nếu khó tính toàn vẹn tham chiếu.

Đó là suy nghĩ đúng đắn nên làm khi có khía cạnh tạm thời của dữ liệu bảng (có giá trị từ FROM_DATE - TO_DATE).

Nếu không, hãy di chuyển dữ liệu sang Bảng kiểm toán và xóa bản ghi.

Về mặt tích cực:

Đây là cách dễ dàng hơn để khôi phục (nếu có thể).

Có thể dễ dàng nhận ra trạng thái tại một thời điểm cụ thể.


2

Nó khá chuẩn trong những trường hợp bạn muốn giữ lịch sử của một thứ gì đó (ví dụ: tài khoản người dùng như @Jon Dewees đề cập). Và chắc chắn đó là một ý tưởng tuyệt vời nếu có nhiều khả năng người dùng yêu cầu hủy xóa.

Nếu bạn lo lắng về logic của việc lọc ra các bản ghi đã xóa khỏi các truy vấn của bạn trở nên lộn xộn và chỉ làm phức tạp các truy vấn của bạn, bạn chỉ có thể xây dựng các dạng xem thực hiện việc lọc cho bạn và sử dụng các truy vấn chống lại điều đó. Nó sẽ ngăn chặn việc rò rỉ các bản ghi này trong các giải pháp báo cáo và tương tự.


2

Có những yêu cầu ngoài thiết kế hệ thống cần được giải đáp. Yêu cầu pháp lý hoặc luật định trong việc lưu giữ hồ sơ là gì? Tùy thuộc vào những gì các hàng liên quan đến, có thể có một yêu cầu pháp lý rằng dữ liệu được lưu giữ trong một khoảng thời gian nhất định sau khi nó bị 'tạm ngưng'.

Mặt khác, yêu cầu có thể là một khi bản ghi bị 'xóa', nó thực sự bị xóa và không thể thu hồi. Trước khi bạn đưa ra quyết định, hãy nói chuyện với các bên liên quan của bạn.


2

Các ứng dụng dành cho thiết bị di động phụ thuộc vào đồng bộ hóa có thể áp đặt việc sử dụng logic thay vì xóa vật lý: máy chủ phải có khả năng cho khách hàng biết rằng bản ghi đã bị (đánh dấu là) bị xóa và điều này có thể không khả thi nếu bản ghi đã bị xóa thực tế.


1

Họ không cho phép cơ sở dữ liệu hoạt động vì nó sẽ làm cho những thứ như chức năng thác nước trở nên vô dụng.

Đối với những thứ đơn giản như chèn, trong trường hợp chèn lại, thì mã đằng sau nó tăng gấp đôi.

Bạn không thể chỉ chèn đơn giản, thay vào đó bạn phải kiểm tra sự tồn tại và chèn nếu nó không tồn tại trước đó hoặc cập nhật cờ xóa nếu nó tồn tại trong khi cũng cập nhật tất cả các cột khác thành giá trị mới. Đây được coi là bản cập nhật cho nhật ký giao dịch cơ sở dữ liệu và không phải là một phụ trang mới gây ra nhật ký kiểm tra không chính xác.

Chúng gây ra các vấn đề về hiệu suất vì các bảng đang được gắn với dữ liệu dư thừa. Nó đóng vai trò khó khăn với việc lập chỉ mục đặc biệt là với tính duy nhất.

Tôi không phải là một fan hâm mộ lớn của việc xóa logic.


1

Để trả lời bình luận của Tohid, chúng tôi phải đối mặt với cùng một vấn đề là chúng tôi muốn duy trì lịch sử của các bản ghi và chúng tôi cũng không chắc liệu chúng tôi có muốn is_deletedcột hay không.

Tôi đang nói về việc triển khai python của chúng tôi và một trường hợp sử dụng tương tự mà chúng tôi đã gặp phải.

Chúng tôi đã gặp https://github.com/kvesteri/sqlalchemy-continuum , đây là một cách dễ dàng để tải bảng phiên bản cho bảng tương ứng của bạn. Dòng mã tối thiểu và ghi lại lịch sử để thêm, xóa và cập nhật.

Điều này phục vụ nhiều hơn chỉ is_deletedcột. Bạn luôn có thể backref bảng phiên bản để kiểm tra những gì đã xảy ra với mục nhập này. Cho dù mục nhập đã bị xóa, cập nhật hoặc thêm vào.

Bằng cách này, chúng tôi không cần phải có is_deletedcột và chức năng xóa của chúng tôi khá đơn giản. Bằng cách này, chúng tôi cũng không cần phải nhớ đánh dấu is_deleted=Falsetrong bất kỳ api nào của chúng tôi.


0

Soft Delete là một thực hành lập trình được tuân theo trong hầu hết các ứng dụng khi dữ liệu có liên quan hơn. Hãy xem xét một trường hợp ứng dụng tài chính mà việc xóa do nhầm lẫn của người dùng cuối có thể gây tử vong. Đó là trường hợp khi xóa mềm trở nên phù hợp. Trong xóa mềm, người dùng không thực sự xóa dữ liệu khỏi bản ghi thay vào đó nó được gắn cờ là IsDeleted thành true (Theo quy ước thông thường).

Trong EF 6.x hoặc EF 7 trở đi Softdelete được Thêm vào dưới dạng một thuộc tính nhưng chúng tôi phải tạo một thuộc tính tùy chỉnh vào lúc này.

Tôi thực sự khuyên bạn nên sử dụng SoftDelete Trong một thiết kế cơ sở dữ liệu và nó là một quy ước tốt cho việc thực hành lập trình.


0

Phần lớn thời gian sử dụng softdeleting vì bạn không muốn để lộ một số dữ liệu nhưng bạn phải giữ nó vì lý do lịch sử (Một sản phẩm có thể bị ngừng sản xuất, vì vậy bạn không muốn có bất kỳ giao dịch mới nào với nó nhưng bạn vẫn cần phải làm việc với lịch sử của giao dịch bán). Nhân tiện, một số đang sao chép giá trị thông tin sản phẩm trong dữ liệu giao dịch bán hàng thay vì tham chiếu đến sản phẩm để xử lý việc này.

Trên thực tế, nó trông giống như một bản ghi lại cho một tính năng hiển thị / ẩn hoặc hoạt động / không hoạt động. Bởi vì đó là ý nghĩa của "xóa" trong thế giới kinh doanh. Tôi muốn nói rằng Kẻ hủy diệt có thể xóa mọi người nhưng ông chủ chỉ cần sa thải họ.

Cách làm này khá phổ biến và được rất nhiều ứng dụng sử dụng vì nhiều lý do. Vì đó không phải là cách duy nhất để đạt được điều này, vì vậy bạn sẽ có hàng nghìn người nói rằng điều đó tuyệt vời hoặc nhảm nhí và cả hai đều có những lập luận khá tốt.

Từ quan điểm bảo mật, SoftDelete sẽ không thay thế công việc Kiểm toán và nó cũng sẽ không thay thế công việc sao lưu. Nếu bạn sợ "sự chèn / xóa giữa hai trường hợp sao lưu", bạn nên đọc về Mô hình khôi phục toàn bộ hoặc hàng loạt. Tôi thừa nhận rằng SoftDelete có thể làm cho quá trình khôi phục trở nên đơn giản hơn.

Tùy thuộc vào bạn để biết yêu cầu của bạn.


0

Để đưa ra một giải pháp thay thế, chúng tôi yêu cầu người dùng sử dụng thiết bị từ xa cập nhật qua MobiLink. Nếu chúng tôi xóa các bản ghi trong cơ sở dữ liệu máy chủ, các bản ghi đó sẽ không bao giờ được đánh dấu là đã xóa trong cơ sở dữ liệu máy khách.

Vì vậy, chúng tôi làm cả hai. Chúng tôi làm việc với khách hàng của mình để xác định xem họ muốn khôi phục dữ liệu trong bao lâu. Ví dụ: nói chung, khách hàng và sản phẩm đang hoạt động cho đến khi khách hàng của chúng tôi nói rằng chúng nên bị xóa, nhưng lịch sử bán hàng chỉ được lưu giữ trong 13 tháng và sau đó sẽ tự động xóa. Khách hàng có thể muốn giữ lại khách hàng và sản phẩm đã xóa trong hai tháng nhưng giữ lại lịch sử trong sáu tháng.

Vì vậy, chúng tôi chạy một tập lệnh qua đêm để đánh dấu những thứ đã xóa một cách hợp lý theo các thông số này và sau đó hai / sáu tháng sau, bất kỳ thứ gì được đánh dấu hợp lý bị xóa ngày hôm nay sẽ bị xóa cứng.

Chúng ta không đề cập đến vấn đề bảo mật dữ liệu hơn là về việc có cơ sở dữ liệu khổng lồ trên thiết bị khách có bộ nhớ hạn chế, chẳng hạn như điện thoại thông minh. Một khách hàng đặt 200 sản phẩm hai lần một tuần trong bốn năm sẽ có hơn 81.000 dòng lịch sử, trong đó 75% khách hàng không quan tâm nếu họ nhìn thấy.


0

Tất cả phụ thuộc vào trường hợp sử dụng của hệ thống và dữ liệu của nó.

Ví dụ: nếu bạn đang nói về hệ thống do chính phủ quản lý (ví dụ như hệ thống tại một công ty dược phẩm được coi là một phần của hệ thống chất lượng và phải tuân theo các hướng dẫn của FDA về hồ sơ điện tử), thì tốt hơn hết bạn không nên xóa khó! Một kiểm toán viên của FDA có thể đến và yêu cầu tất cả hồ sơ trong hệ thống liên quan đến số sản phẩm ABC-123, và tốt hơn là tất cả dữ liệu đều có sẵn. Nếu chủ sở hữu quy trình kinh doanh của bạn cho biết hệ thống không cho phép bất kỳ ai sử dụng số sản phẩm ABC-123 trên các bản ghi mới về sau, hãy sử dụng phương pháp xóa mềm thay thế để làm cho nó "không hoạt động" trong hệ thống, trong khi vẫn bảo toàn dữ liệu lịch sử.

Tuy nhiên, có thể hệ thống của bạn và dữ liệu của nó có một trường hợp sử dụng như "theo dõi thời tiết tại Bắc Cực". Có thể bạn đo nhiệt độ mỗi giờ một lần và vào cuối ngày tổng hợp mức trung bình hàng ngày. Có thể dữ liệu hàng giờ sẽ không còn được sử dụng sau khi tổng hợp và bạn sẽ cố gắng xóa các kết quả đọc hàng giờ sau khi tạo tổng hợp. (Đây là một ví dụ đơn giản, nhỏ nhặt.)

Vấn đề là, tất cả phụ thuộc vào trường hợp sử dụng của hệ thống và dữ liệu của nó, chứ không phải quyết định được đưa ra hoàn toàn từ quan điểm công nghệ.


0

Tốt! Như mọi người đã nói, tùy trường hợp.

Nếu bạn có một chỉ mục trên một cột như UserName hoặc EmailID - và bạn không bao giờ mong đợi UserName hoặc EmailID tương tự được sử dụng lại; bạn có thể xóa mềm.

Điều đó nói rằng, hãy luôn kiểm tra xem hoạt động SELECT của bạn có sử dụng khóa chính hay không. Nếu câu lệnh SELECT của bạn sử dụng khóa chính, thì việc thêm cờ với mệnh đề WHERE sẽ không tạo ra nhiều khác biệt. Hãy lấy một ví dụ (Pseudo):

Người dùng bảng (UserID [khóa chính], EmailID, Bị xóa)

SELECT * FROM Users where UserID = 123456 and IsDeleted = 0

Truy vấn này sẽ không tạo ra bất kỳ sự khác biệt nào về mặt hiệu suất vì cột UserID có khóa chính. Ban đầu, nó sẽ quét bảng dựa trên PK và sau đó thực hiện điều kiện tiếp theo.

Các trường hợp xóa mềm hoàn toàn không hoạt động:

Đăng ký chủ yếu là tất cả các trang web lấy EmailID làm nhận dạng duy nhất của bạn. Chúng tôi biết rất rõ, một khi một EmailID được sử dụng trên một trang web như facebook, G + thì nó không thể được sử dụng bởi bất kỳ ai khác.

Sẽ có một ngày khi người dùng muốn xóa hồ sơ của mình khỏi trang web. Bây giờ, nếu bạn thực hiện xóa hợp lý, người dùng đó sẽ không thể đăng ký lại. Ngoài ra, đăng ký lại bằng cùng một EmailID không có nghĩa là khôi phục toàn bộ lịch sử. Mọi người đều biết, xóa có nghĩa là xóa. Trong các tình huống như vậy, chúng tôi phải thực hiện xóa thực tế. Nhưng để duy trì toàn bộ lịch sử của tài khoản, chúng ta phải luôn lưu trữ các bản ghi đó trong bảng lưu trữ hoặc bảng đã xóa.

Đúng vậy, trong những tình huống chúng ta có nhiều bàn ngoại, việc xử lý khá rườm rà.

Cũng nên nhớ rằng việc xóa mềm / logic sẽ làm tăng kích thước bảng của bạn, vì vậy kích thước chỉ mục.


0

Tôi đã trả lời trong một bài viết khác . Tuy nhiên, tôi nghĩ câu trả lời của tôi phù hợp hơn với câu hỏi ở đây.

Giải pháp thực tế của tôi cho mềm xóa được lưu trữ bằng cách tạo ra một bảng mới với các cột sau: original_id, table_name, payload, (và một tùy chọn chính chìa khóa 'id).

Trong trường hợp original_idlà id ban đầu của kỷ lục bị xóa, table_name là tên bảng của hồ sơ xóa ( "user"trong trường hợp của bạn), payloadlà JSON-chuyển đổi thành chuỗi chuỗi từ tất cả các cột của bản ghi bị xóa.

Tôi cũng khuyên bạn nên tạo một chỉ mục trên cột original_idđể truy xuất dữ liệu sau này.

Bằng cách này để lưu trữ dữ liệu. Bạn sẽ có những lợi thế này

  • Theo dõi tất cả dữ liệu trong lịch sử
  • Chỉ có một nơi để lưu trữ bản ghi từ bất kỳ bảng nào, bất kể cấu trúc bảng của bản ghi đã bị xóa
  • Không phải lo lắng về chỉ mục duy nhất trong bảng gốc
  • Không phải lo lắng về việc kiểm tra chỉ mục nước ngoài trong bảng gốc
  • Không còn WHEREmệnh đề nào trong mọi truy vấn để kiểm tra việc xóa

Đó đã là một cuộc thảo luận ở đây giải thích tại sao mềm xóa không phải là một ý tưởng tốt trong thực tế. Soft-delete giới thiệu một số rắc rối có thể xảy ra trong tương lai như đếm bản ghi, ...


Tôi đã viết một bài đăng blog trên tất cả các cách để xóa dữ liệu transang.me/database-design-practice-soft-deletion-to
transang

0

Những cuộc phiêu lưu là bảo toàn / tồn tại dữ liệu. Một lỗi sẽ làm giảm hiệu suất khi truy vấn hoặc truy xuất dữ liệu từ các bảng có số lượng xóa mềm đáng kể. Trong trường hợp của chúng tôi, chúng tôi sử dụng kết hợp cả hai: như những người khác đã đề cập trong các câu trả lời trước, chúng tôi soft-delete users/clients/customerschẳng hạn và hard-deletetrên items/products/merchandisecác bảng nơi có các bản ghi trùng lặp mà không cần phải lưu giữ.


0

Tùy thuộc vào từng trường hợp, hãy xem xét những điều dưới đây:

Thông thường, bạn không cần phải "xóa mềm" một bản ghi. Giữ cho nó đơn giản và nhanh chóng. Ví dụ: Xóa một sản phẩm không còn khả dụng nữa, vì vậy bạn không cần phải kiểm tra xem sản phẩm đó có bị xóa mềm trên ứng dụng của bạn không (số lượng, danh sách sản phẩm, sản phẩm được đề xuất, v.v.).

Tuy nhiên, bạn có thể xem xét "xóa mềm" trong mô hình kho dữ liệu. ví dụ: Bạn đang xem biên lai cũ trên một sản phẩm đã bị xóa. *

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.