Cascading xóa Xóa các bản ghi mà không thực sự bị xóa


8

Chỉ cần cố gắng để có được một số ý tưởng về những gì mọi người làm cho kịch bản này. Chúng tôi có cơ sở dữ liệu hệ thống (SQL Server 2008 R2) có các bảng và mỗi bảng có một trường mà chúng tôi có thể gọi là "Đã xóa". Về cơ bản, đó là trường bit nếu bản ghi 1 bị xóa, nếu là 0 thì không bị xóa. Trường này là nullable và mặc định của nó là 0.

Chúng tôi không thể cho phép xóa thực sự vào cơ sở dữ liệu, vì vậy để giải quyết vấn đề này, chúng tôi đặt trường bit (Đã xóa) thành đúng. Trong ứng dụng của chúng tôi, chúng tôi kết thúc với các truy vấn trông như thế này:

SELECT blah FROM MyTable WHERE .. AND Deleted=0

Về cơ bản chúng tôi lọc các bản ghi để chúng tôi chỉ nhận được các hàng không bị xóa. Vấn đề của chúng tôi là hồ sơ liên quan cần xếp tầng. Mọi người thích gì hơn, chúng ta có nên làm điều này trong mã phía máy chủ để khi bạn xóa một bản ghi thì nó sẽ xóa (Đặt trường bit bị xóa thành đúng) cho tất cả các bản ghi liên quan? Hoặc đây có nên là một trình kích hoạt phải kiểm tra trường này và đặt trường bit cho tất cả các bản ghi liên quan thành 1 không?

Hay chúng ta hoàn toàn đi sai đường?


sử dụng chế độ xem để xóa không bao giờ lọt vào hình ảnh và nhóm trên bitfield đó
ratchet freak

@ratchetfreak - điều này không giúp ích gì cho các hồ sơ liên quan ... làm thế nào để bạn xử lý các tầng của việc xóa. Hãy tưởng tượng một trang công ty có các vấn đề liên quan, nếu ai đó xóa công ty (đặt Company.Delatted = 1) làm thế nào để bạn xóa các vấn đề liên quan đến công ty đó?
JonH

2
điều duy nhất tự động hóa nó là một trình kích hoạt cập nhật
ratchet freak

1
@ratchetfreak - Đó là loại câu hỏi của tôi, chúng ta nên xử lý nó thông qua một trình kích hoạt cập nhật, hoặc thông qua mã phía máy chủ, và tại sao. Tôi sắp xếp để biết câu trả lời cho điều này. Tôi chỉ hy vọng có được ý tưởng về những gì người khác làm để xóa mềm - làm thế nào bạn có thể xóa các mối quan hệ (xóa tầng có bạn mà không thực sự xóa).
JonH

2
Tại sao bạn cần xóa dữ liệu liên quan? Nếu cha mẹ của dữ liệu liên quan không thể truy cập, làm thế nào bạn sẽ truy cập nó?
Kevin

Câu trả lời:


2

Không có giải pháp tốt ở đây. Cơ sở dữ liệu cung cấp xóa tầng đặc biệt, hiệu quả thông qua các khóa ngoại, nhưng nếu như bạn nói, xóa thực tế không phải là một tùy chọn, thì bạn không thể tận dụng tầng đó.

Tùy thuộc vào việc xóa là một sự cố phổ biến hay hiếm gặp, sẽ hiệu quả hơn khi mô phỏng xếp tầng ngay lập tức (thông qua các truy vấn hoặc trình kích hoạt bổ sung) khi bạn giả mạo xóa một cái gì đó, hoặc chỉ luôn lấy mọi thứ từ DB và lọc khi xóa cờ trong logic kinh doanh.

Cá nhân tôi đã luôn sử dụng tùy chọn thứ ba: tất cả các bản ghi công ty con chỉ có thể truy cập được từ bản ghi chính, điều này sẽ không bao giờ xảy ra nếu bản đó bị xóa mềm, do đó bạn không cần phải làm gì cả! Rõ ràng điều này chỉ hoạt động nếu mô hình dữ liệu của bạn là một cây nghiêm ngặt (các nhận xét chỉ được truy xuất khi xem sản phẩm họ áp dụng, đặc quyền người dùng chỉ được truy xuất khi quản trị người dùng mà họ thuộc về, v.v.) chứ không phải là một trang web (nơi bạn có thể truy vấn tất cả các bình luận hoặc tất cả các hồ sơ đặc quyền một cách thờ ơ), nhưng tôi thấy rằng điều này có thể được thực hiện để làm việc cho nhiều tình huống đáng ngạc nhiên.


@Killian - Tôi tin rằng đây có thể là con đường chúng ta phải đi (kích hoạt). Tuy nhiên, với tư cách là một nhóm chúng ta cần thảo luận nhiều hơn với các bên liên quan về những gì nên hay không nên xếp tầng. Cảm ơn cho đầu vào tuyệt vời của bạn.
JonH

5

Tôi đã thực hiện điều này trước đây với các bảng kiểm toán, theo đó mọi thay đổi đối với cơ sở dữ liệu được ghi vào bảng nhân bản kiểm toán (Chèn / Cập nhật / Xóa) và các mục thực tế thực sự bị xóa theo cách xếp tầng.

Các bảng nhân bản giống hệt với bảng thực với việc thêm 3 cột, "ChangeType", "Người dùng", "Ngày".

Điều này có lợi thế kép là có thể xóa dữ liệu chính xác nhưng cũng cho phép trạng thái của cơ sở dữ liệu được tạo lại tại bất kỳ thời điểm nào và cho toàn bộ lịch sử của bất kỳ mục nào được ghi lại.

Tôi sẽ thêm rằng để xóa xếp tầng, nói chung tôi thích xóa tầng trên máy khách - máy chủ không nên quá thông minh về việc này, nếu người dùng xóa công ty và có vấn đề liên quan - hành động xóa công ty cũng nên xóa bất kỳ hồ sơ tương ứng.

Đây là hệ thống quản lý tài chính cho một ngân hàng đầu tư lớn nên khả năng kiểm toán là một tính năng quan trọng.


Tôi có thể xem đây là một cách và chúng tôi nghĩ về nó nhưng tôi tin rằng nó phù hợp với các hệ thống loại tài chính. Chúng tôi sẽ phải nhân đôi rất nhiều bảng và mối quan hệ khác và cơ sở mã sẽ phát triển đáng kể. Tuy nhiên, tôi có thể thấy sự cần thiết trong trường hợp của bạn.
JonH

Sao chép các bảng không thành vấn đề nếu các bảng kiểm toán được tự động triển khai và giữ đồng bộ - giống với mã, tất cả những gì chúng tôi phải làm là cung cấp một trình tạo ở lớp dữ liệu để chuyển giữa các bảng kiểm toán và các bảng trực tiếp - tất cả các truy vấn giữ nguyên
Michael

Michael nếu bạn không phiền tôi hỏi đội ngũ các nhà phát triển của bạn cho một dự án như thế này lớn đến mức nào?
JonH

Cách đây một thời gian nên tôi không chắc chắn 100% nhưng tôi nghĩ 4 nhà phát triển, 3 người thử nghiệm và 1 nhà phân tích.
Michael

1

Làm điều đó rõ ràng trên câu lệnh xóa / hủy xóa. Có thể có một số tình huống mà bạn không muốn xếp tầng xóa.

> Update table1 set deleted=@flag where...
> Update table2 set deleted=@flag where...

Ví dụ; xem xét một người có nhiều địa chỉ.

Xóa người, chỉ cần đặt cờ Xóa trên người. Không cần xếp tầng xóa thành địa chỉ, vì khi chúng tôi khôi phục, chúng tôi muốn các địa chỉ đó quay lại.

Giả sử người đó đã di chuyển, sau đó chúng tôi chỉ muốn cập nhật cờ xóa trên địa chỉ cũ, chỉ để lại các địa chỉ và người khác. Vì vậy, xếp tầng có thể không luôn luôn được yêu cầu và sẽ phụ thuộc vào kịch bản.

Vì vậy, tôi nghĩ rằng bạn cần phải rõ ràng tùy thuộc vào cách mô hình của bạn được thiết lập và những gì bạn xóa.


1
Không nên duy trì tính toàn vẹn của cơ sở dữ liệu (với một bộ kích hoạt) thay vì mong muốn lập trình viên ứng dụng nhận thức được tất cả các mối quan hệ giữa các bảng và những gì cần xếp tầng ở đâu?

@MichealIT - Không có tính toàn vẹn dữ liệu ở đây vì nó chỉ đơn giản là cập nhật một cột. Bạn đã đúng, bản cập nhật có thể đi vào trình kích hoạt, nhưng việc xác định rõ ràng bằng thao tác xóa (SP) sẽ giúp tìm kiếm dễ dàng hơn. Trong trình kích hoạt, người ta sẽ phải thẩm vấn cờ Xóa và thực hiện hành động thích hợp cho dù đó là 1 hay 0. Logic kích hoạt có xu hướng tối nghĩa hơn so với quy trình được lưu trữ.
Jon Raynor

@MichealT - Trong ví dụ này, trừ khi bản ghi địa chỉ sẽ bị "xóa", hãy để nó một mình. Theo nghĩa cơ sở dữ liệu quan hệ, bạn vẫn duy trì tính toàn vẹn quan hệ vì tất cả các bản ghi này vẫn tồn tại. Đó là các quy tắc kinh doanh chọn loại trừ chúng. Và vâng, một nhà phát triển hiểu rõ hơn về cách xử lý tất cả các thao tác xóa mềm này.
JeffO
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.