Tôi đang sử dụng PostgreSQL nhưng tôi cho rằng hầu hết các db hàng đầu phải có một số khả năng tương tự, và hơn nữa, các giải pháp cho chúng có thể truyền cảm hứng cho các giải pháp cho tôi, vì vậy đừng xem xét cụ thể PostgreQuery này.
Tôi biết tôi không phải là người đầu tiên cố gắng giải quyết vấn đề này vì vậy tôi cho rằng đáng để hỏi ở đây nhưng tôi đang cố gắng đánh giá chi phí của việc lập mô hình dữ liệu kế toán sao cho mọi giao dịch đều được cân bằng cơ bản. Các dữ liệu kế toán là chỉ phụ lục. Ràng buộc tổng thể (được viết bằng mã giả) ở đây có thể trông gần giống như:
CREATE TABLE journal_entry (
id bigserial not null unique, --artificial candidate key
journal_type_id int references journal_type(id),
reference text, -- source document identifier, unique per journal
date_posted date not null,
PRIMARY KEY (journal_type_id, reference)
);
CREATE TABLE journal_line (
entry_id bigint references journal_entry(id),
account_id int not null references account(id),
amount numeric not null,
line_id bigserial not null unique,
CHECK ((sum(amount) over (partition by entry_id) = 0) -- this won't work
);
Rõ ràng một ràng buộc kiểm tra như vậy sẽ không bao giờ làm việc. Nó hoạt động trên mỗi hàng và có thể kiểm tra toàn bộ db. Vì vậy, nó sẽ luôn luôn thất bại và làm chậm nó.
Vì vậy, câu hỏi của tôi là cách tốt nhất để mô hình ràng buộc này là gì? Tôi đã cơ bản xem xét hai ý tưởng cho đến nay. Tự hỏi nếu đây là những người duy nhất, hoặc nếu ai đó có một cách tốt hơn (ngoài việc để nó ở cấp độ ứng dụng hoặc một Proc được lưu trữ).
- Tôi có thể mượn một trang từ khái niệm thế giới kế toán về sự khác biệt giữa một cuốn sách gốc và một cuốn sách cuối cùng (tạp chí chung so với sổ cái chung). Về vấn đề này, tôi có thể mô hình hóa nó như một mảng các dòng nhật ký được đính kèm với mục nhật ký, thực thi các ràng buộc trên mảng (theo thuật ngữ PostgreQuery, chọn sum (số tiền) = 0 từ không nhất định (je.line_items). lưu chúng vào bảng mục hàng, trong đó các ràng buộc cột riêng lẻ có thể được thi hành dễ dàng hơn và trong đó các chỉ mục, v.v có thể hữu ích hơn. Đây là hướng tôi đang nghiêng.
- Tôi có thể thử mã hóa một trình kích hoạt ràng buộc sẽ thực thi điều này trên mỗi giao dịch với ý tưởng rằng tổng của một chuỗi 0 sẽ luôn là 0.
Tôi đang cân nhắc những điều này so với cách tiếp cận hiện tại là thực thi logic trong một thủ tục được lưu trữ. Chi phí phức tạp đang được cân nhắc dựa trên ý tưởng rằng bằng chứng toán học về các ràng buộc là vượt trội so với các bài kiểm tra đơn vị. Hạn chế lớn của # 1 ở trên là các loại như tuples là một trong những lĩnh vực trong PostgreQuery, nơi người ta có hành vi không nhất quán và thay đổi các giả định thường xuyên và vì vậy tôi thậm chí hy vọng rằng hành vi trong lĩnh vực này có thể thay đổi theo thời gian. Thiết kế một phiên bản an toàn trong tương lai không phải là quá dễ dàng.
Có cách nào khác để giải quyết vấn đề này sẽ mở rộng lên tới hàng triệu bản ghi trong mỗi bảng không? Tui bỏ lỡ điều gì vậy? Có một sự đánh đổi tôi đã bỏ lỡ?
Để đáp lại quan điểm của Craig bên dưới về các phiên bản, ở mức tối thiểu, điều này sẽ phải chạy trên PostgreQuery 9.2 trở lên (có thể là 9.1 trở lên, nhưng có lẽ chúng ta có thể đi thẳng với 9.2).