Thiết kế tốt nhất cho bảng cơ sở dữ liệu thay đổi / kiểm toán? [đóng cửa]


114

Tôi cần tạo một bảng cơ sở dữ liệu để lưu trữ nhật ký thay đổi / kiểm tra khác nhau (khi nội dung nào đó được thêm, xóa, sửa đổi, v.v.). Tôi không cần phải lưu trữ thông tin đặc biệt chi tiết, vì vậy tôi đã suy nghĩ về điều gì đó dọc theo dòng:

  • id (cho sự kiện)
  • người dùng đã kích hoạt nó
  • tên sự kiện
  • mô tả sự kiện
  • dấu thời gian của sự kiện

Am i thiếu cái gì ở đây? Rõ ràng là tôi có thể tiếp tục cải thiện thiết kế, mặc dù tôi không có kế hoạch làm cho nó phức tạp (tạo các bảng khác cho các loại sự kiện hoặc những thứ tương tự như vậy là không có vì đó là một sự phức tạp đối với nhu cầu của tôi).


Tôi đọc câu trả lời của bạn và tôi ngạc nhiên không ai nói về Luật. Tôi biết rằng một số luật hoặc tài liệu thực hành tốt giải thích cách chúng ta PHẢI triển khai bảng kiểm toán (chỉ đọc). Nhưng tôi không có nhiều thông tin hơn thế này. Tôi chỉ biết rằng nó tồn tại. Tôi đang suy nghĩ về đường mòn kiểm toán trong CFR 21 phần 11.
Bastien Vandamme

Câu trả lời:


70

Trong dự án tôi đang thực hiện, nhật ký kiểm tra cũng bắt đầu từ thiết kế rất tối giản, giống như thiết kế bạn đã mô tả:

event ID
event date/time
event type
user ID
description

Ý tưởng vẫn giống nhau: giữ mọi thứ đơn giản.

Tuy nhiên, rõ ràng là thiết kế tối giản này là không đủ. Cuộc kiểm toán điển hình đang sôi sục những câu hỏi như sau:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

Vì vậy, để có thể trả lời những câu hỏi như vậy một cách nhanh chóng (sử dụng SQL), chúng tôi đã kết thúc hai cột bổ sung trong bảng kiểm tra

object type (or table name)
object ID

Đó là khi thiết kế nhật ký kiểm toán của chúng tôi thực sự ổn định (trong vài năm nay).

Tất nhiên, "cải tiến" cuối cùng sẽ chỉ hoạt động đối với các bảng có khóa thay thế. Nhưng hãy đoán xem? Tất cả các bảng đáng kiểm tra của chúng tôi đều có một khóa như vậy!


Vấn đề duy nhất tôi gặp phải với thiết kế này (đường mòn kiểm tra dựa trên 'mô tả') là bản địa hóa ngôn ngữ được sử dụng trong trường đó.
Sam Wilson

@Sam Tôi không thấy vấn đề như vậy, nếu thông báo do hệ thống tạo, chỉ cần sử dụng một khóa ở đây cho chuỗi dịch;
JCM

4
@Hiru: Khi bạn "trộn" hai hoặc nhiều khái niệm riêng biệt vào một cột, thường thì nó sẽ phản tác dụng, sớm hay muộn. Ví dụ: nếu bạn "trộn lẫn" loại sự kiện và loại đối tượng, nó sẽ ảnh hưởng đến các truy vấn như "hiển thị cho tôi bản ghi cho tất cả các đối tượng thuộc loại đã cho" và "hiển thị cho tôi bản ghi cho tất cả các sự kiện thuộc một loại nhất định" (các truy vấn sẽ nhiều hơn phức tạp và rất có thể sẽ hoạt động chậm hơn nhiều).
Yarik

3
Ngoài các cột này, người ta có thể có thêm một cột cho tải trọng sự kiện có cấu trúc / mô tả có cấu trúc . Cột này sẽ chứa thông tin chi tiết về sự kiện (bất kỳ độ phức tạp nào) ở định dạng máy tính có thể đọc được, XML / JSON. Dễ dàng tuần tự hóa, để truy vấn chống lại (ít nhất là trong Postgres / MSSQL), để suy luận về.
turdus-merula

1
@Benjamin: Câu trả lời là trong mô hình miền (hay còn gọi là mô hình kinh doanh). Nếu mô hình cho phép tạo đồng thời các thực thể (ví dụ như một phần của giao dịch logic) thì tôi không thấy bất kỳ vấn đề nào khi có nhiều bản ghi nhật ký với chính xác cùng một dấu thời gian. Ví dụ: nếu việc tạo đơn đặt hàng (như một giao dịch) có thể bao gồm việc tạo N mục đơn hàng, thì tất cả các bản ghi nhật ký 1 + N tương ứng sẽ có cùng một dấu thời gian. Phân tích tiếp theo của nhật ký như vậy có thể tận dụng lợi thế này, coi các bản ghi 1 + N này không phải là các bản ghi độc lập mà là các phần tử của một giao dịch logic. Hy vọng điều này có ý nghĩa.
Yarik

24

Chúng tôi cũng ghi lại các giá trị cũ và mới và cột của chúng cũng như khóa chính của bảng đang được kiểm toán trong bảng chi tiết kiểm toán. Nghĩ xem bạn cần bảng kiểm toán để làm gì? Bạn không chỉ muốn biết ai đã thực hiện thay đổi và khi nào, mà khi một thay đổi xấu xảy ra, bạn muốn có một cách nhanh chóng để khôi phục dữ liệu.

Trong khi bạn đang thiết kế, bạn nên viết mã để khôi phục dữ liệu. Khi bạn cần phục hồi, thường rất vội vàng, tốt nhất bạn nên chuẩn bị sẵn sàng.


1
Điều này thực sự tốt, tôi không hiểu tại sao mọi người lại bỏ qua những bài viết cuối cùng.
Maddy.Shik

3
Tìm nguồn cung ứng sự kiện là một cách tiếp cận thay thế để cung cấp chức năng khôi phục trong khi duy trì lịch sử.
Sam

23

Có một số thứ khác mà bạn có thể muốn kiểm tra, chẳng hạn như tên bảng / cột, máy tính / ứng dụng mà từ đó thực hiện cập nhật, v.v.

Bây giờ, điều này phụ thuộc vào mức độ kiểm toán chi tiết mà bạn thực sự cần và ở cấp độ nào.

Chúng tôi đã bắt đầu xây dựng giải pháp kiểm tra dựa trên trình kích hoạt của riêng mình và chúng tôi muốn kiểm tra mọi thứ và cũng có sẵn tùy chọn khôi phục. Điều này hóa ra quá phức tạp, vì vậy chúng tôi đã kết thúc kỹ thuật đảo ngược công cụ bên thứ ba ApexSQL Audit dựa trên trình kích hoạt để tạo ra giải pháp tùy chỉnh của riêng chúng tôi.

Lời khuyên:

  • Bao gồm các giá trị trước / sau

  • Bao gồm 3-4 cột để lưu trữ khóa chính (trong trường hợp đó là khóa tổng hợp)

  • Lưu trữ dữ liệu bên ngoài cơ sở dữ liệu chính như đã được Robert đề xuất

  • Dành một lượng thời gian kha khá để chuẩn bị báo cáo - đặc biệt là những báo cáo bạn có thể cần để khôi phục

  • Kế hoạch lưu trữ tên máy chủ / ứng dụng - điều này có thể rất hữu ích để theo dõi các hoạt động đáng ngờ


2
Tại sao bạn lại thiết kế ngược nó thay vì mua nó?
Jowen

1
kiểm soát nhiều hơn sản phẩm
Tebe

1
Hy vọng họ không kiện bạn.
Sắp xếp

9

Có rất nhiều câu trả lời thú vị ở đây và trong những câu hỏi tương tự. Những điều duy nhất tôi có thể bổ sung từ kinh nghiệm cá nhân là:

  1. Đặt bảng kiểm toán của bạn trong một cơ sở dữ liệu khác. Lý tưởng nhất là bạn muốn tách khỏi dữ liệu gốc. Nếu bạn cần khôi phục cơ sở dữ liệu của mình, bạn không thực sự muốn khôi phục lại dấu vết kiểm tra.

  2. Chuẩn hóa càng nhiều càng tốt một cách hợp lý. Bạn muốn bảng có càng ít phụ thuộc vào dữ liệu gốc càng tốt. Bảng kiểm toán phải đơn giản và nhanh chóng để lấy dữ liệu từ đó. Không có phép nối hoặc tra cứu ưa thích trên các bảng khác để truy cập dữ liệu.


8
Dữ liệu chưa chuẩn hóa có thực sự đọc nhanh hơn so với dữ liệu chuẩn hóa với các chỉ mục thích hợp không? (Không phải tất cả sự trùng lặp sẽ dẫn đến việc đọc thêm dữ liệu từ ổ cứng chứ?)
Sam

4

Những gì chúng ta có trong bàn: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

Id chung trỏ đến một hàng trong bảng đã được cập nhật và tên bảng là tên của bảng đó dưới dạng một chuỗi. Không phải là một thiết kế DB tốt, nhưng rất hữu ích. Tất cả các bảng của chúng tôi đều có một cột khóa thay thế duy nhất để điều này hoạt động tốt.


2
"Lượng" đại diện cho điều gì?
turdus-merula

Đó là một ứng dụng tài chính, vì vậy nó là giá trị đô la của thứ được ủy quyền, v.v.
WW.

4

Nói chung, kiểm toán tùy chỉnh (tạo nhiều bảng khác nhau) là một lựa chọn tồi. Cơ sở dữ liệu / trình kích hoạt bảng có thể bị vô hiệu hóa để bỏ qua một số hoạt động nhật ký. Bảng kiểm tra tùy chỉnh có thể bị giả mạo. Các trường hợp ngoại lệ có thể xảy ra sẽ làm giảm ứng dụng. Không đề cập đến những khó khăn khi thiết kế một giải pháp mạnh mẽ. Cho đến nay tôi thấy một trường hợp rất đơn giản trong cuộc thảo luận này. Bạn cần tách biệt hoàn toàn khỏi cơ sở dữ liệu hiện tại và với bất kỳ người dùng đặc quyền nào (DBA, Nhà phát triển). Mọi RDBMS chính thống cung cấp các phương tiện kiểm tra mà ngay cả DBA cũng không thể vô hiệu hóa, giả mạo bí mật. Do đó, khả năng đánh giá được cung cấp bởi nhà cung cấp RDBMS phải là lựa chọn đầu tiên. Tùy chọn khác sẽ là trình đọc nhật ký giao dịch của bên thứ ba hoặc trình đọc nhật ký tùy chỉnh để đẩy thông tin đã phân tách vào hệ thống nhắn tin kết thúc ở một số dạng Kho dữ liệu kiểm tra hoặc trình xử lý sự kiện thời gian thực. Tóm tắt: Kiến trúc sư giải pháp / "Tay kiến ​​trúc sư dữ liệu" cần tham gia vào việc định hướng một hệ thống như vậy dựa trên các yêu cầu. Nó thường là những thứ quá nghiêm trọng nếu chỉ giao cho một nhà phát triển giải pháp.


3

Có rất nhiều cách để làm điều này. Cách yêu thích của tôi là:

  1. Thêm một mod_usertrường vào bảng nguồn của bạn (một trường bạn muốn ghi lại).

  2. Tạo một bảng nhật ký có chứa các trường bạn muốn ghi, cộng với một trường log_datetimeseq_num. seq_numlà khóa chính.

  3. Tạo trình kích hoạt trên bảng nguồn để chèn bản ghi hiện tại vào bảng nhật ký bất cứ khi nào bất kỳ trường được giám sát nào bị thay đổi.

Bây giờ bạn đã có hồ sơ về mọi thay đổi và ai đã thực hiện nó.


Vậy ... trường mod_user phải làm gì?
conny

1
Cho bạn biết ai đã thực hiện thay đổi. Cập nhật mã phải bao gồm một cái gì đó để đặt trường đó cho người dùng hiện tại.
JosephStyons

Vậy còn xóa thì sao? Nếu bạn xóa một hàng, làm thế nào để bạn xử lý giá trị cho cột mod_user?
Kenn Cal,

@KennCal Trigger có thể sử dụng các bảng ảo, bạn có thể xem dữ liệu sau và trước đó, bên trong cùng một trình kích hoạt. Không quan trọng hoạt động. stackoverflow.com/questions/6282618/…
Renan Cavalieri

2
@KennCal Bạn nói đúng, trình kích hoạt xóa sẽ cần lưu trữ thông tin đó cho bạn. Tuy nhiên, điều ác là ở chi tiết - nếu bạn đang sử dụng xác thực SQL, trình kích hoạt chỉ có thể chạy [select CURRENT_USER]. Nếu đó là một ứng dụng khách, thì mã khách hàng cần thông báo đó là ai. Nếu đó là một lệnh gọi API, thì người dùng đang xóa cần phải là một tham số bắt buộc đối với lệnh gọi.
JosephStyons

1

Theo nguyên tắc phân tách:

  1. Bảng dữ liệu kiểm toán cần tách biệt với cơ sở dữ liệu chính. Bởi vì cơ sở dữ liệu kiểm toán có thể có nhiều dữ liệu lịch sử, nên từ quan điểm sử dụng bộ nhớ, sẽ có ý nghĩa khi giữ chúng riêng biệt.

  2. Không sử dụng trình kích hoạt để kiểm tra toàn bộ cơ sở dữ liệu, vì bạn sẽ kết thúc với một mớ hỗn độn các cơ sở dữ liệu khác nhau để hỗ trợ. Bạn sẽ phải viết một cái cho DB2, SQLServer, Mysql, v.v.

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.