Các cách để có lịch sử thay đổi các mục cơ sở dữ liệu


21

Các cách để cho phép phiên bản của các mục cơ sở dữ liệu (dữ liệu) là gì?

Hãy suy nghĩ về khả năng quản lý nội dung của hệ thống để hoàn nguyên các thay đổi của bài viết.

Ưu / nhược điểm của họ là gì?


1
Chính xác những gì bạn muốn phiên bản? Các lược đồ hoặc dữ liệu?
tdammers

1
Tôi muốn phiên bản dữ liệu. Để giữ ví dụ về cms, hãy nói các phiên bản của bài viết .
matcauthon

Bạn có thể muốn nhìn vào Datomic.
dan_waterworth

Câu trả lời:


19

Về cơ bản có hai cách tiếp cận: một bảng kiểm toán, với tất cả các giá trị trước đó được lưu trong đó hoặc bao gồm ngày bắt đầu / ngày kết thúc như một phần của bảng và tất cả các bản cập nhật tạo ra một bản ghi mới trong khi đóng bản ghi cũ.

Cập nhật: SQL SERVER 2016 hỗ trợ điều này dưới dạng mẫu / bảng thiết kế - https://docs.microsoft.com/en-us/sql/relational-database/tables/temporal-tables?view=sql-server-2017


4
Vì vậy, cách tiếp cận đầu tiên có thể có khả năng mở rộng hơn. Vì dữ liệu "được lưu trữ" sẽ hiếm khi được truy cập, thiết kế cơ sở dữ liệu có thể được tối ưu hóa. Và bàn làm việc giữ nhỏ. Tùy thuộc vào độ phức tạp, nó cũng có thể chỉ lưu các khác biệt. Có nên sử dụng mô hình memento ?
matcauthon

1
Điều đó sẽ phụ thuộc vào cách sử dụng của bạn, nó có thể đủ để sử dụng các trình kích hoạt để điền vào bảng / s và sau đó cung cấp cách chọn những gì và khoảng cách để quay trở lại.
jmoreno

Bạn có một lỗi đánh máy trong câu trả lời của bạn (patter nên là mẫu)
geocodezip

7

Một ý tưởng là sử dụng "Cơ sở dữ liệu chỉ chèn". Ý tưởng cơ bản là bạn không bao giờ xóa hoặc cập nhật dữ liệu liên tiếp .

Mỗi bảng được yêu cầu theo dõi sẽ có hai datetimecột fromto. Họ bắt đầu với giá trị NULLtrong mỗi (bắt đầu từ thời gian đến kết thúc thời gian). Khi bạn cần "thay đổi" hàng bạn thêm một hàng mới, đồng thời bạn cập nhật tohàng trước đó Nowfromhàng bạn đang thêm vào Now.

Để biết thêm thông tin chi tiết, xem tại:

Kỹ thuật này được gọi AuditTrailđể quản lý dữ liệu cũ và các cửa hàng của nó thay đổi lịch sử.

Có vẻ như câu hỏi về bản chất này đã được đăng:


Đáng buồn là câu hỏi đó dường như đã bị xóa :(
Douglas Gaskell

Không có vấn đề, đây là liên kết . Một đề xuất thiết kế tốt khác trong liên kết
Yusubov

2

Tôi nghĩ rằng bạn có thể sử dụng trình kích hoạt cho mỗi bảng và duy trì dữ liệu trong _history (hoặc bạn có thể đặt bất kỳ tên nào) và trên mỗi lần chèn, cập nhật, xóa trên bảng chính sẽ kích hoạt trình kích hoạt của bạn và bạn có thể lưu các chi tiết trong bảng này. cũng có sẵn với cơ sở dữ liệu SQLite nếu bạn đang sử dụng một cơ sở dữ liệu.

Cơ chế này cũng hữu ích cho các dự án lớn. Trong bảng này, bạn có thể ghi thông tin của người dùng đã thực hiện các thay đổi cùng với dấu thời gian của các thay đổi. sau đó bạn có thể khôi phục bảng của mình theo bất kỳ dấu thời gian nào phù hợp với yêu cầu của bạn.

Mỗi cơ sở dữ liệu có cách riêng để viết và kích hoạt mã. Nếu bạn đang sử dụng SQLite, hãy truy cập SQLite.org để biết cú pháp. Đối với các cơ sở dữ liệu khác, bạn có thể truy cập các trang web chính thức của họ.


1

Bạn có thể biết về công cụ db Sqlite . Toàn bộ db được lưu trong một tệp duy nhất. Api cũng hỗ trợ các hệ thống tệp ảo, vì vậy về cơ bản, bạn có thể tổ chức lưu trữ ở bất cứ đâu và với bất kỳ định dạng nào, chỉ cần phản hồi các hoạt động đọc và ghi tại các lần tắt tệp cụ thể. Các ứng dụng có thể cho việc này có thể là mã hóa, nén, v.v. Phần tốt nhất của nó là lớp container không nên biết gì về cơ sở dữ liệu, định dạng tệp sql hoặc sqlite, chỉ tuân theo các cuộc gọi lại xRead và xWrite.

Một trong những ý tưởng là thực hiện tính năng cỗ máy thời gian. Vì vậy, bất kỳ thao tác xWrite nào cũng lưu mọi phân đoạn mà nó sẽ ghi đè lên trong lịch sử "hoàn tác" và người dùng có thể chọn một ngày trong quá khứ để xem db chứa gì (có thể là chế độ chỉ đọc). Tôi chưa có ví dụ hoạt động (đã có một cuộc thảo luận về nó trong danh sách thư sqlite), nhưng có lẽ các công cụ khác cung cấp API VFS để có thể có một cái gì đó tương tự. Và một khi nó được thực hiện, nó sẽ tương thích với các cấu trúc cơ sở dữ liệu có độ phức tạp bất kỳ.


Bạn nghĩ gì về cách tiếp cận này có thể mở rộng cho các dự án lớn hơn?
matcauthon

Tôi nghĩ rằng điều này có thể thêm chi phí dữ liệu lớn cho các thay đổi dữ liệu lớn (rõ ràng vì mỗi thay đổi nên được lưu, mặc dù nén cho phiên bản cũ hơn có thể giúp ích). Ngoài ra, từ quan điểm của lược đồ của bạn, miễn là nó hoạt động cho hai bảng, nó hoạt động trong hai mươi.
Maksee

1

Phương pháp chúng tôi sử dụng để tạo phiên bản cơ sở dữ liệu là sử dụng bảng kiểm toán. Bảng này có một lược đồ dọc theo các dòng:

Seq      - Int      ' Unique identifier for this table
Event    - Char     ' Insert / Update / Delete
TblName  - Char     ' Table that had field value changed
FldName  - Char     ' Field that was changed
KeyValue - Char     ' delimited list of values for fields that make up the PK of table changed
UsrId    - Char     ' User who made the change
OldValue - Char     ' Old value (converted to character)
NewValue - Char     ' New value (converted to character)
AddTs    - DateTime ' When the change was made

Sau đó chúng tôi có các kích hoạt trên Chèn / Cập nhật / Xóa các bảng mà chúng tôi muốn theo dõi.

Ưu điểm:

  • Tất cả dữ liệu nằm trong một bảng
  • Có thể được thiết lập để theo dõi tất cả các trường hoặc các trường cụ thể trong một bảng
  • Dễ dàng hiển thị phiên bản trên mỗi trường cho một bảng

Nhược điểm:

  • Có tất cả thông tin kiểm toán trong một bảng dẫn đến số lượng hồ sơ cực lớn
  • Rất nhiều yếu tố cần thiết

0

Tôi đang làm một phiên bản này. đối với mỗi bản ghi, tôi có Ngày chèn, ngày sửa đổi và cờ boolean Bản ghi hoạt động. Đối với lần chèn ban đầu, ngày chèn và ngày sửa đổi đều được đặt thành Now () (Ví dụ này nằm trong Access) và cờ bản ghi hoạt động được đặt thành true. sau đó nếu tôi sửa đổi bản ghi đó, tôi sao chép toàn bộ bản ghi sang bản ghi mới, thay đổi (các) trường mà người dùng đang thay đổi, tôi để ngày Chèn bằng với bản gốc và thay đổi ngày Sửa đổi thành Hiện tại (). Sau đó tôi lật cờ Bản ghi hoạt động của bản ghi gốc falsevà bản ghi mới đểtrue . Tôi cũng có một trường cho ModifiedRecordsParentID nơi tôi lưu danh tính của bản ghi gốc.

Sau đó, nếu tôi thậm chí cần truy vấn, tôi chỉ có thể trả lại các bản ghi ở đâu ActiveRecord = truevà tôi sẽ chỉ nhận được thông tin cập nhật nhất.


Không cần ActiveRecordcờ. Hàng MAX (*) phải luôn là bản ghi hiện tại. Khôi phục lại phiên bản trước chỉ đơn giản là chèn hàng đã nói vào bảng một lần nữa.
đảo ngược

Tôi không chắc làm thế nào để chọn công việc được chọn, nhưng bây giờ khi bạn gọi nó ra, tôi đang nghĩ về nó và có một ý tưởng, hmmmm
Brad

Thông thường MAX (tên_bảng) chọn giá trị lớn nhất trong cột của bảng. Để chọn toàn bộ hàng, một đơn giản select top 1 order by id descendingsẽ làm.
đảo ngược

Vâng, nó hoạt động cho một bản ghi đơn giản nhưng bảng của tôi là một tập hợp các bản ghi con cần được chọn ngay lập tức nhưng có thể được sửa đổi riêng lẻ. Chỉ phức tạp hơn một chút.
Brad

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.