Thực hành tốt nhất cho lịch sử / bảng thời gian?


11

Giả sử tôi có một đối tượng, với các trường nhất định mà tôi muốn theo dõi lịch sử và các trường nhất định mà tôi không muốn theo dõi lịch sử. Từ góc độ chuẩn hóa, là lược đồ sau đây ổn:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

trong đó MyObjectHistory chứa các trường được theo dõi cho tất cả ngoại trừ phiên bản mới nhất. Hoặc, nếu tất cả các trường được theo dõi phải nằm trong một bảng và tất cả các phiên bản bao gồm cả các bản mới nhất sẽ nằm trong bảng đó, như trong:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

Tôi đồng ý với
@Joel

Câu trả lời:


7

Vì lý do truy cập dữ liệu thực tế, bạn nên sử dụng cấu trúc từ tùy chọn đầu tiên của mình, nhưng thay vào đó hãy giữ tất cả các phiên bản của các giá trị cột được theo dõi bao gồm cả phiên bản hiện tại trong bảng lịch sử của bạn.

Lý do cho điều này là vì nói chung, khi bạn muốn nhìn vào lịch sử, bạn muốn bao gồm hiện tại và tất cả các phiên bản trong quá khứ. Khi bạn không muốn nhìn vào lịch sử, bạn muốn nó tránh đường. Trong nhiều trường hợp, điều này có nghĩa là đi xa đến mức tách biệt lịch sử thành một lược đồ hoặc cơ sở dữ liệu riêng biệt hoàn toàn. Ngay cả khi bạn giữ lịch sử của mình trong cùng một lược đồ với dữ liệu hiện tại của bạn, mọi truy vấn xem dữ liệu lịch sử (bao gồm các giá trị hiện tại) sẽ phức tạp hơn nhiều vì về cơ bản chúng phải liên kết hai nguồn.


2

Tôi thích phiên bản đầu tiên vì có lẽ bạn hiếm khi chỉ cần xem lịch sử nhưng bạn sẽ thường xuyên cần xem giá trị hiện tại. Một bảng lịch sử nên được điền từ một trình kích hoạt, vì vậy bạn không cần phải lo lắng về việc dữ liệu sẽ không đồng bộ nói chung. Vì vậy, giả sử bạn có một triệu bản ghi trong MyObject và sau đó bạn có 10.000.000 bản ghi trong MyObjectHistory. Bạn có thực sự muốn tham gia vào một bảng có nhiều bản ghi để nhận giá trị hiện tại không?

Bây giờ nếu bạn sẽ cần truy vấn lịch sử dưới dạng tự do hoặc thường xuyên hơn giá trị hiện tại, thì cấu trúc thứ hai sẽ hoạt động. (Và nếu bạn sẽ hiển thị giá trị vào một ngày cụ thể, tôi sẽ có một trường bắt đầu và kết thúc trong đó để làm cho việc truy vấn đơn giản hơn.)

BTW Tôi sẽ thêm một trường ngày vào bảng lịch sử để có thể biết thứ tự thay đổi đã xảy ra. Bạn không thể dựa vào danh tính cho trật tự thời gian. Xin vui lòng nếu có một câu hỏi về một giá trị phổ biến và khi nó thay đổi, bạn sẽ cần phải knwo. Tôi cũng có thể đưa vào các giá trị cho ứng dụng mà thay đổi đến từ (nếu bạn có nhiều ứng dụng) và / hoặc người thực hiện thay đổi.


0

Có một vài lý do quan trọng cho # 1. Đầu tiên là vấn đề kích thước mà HLGEM chỉ ra nhưng cũng có những vấn đề quan trọng khác.

Thông thường, lộ trình kiểm toán của bạn sẽ có những yêu cầu phát triển theo thời gian. Cuối cùng, bạn có thể muốn theo dõi người dùng cơ sở dữ liệu, thời gian thay đổi, v.v. Các yêu cầu về đường kiểm toán và bảng chính của bạn có thể thay đổi theo thời gian một cách độc lập. Cuối cùng, bạn có thể muốn thanh lọc dữ liệu theo dõi kiểm toán sau một khoảng thời gian độc lập và một bảng hoàn toàn riêng biệt.

Tất nhiên, có thể có trường hợp bạn muốn hợp nhất chúng hoàn toàn (như chúng tôi áp dụng thuế suất trong LedgerSMB) vì dữ liệu lịch sử có thể được sử dụng cho các tính toán hiện tại và số lượng hồ sơ có thể tương đối nhỏ.

Tuy nhiên, tôi sẽ đề xuất rằng việc lưu trữ các đối tượng trong các bảng như thế này hiếm khi dẫn đến các thiết kế tốt, chuẩn hóa. Theo kinh nghiệm của tôi, bạn thực sự muốn một số đóng gói giữa lưu trữ được chuẩn hóa tốt và một mô hình đối tượng ứng dụng.


2
Ý của bạn là gì khi đóng gói giữa bộ lưu trữ được chuẩn hóa tốt và mô hình đối tượng ứng dụng là gì? Bạn sẽ giải thích về ý tưởng này hay đưa ra một ví dụ?
cubetwo1729
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.