Trong một dự án tôi đang làm việc, mọi thay đổi đối với các hàng trong một số bảng của cơ sở dữ liệu phải được theo dõi để kiểm tra hoặc khôi phục thêm. Phải dễ dàng tìm ra ai đã sửa đổi hàng, từ địa chỉ IP nào và khi nào, và có thể khôi phục phiên bản trước đó.
Điều tương tự được sử dụng ví dụ bởi Stack Exchange. Khi tôi thay đổi câu hỏi của người khác, có thể thấy rằng tôi đã thay đổi nó và khôi phục lại các thay đổi.
Kỹ thuật chung được sử dụng để lưu trữ mọi thay đổi đối với một đối tượng trong cơ sở dữ liệu , với điều kiện là lược đồ hiện tại của tôi có hầu hết các thuộc tính (bên dưới) mà một ứng dụng kinh doanh trung bình?
- Các đối tượng có kích thước tương đối nhỏ: có thể có một số
nvarchar(1000)
ví dụ, nhưng không phải là các đốm dữ liệu nhị phân khổng lồ, dữ liệu này được lưu trữ trực tiếp trên đĩa và được truy cập trực tiếp, và không thông qua Microsoft SQLfilestream
, - Tải cơ sở dữ liệu khá thấp và toàn bộ cơ sở dữ liệu được xử lý bởi một máy ảo trên máy chủ,
- Quyền truy cập vào các phiên bản trước không cần phải nhanh như quyền truy cập vào phiên bản mới nhất, nhưng vẫn phải cập nhật và không quá chậm².
<tl-dr>
Tôi đã nghĩ về các trường hợp sau đây, nhưng tôi không có kinh nghiệm thực tế với các loại kịch bản đó, vì vậy tôi sẽ nghe ý kiến khác:
Lưu trữ mọi thứ trong cùng một bảng, phân biệt các hàng theo ID và phiên bản. IMO, nó thực sự ngu ngốc và sẽ sớm bị tổn thương về mức độ hiệu suất. Với phương pháp này, cũng không thể đặt mức bảo mật khác cho các mục mới nhất và theo dõi các phiên bản. Cuối cùng, mọi truy vấn sẽ phức tạp hơn để viết. Trên thực tế, để truy cập dữ liệu cập nhật, tôi sẽ buộc phải nhóm mọi thứ bằng ID và truy xuất, trong mỗi nhóm, phiên bản cuối cùng.
Lưu trữ phiên bản mới nhất trong một bảng và, tại mỗi thay đổi, sao chép phiên bản lỗi thời sang một bảng khác trong lược đồ khác. Lỗ hổng là mỗi lần, chúng tôi lưu trữ mọi giá trị, ngay cả khi nó không thay đổi. Đặt giá trị không thay đổi thành
null
không phải là một giải pháp, vì tôi cũng phải theo dõi khi giá trị được thay đổi thànhnull
hoặc từnull
.Lưu trữ phiên bản mới nhất trong một bảng và danh sách các thuộc tính đã thay đổi với các giá trị trước đó của chúng trong một bảng khác. Điều này dường như có hai sai sót: điều quan trọng nhất là cách duy nhất để sắp xếp các loại giá trị không đồng nhất của các giá trị trước đó trong cùng một cột là có a
binary(max)
. Điều thứ hai là, tôi tin rằng, sẽ khó sử dụng cấu trúc như vậy hơn khi hiển thị các phiên bản trước cho người dùng.Làm tương tự như trong hai điểm trước, nhưng lưu trữ các phiên bản trong cơ sở dữ liệu riêng biệt. Hiệu suất khôn ngoan, có thể thú vị để tránh làm chậm việc truy cập các phiên bản mới nhất bằng cách có các phiên bản trước đó trong cùng một cơ sở dữ liệu; Tuy nhiên, tôi tin rằng đó là một tối ưu hóa sớm và chỉ phải được thực hiện nếu có bằng chứng cho thấy việc có các phiên bản cũ hơn và mới nhất trong cùng một cơ sở dữ liệu là một nút cổ chai.
</ tl-dr>
Ví dụ, không thể chấp nhận lưu trữ các thay đổi vào tệp nhật ký, vì nó được thực hiện cho nhật ký HTTP và xóa dữ liệu từ nhật ký đến cơ sở dữ liệu vào ban đêm khi tải máy chủ thấp nhất. Thông tin về các phiên bản khác nhau phải có sẵn ngay lập tức hoặc gần như ngay lập tức; một vài giây chậm trễ là chấp nhận được.
² Thông tin không được truy cập rất thường xuyên và chỉ bởi một nhóm người dùng cụ thể, tuy nhiên, sẽ không thể chấp nhận được việc buộc họ phải chờ trong 30 giây để danh sách các phiên bản hiển thị. Một lần nữa, một vài giây chậm trễ là chấp nhận được.