Các bảng lưu trữ riêng biệt hoặc xóa mềm cho cơ sở dữ liệu hàng tồn kho


7

Tôi đang xây dựng cơ sở dữ liệu kiểm kê theo dõi thiết bị máy tính và các thiết bị phần cứng khác. Tại một số thời điểm trong cuộc sống của bất kỳ thiết bị nào, thiết bị đã ngừng hoạt động và được lưu trữ. Sau khi được lưu trữ, nó cần được theo dõi vì nó được xóa khỏi dịch vụ và được xử lý đúng cách. Ban đầu tôi đã thiết kế cơ chế lưu trữ bằng cách sử dụng một bản sao chính xác của cơ sở dữ liệu đang hoạt động để nhận dữ liệu của nó bằng cách sử dụng trình kích hoạt xóa khỏi cơ sở dữ liệu hoạt động. Cơ sở dữ liệu lưu trữ bao gồm các bản sao của tất cả các bảng có liên quan vì vì một số bản ghi liên quan đến nước ngoài không còn phù hợp, người dùng không thể truy cập được để sử dụng với các thiết bị mới, nhưng được yêu cầu về tính toàn vẹn tham chiếu và truy vấn với các bảng lưu trữ. Hãy nhớ rằng khái niệm lưu trữ ở đây không chỉ là để giữ một lịch sử hoặc nhật ký. Các kho lưu trữ là một phần của quá trình kinh doanh,

ERD bên dưới sử dụng Inventory.DeviceTypebảng làm ví dụ trong đó tất cả các mục nhập và cập nhật được sao chép vào Archive.DeviceTypebảng. Khi người dùng không còn có thể nhập các bản ghi hàng tồn kho của một loại thiết bị nhất định, nó sẽ bị xóa khỏi Inventory.DeviceTypebảng, nhưng vẫn còn trong bảng lưu trữ. Mẫu này được sử dụng trên tất cả các bảng để đảm bảo tài liệu lưu trữ tham chiếu đến dữ liệu hợp lệ, do đó là bản sao của tất cả các bảng.

Ví dụ về bảng hoạt động (Các bảng liên quan khác bị bỏ qua) ERD hoạt động

Ví dụ về bảng lưu trữ (Các bảng liên quan khác bị bỏ qua) Lưu trữ ERD

Vấn đề

Tôi đang cố gắng tìm hiểu làm thế nào tôi sẽ truy vấn cơ sở dữ liệu nếu tôi không biết thiết bị đang hoạt động hay được lưu trữ? Ví dụ: nếu người dùng có số sê-ri và muốn tìm hiểu thông tin về thiết bị và họ không biết liệu nó có được lưu trữ hay không.

Cách 1: Tạo chế độ xem dựa trên tất cả liên minh?

Tùy chọn 2: Truy vấn cơ sở dữ liệu đang hoạt động và sau đó truy vấn kho lưu trữ nếu truy vấn đầu tiên không trả về gì?

Câu chuyện tiếp tục ...

Một cộng sự đề nghị tôi loại bỏ cơ sở dữ liệu lưu trữ và sử dụng sơ đồ xóa mềm. Tôi đã xây dựng một mô hình bằng cách sử dụng ý tưởng này, và sau đó bắt đầu gặp phải một loạt các vấn đề khác.

Dưới đây là các bảng tương tự bằng cách sử dụng lược đồ xóa mềm.

Ví dụ xóa mềm

Xóa mềm ERD

Với thiết lập này, các thiết bị được lưu trữ bằng cách đặt IsArchivedtrường thành true và nhập một ArchivedDate. Tôi có thể truy vấn bất kỳ thiết bị nào một cách dễ dàng cho dù thiết bị đang hoạt động hay được lưu trữ. (Vui lòng bỏ qua IsActivetrường này, vì trường hợp này được sử dụng cho một khái niệm không liên quan).

Hãy chú ý đến bảng phụ của Điện thoại, nơi tôi phải truyền một chỉ mục của cờ DeviceID và IsArchiving vì số điện thoại phải là duy nhất cho các thiết bị hoạt động. Tôi phải làm điều này với các bảng phụ khác. Tôi không biết đây là một thiết kế tốt hay xấu.

Phần này thực sự làm tôi bối rối ...

Các thực tiễn tốt nhất để xử lý xóa mềm trong đó các giá trị khóa ngoài có thể được đánh dấu là đã xóa. Điều duy nhất tôi có thể nghĩ đến là tạo một thói quen tìm kiếm tất cả các bản ghi liên quan đến dữ liệu đã xóa và tạo một báo cáo để người dùng giải quyết các khác biệt. Ví dụ: nếu một bảng vị trí có liên quan đến bảng thiết bị và một số vị trí bị xóa mềm, thì các thiết bị tham chiếu đến các vị trí không còn tồn tại và phải được di chuyển.

Nhân tiện, tôi đang sử dụng MS SQL Server 2008 R2 và tôi dự định sử dụng Entity Framework 4 trong ứng dụng của mình. Tôi đánh giá khả năng duy trì cơ sở dữ liệu trên hiệu suất.

Cảm ơn bạn đã đọc.


Để truyền cờ IsArchiving, bạn có thể sử dụng TRÊN CẬP NHẬT CASCADE. Vì bạn tìm kiếm trên số sê-ri, bạn muốn giữ cả hai hàng hiện tại và được lưu trữ trong một bảng, với UNIQUE hoặc PRIMARY KEY thực thi tính duy nhất của nó.
AK

Câu trả lời:


6

Tôi sẽ nói rằng nếu người dùng của bạn sẽ cần truy vấn dữ liệu Lưu trữ, thì sử dụng bitcờ hoặc soft deletedễ dàng hơn. Nếu người dùng không cần dữ liệu nữa, thì tôi sẽ đi với các bảng lưu trữ.

Dựa trên mô tả của bạn ở trên, tôi sẽ đề nghị đi với Soft Deletephiên bản. Tôi có thể nói với bạn từ kinh nghiệm trong một trong các hệ thống của chúng tôi, chúng tôi đã đi với một lược đồ lưu trữ để di chuyển dữ liệu cũ hơn và nó không dẫn đến vấn đề gì vì người dùng cần quyền truy cập vào dữ liệu. Vì vậy, nó dẫn đến việc sử dụng UNION ALLtrên mọi truy vấn chúng tôi phải chạy.

Do vấn đề, chúng tôi đã dừng tuyến đường đó và chuyển sang xóa mềm, điều này dễ dàng hơn nhiều.

Chúng tôi đã thêm một bitcờ vào tất cả các bảng cần thiết và sau đó chúng tôi chỉ đưa điều này vào WHEREmệnh đề khi truy vấn dữ liệu.

Một gợi ý sẽ là đảm bảo rằng trường này có giá trị mặc định khi bạn INSERTdữ liệu. Nếu bạn đang sử dụng IsArchivedthì giá trị mặc định trên cột sẽ là sai vì bạn không muốn nó được lưu trữ ngay lập tức.


3

Gần đây tôi đã vật lộn với câu hỏi về xóa mềm so với các bảng lưu trữ và rõ ràng có rất nhiều bài viết trên web có nội dung "không xóa mềm, lưu trữ". Mặc dù vậy, tôi vẫn chưa tìm thấy người ủng hộ kho lưu trữ, những người thậm chí thừa nhận vấn đề của bạn tồn tại, nhưng tôi nghĩ rằng tôi đã tìm ra lý do tại sao.

Vấn đề là có hai lý do khiến một bảng có thể là đầu PK của khóa ngoại: bởi vì nó sở hữu một cách hợp lý dữ liệu trong bảng khác hoặc vì nó đang được tham chiếu. Một đơn hàng "sở hữu" đó là OrderDetails. Một địa chỉ chỉ tham chiếu một Nhà nước.

Khi tất cả các FK tham chiếu bảng được quan hệ "sở hữu bởi", bạn không nên xóa mềm.

DeviceTypes của bạn đang được Thiết bị tham chiếu, không thuộc sở hữu. Mẫu lưu trữ không hoạt động ở đây, nó cản trở việc thực thi tính toàn vẹn tham chiếu.

Mặc dù vậy, đây là điều: việc dừng DeviceType không phải là xóa. Dữ liệu vẫn còn sống theo nghĩa được tham chiếu bởi các thiết bị. Bạn không thể (về mặt logic) xóa một Loại thiết bị đang sử dụng. Vì vậy, do hoạt động logic của bạn không phải là xóa, nên việc bạn sử dụng cờ NotAv Available thực sự không phải là xóa mềm. Tôi nghĩ đây là lý do tại sao các nhà lưu trữ không ủng hộ nó.

Đối với những gì nó có giá trị, trong trường hợp của tôi, tôi đã đi với các bảng lưu trữ, bởi vì tôi thực sự muốn xóa dữ liệu một cách hợp lý nhưng chỉ giữ lại cho mục đích kiểm toán. Lý do đằng sau sự lựa chọn của tôi thực sự không liên quan gì đến cơ sở dữ liệu, đó là vì EntityFramework không hỗ trợ tốt cho việc xóa mềm, tôi không thể tìm ra cách tốt để thực thi chúng trên các thuộc tính điều hướng.

Trong SQL Server 2008 R2, bạn có thể giảm thiểu hầu hết các nhược điểm mà người ủng hộ lưu trữ yêu cầu xóa mềm. Bạn có thể sử dụng các chỉ mục được lọc để giảm hình phạt hiệu suất khi mang một loạt các bản ghi bị xóa trong bảng của mình (và hành động xóa mềm rẻ hơn so với hành động lưu trữ, trừ khi bạn cũng phân vùng bảng của mình, điều này có thể có ý nghĩa đối với chiến lược sao lưu ). Tôi tin rằng bạn cũng có thể thực thi tính toàn vẹn tham chiếu trên cờ xóa, mượn từ một kỹ thuật tôi từng thấy trong một bài viết Celko- các bảng con có thể có cờ ParentIsDelatted và hai FK cho cha mẹ của chúng, một bảng chỉ trên ParentId, bảng kia trên ParentId, ParentIsDelatted. Bạn thậm chí có thể có ParentIsDelatted, SelfIsDelatted và biến IsDelatted thành một trường được tính toán bền vững để không bị xóa có thể phân biệt xóa trực tiếp của trẻ em khỏi xóa từ cha mẹ. Tuy nhiên, đối với bạn, bạn không thực sự xóa và bạn không muốn ngăn chặn hoặc xếp tầng không có sẵn của Loại thiết bị mà Thiết bị tồn tại.


1

Bạn có thể phân vùng các bảng chính trên sự kết hợp của id chính và cờ IsArchiving; điều này sẽ có lợi ích kép là làm cho các truy vấn trở nên dễ dàng và duy trì hiệu suất của các truy vấn, v.v so với các bản ghi không được lưu trữ.

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.