Làm thế nào ghi lại mọi thay đổi của một hàng trong cơ sở dữ liệu được lưu trữ chung?


10

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 SQL filestream,
  • 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:

  1. 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.

  2. 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 nullkhô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ành nullhoặc từ null.

  3. 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.

  4. 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.


3
Có liên quan: SQL Server Thay đổi thu thập dữ liệu .
Nick Chammas

Câu trả lời:


8

Cách thông thường để ghi nhật ký kiểm toán loại này là có một bảng bóng và thay đổi nhật ký với các kích hoạt trên bảng cơ sở mà bạn đang kiểm toán. Các bảng khác có thể được đặt trên một đĩa vật lý khác nếu bạn cần điều đó để thực hiện và bạn có thể đặt các chỉ mục cho chúng nếu bạn cần hỗ trợ truy xuất dữ liệu nhanh chóng.

Các bảng sẽ có cấu trúc gần giống với các bảng ban đầu của bạn, nhưng sẽ có cột datetime khi thay đổi diễn ra và một điểm đánh dấu xem hàng được chèn, thay đổi hay xóa. Trình tự các phiên bản có thể được thực hiện bằng dấu thời gian.

Ngày thay đổi có thể được thực hiện bằng cách làm cho cột thời gian không thành null với mặc định là getdate (); một cột người dùng kiểm toán sẽ bắt người dùng với cột không null được mặc định là Suser_Sname (). Giả sử người dùng thực tế đang bị mạo danh trong phiên này sẽ nắm bắt được danh tính của người dùng thực hiện thay đổi.

Cơ sở dữ liệu không có cách nào để nhận biết địa chỉ IP kết nối với máy chủ web. Ứng dụng sẽ phải nắm bắt rõ ràng và ghi lại địa chỉ IP với giao dịch.

Nếu bạn có một số lượng lớn các bảng bạn muốn kiểm toán, bạn có thể sử dụng siêu dữ liệu từ từ điển dữ liệu hệ thống để tạo các kích hoạt theo chương trình.

Giải pháp này cho đến nay là tốt nhất vì nhiều lý do:

  • Nó nắm bắt bất kỳ thay đổi nào đối với bảng, không chỉ những thay đổi được thực hiện bởi ứng dụng.

  • Các bảng kiểm toán có thể được đặt trên một bộ đĩa khác để giảm tải I / O trên các bảng chính của bạn.

  • Bạn có thể sử dụng chế độ xem dựa trên sự kết hợp của bảng và bảng nhật ký kiểm toán để hiển thị toàn bộ lịch sử bao gồm cả phiên bản hiện tại.

  • Bạn có thể lập chỉ mục các bảng nhật ký kiểm toán khi cần thiết để người dùng kiểm toán có thể truy vấn chúng một cách đáp ứng. Như thường lệ, lựa chọn chỉ mục là sự đánh đổi giữa hiệu năng truy vấn và chi phí cập nhật.


Bạn thử nói nếu tôi có 1000 bảng mà tôi cần duy trì nhật ký cho bất kỳ thay đổi nào thì tôi phải tạo 1000 bảng bóng hả? và 1000 kích hoạt để nắm bắt sự thay đổi? nếu có thì đó là ý tưởng không có thật ... chúng ta có thể tạo một bảng lịch sử và một trình kích hoạt duy nhất để nắm bắt và ghi lại dữ liệu đã thay đổi. chúng ta có thể lưu trữ dữ liệu hàng cũ và mới trong bảng đó dưới dạng xml .... đó là nhiều người làm .... tôi rõ rồi !!
Thomas

1
Đối với 1000 bảng, bạn viết một tiện ích đọc các định nghĩa từ từ điển dữ liệu hệ thống và tạo ra các kích hoạt và định nghĩa bảng. Tôi đã thực hiện nó trên một hệ thống với 560 bảng và nó hoạt động tốt.
Mối quan

0

Tôi biết nhiều hệ thống CMS (bao gồm Wordpress) sử dụng một bảng duy nhất để lưu trữ tất cả các phiên bản của dữ liệu. Nhưng sau đó, một lần nữa, họ chỉ phải làm điều này cho bảng có bài đăng blog. Xem cấu trúc cơ sở dữ liệu Wordpress .

Ngoài ra, số lượng hồ sơ và số lần sửa đổi mỗi hàng đi qua sẽ đóng một vai trò quan trọng trong quyết định của bạn.


0

Về phiên bản CMS; đối với drupal, nó tạo một bảng đặc biệt cho mọi trường của thực thể lưu trữ giá trị cũ; một khái niệm như vậy cho phép bạn xử lý tốt dữ liệu của mình nhưng tôi nghĩ nó rất tốn kém, giải pháp của riêng tôi là chuyển đổi đối tượng của mình sang định dạng xml và lưu trữ dưới dạng chuỗi với các trường khác (changetime, id ...)

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.