Các mẫu cho Phiên bản dữ liệu quan hệ trong cơ sở dữ liệu MySQL?


12

Tôi đang cố gắng tìm cách tiếp cận cho một dự án, nơi Người dùng có thể chỉnh sửa các bản ghi và có thể xem các phiên bản trước đó của các bản ghi đó. Dưới đây là lược đồ ví dụ mô phỏng, sử dụng danh sách:

TABLE list (
  id int auto_increment primary key,
  user_id int, 
  title varchar(255)
);

TABLE list_tasks (
  id int auto_increment primary key,
  list_id int,
  title varchar(255),
  order int,
  is_complete tinyint
);

Vì vậy, người dùng có thể vào và thực hiện một số chỉnh sửa vào danh sách, (nghĩa là thêm hoặc xóa các tác vụ, sắp xếp lại các tác vụ, đánh dấu một số hoàn thành, đổi tên một số, v.v.), sau đó lưu chúng. Tại thời điểm này, tôi muốn tạo một 'phiên bản 2' của danh sách và tác vụ và để chúng có thể xem các phiên bản trước đó, nhưng khi chúng truy cập vào danh sách, luôn có phiên bản mới nhất.

Có một cách tiếp cận / mẫu thiết kế chung để xử lý dữ liệu phiên bản theo cách này trong cơ sở dữ liệu MySQL không?


Lưu ý rằng họ là thư viện cho việc này. Chẳng hạn, nếu bạn sử dụng Hibernate, có Hibernate Envers. Vì vậy, nếu bạn có một số DAO xử lý khung cho bạn, hãy thử tìm kiếm nếu có cái gì đó như thế này.
Walfrat

Câu trả lời:


9

Nó khá phổ biến để làm điều đó trong một db. Mặc dù bạn đang đặt vấn đề ở chỗ bạn muốn theo dõi bản sửa đổi cho danh sách các mục.

Một cách để làm điều này có thể là thay đổi cấu trúc như

Alter table lists add revision_id integer;
Alter table list_tasks add revision_id integer;

Create Table revisions
{
   id int autoincrement... (revision id)
   list_id int...
   revdate datetime...
}

Khi người dùng lưu danh sách của họ, hãy tạo một bản sửa đổi mới trong revisionsbảng trên và gán giá trị đó cho các mục danh sách trong list_tasksvà sau đó cho id sửa đổi listsđể đánh dấu id đó là bản sửa đổi 'hiện tại'. Khi người dùng chỉnh sửa các mục, không chỉnh sửa các mục hiện có - thay vào đó, hãy chèn các mục mới với id sửa đổi mới và cập nhật listbảng với bản sửa đổi đó để đánh dấu nó là mục hiện tại.

Sau đó, để liệt kê các mục hiện tại, liệt kê các mục từ id sửa đổi hiện tại được chỉ định trong listsbảng. Để duyệt các phiên bản trước, bạn có thể lấy danh sách các bản xem lại trước đó của danh sách từ bảng sửa đổi, sau đó liệt kê các mục riêng lẻ dựa trên id đó.


5

Giải pháp này sử dụng một bảng kiểm toán riêng. Nó có ưu và nhược điểm. Bạn có thể muốn loại bỏ các hồ sơ cũ khỏi bảng chính của bạn. Cải thiện hiệu suất có thể không đáng kể.

Thêm các trường sau vào mỗi bảng được kiểm toán:

AddUserID      int <whatever your system uses>
AddDateTime    datetime
UpdateUserID   int <whatever your system uses>
UpdateDateTime datetime
CurrentVersion int
IsDeleted      bit

Bạn sẽ cần cập nhật các trường này mỗi khi dữ liệu thay đổi. CurrentVersion được tăng thêm 1 (Nó có thể được sử dụng như một cách để khóa bản ghi, nhưng đó là một câu hỏi khác.) IsDelatted cung cấp "xóa mềm" để có thể được tham chiếu trong tương lai.

Các bảng kiểm toán riêng biệt Mỗi bảng phải có phiên bản _Archive hoặc _History tương ứng của bảng. Chúng có lẽ không cần phải được lập chỉ mục theo cùng một cách. Rõ ràng một trường khóa chính duy nhất sẽ không áp dụng. Bạn sẽ có thể tạo một khóa tổng hợp từ trường ID và UpdateDateTime.

Sử dụng một trình kích hoạt (Điều này sẽ giải quyết các thay đổi được thực hiện bên trong hoặc bên ngoài mã của bạn. Bạn có thể quyết định xem điều này có phù hợp với tình huống của bạn không.) Hoặc mã hóa khác, khi một bản ghi được nối, cập nhật hoặc xóa, một bản sao của bản ghi được lưu trong kho lưu trữ / bảng lịch sử. Tất cả các phiên bản và các lĩnh vực kiểm toán khác được duy trì. Điều này sẽ cho bạn biết những gì người dùng đã làm những gì khi. Bảng có thể được so sánh với chính nó để xem khi một bản ghi được thay đổi hoặc để xem xu hướng.

Tôi đã thấy công việc này tốt trong vài năm qua. Tôi muốn nghe về những hạn chế mà tôi có thể không xem xét.


Tôi ủng hộ điều này cũng như của GrandMasterB, cả hai đều tốt và sử dụng cái nào phụ thuộc vào nhiều chi tiết hơn về các nhu cầu cụ thể.
Junky

-2

Tôi sẽ đề nghị bạn đọc bài viết này cũng chi tiết.

https://blog.jondh.me.uk/2011/11/relational-database-versioning-strargeties/comment-page-1/#comment-373850

Một cách tiếp cận khác là có một cột version_id trong bảng của bạn và cờ 'hiện tại' chỉ định hàng nào là hàng hiện tại. Mỗi khi bạn cần cập nhật, bạn có thể chèn một hàng mới và đặt cờ 'hiện tại' của phiên bản hiện tại thành 0 / false và hàng mới được thêm thành 1.

Bằng cách này, bạn có thể tạo chế độ xem chỉ hiển thị những chế độ được đặt cờ hiện tại.

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.