Giao dịch, tài liệu tham khảo và làm thế nào để thực thi sổ sách kế toán kép? (PG)


8

Sổ sách kế toán kép là

một bộ quy tắc để ghi lại thông tin tài chính trong một hệ thống kế toán tài chính, trong đó mọi giao dịch hoặc sự kiện thay đổi ít nhất hai tài khoản sổ cái danh nghĩa khác nhau.

Tài khoản có thể được "ghi nợ" hoặc "ghi có" và tổng của tất cả các khoản tín dụng phải bằng tổng của tất cả các khoản ghi nợ.

Làm thế nào bạn sẽ thực hiện điều này trong cơ sở dữ liệu Postgres? Chỉ định DDL sau:

CREATE TABLE accounts(
    account_id serial NOT NULL PRIMARY KEY,
    account_name varchar(64) NOT NULL
);


CREATE TABLE transactions(
    transaction_id serial NOT NULL PRIMARY KEY,
    transaction_date date NOT NULL
);


CREATE TABLE transactions_details(
    id serial8 NOT NULL PRIMARY KEY,
    transaction_id integer NOT NULL 
        REFERENCES transactions (transaction_id)
        ON UPDATE CASCADE
        ON DELETE CASCADE
        DEFERRABLE INITIALLY DEFERRED,
    account_id integer NOT NULL
        REFERENCES accounts (account_id)
        ON UPDATE CASCADE
        ON DELETE RESTRICT
        NOT DEFERRABLE INITIALLY IMMEDIATE,
    amount decimal(19,6) NOT NULL,
    flag varchar(1) NOT NULL CHECK (flag IN ('C','D'))
);

Lưu ý: bảng giao dịch_details không chỉ định tài khoản ghi nợ / tín dụng rõ ràng, vì hệ thống sẽ có thể ghi nợ / tín dụng nhiều hơn một tài khoản trong một giao dịch.

DDL này tạo ra yêu cầu sau: Sau khi giao dịch cơ sở dữ liệu cam kết trên bảng giao dịch_details, nó phải ghi nợ và ghi có cùng số tiền cho mỗi giao dịch transaction_id, ví dụ :

INSERT INTO accounts VALUES (100, 'Accounts receivable');
INSERT INTO accounts VALUES (200, 'Revenue');

INSERT INTO transactions VALUES (1, CURRENT_DATE);

-- The following must succeed
BEGIN;
    INSERT INTO transactions_details VALUES (DEFAULT, 1, 100, '1000'::decimal, 'D');
    INSERT INTO transactions_details VALUES (DEFAULT, 1, 200, '1000'::decimal, 'C');
COMMIT;


-- But this must raise some error
BEGIN;
    INSERT INTO transactions_details VALUES (DEFAULT, 1, 100, '1000'::decimal, 'D');
    INSERT INTO transactions_details VALUES (DEFAULT, 1, 200, '500'::decimal, 'C');
COMMIT;

Có thể thực hiện điều này trong cơ sở dữ liệu PostgreQuery không? Không chỉ định các bảng bổ sung để lưu trữ trạng thái kích hoạt.

Câu trả lời:


5

Đầu tiên, đây chính xác là câu hỏi tôi có trong đầu khi tôi hỏi các ràng buộc Mô hình hóa trên các tập hợp con? đó chắc chắn là nơi để bắt đầu Câu hỏi đó là tổng quát hơn mặc dù vậy và vì vậy câu trả lời của tôi ở đây sẽ có thêm một chút thông tin liên quan đến phương pháp tiếp cận thực tế.

Bạn có thể không muốn làm điều này khai báo trong PostgreSQL. Các giải pháp khai báo khả thi duy nhất có thể phá vỡ 1NF hoặc cực kỳ phức tạp và do đó, điều này có nghĩa là thực hiện nó một cách bắt buộc.

Trong LedgerSMB, chúng tôi hy vọng sẽ thực hiện việc thực thi này theo hai giai đoạn (cả hai đều nghiêm ngặt).

  1. Tất cả các mục tạp chí sẽ đến thông qua các thủ tục được lưu trữ. Các quy trình được lưu trữ này sẽ chấp nhận danh sách các chi tiết đơn hàng dưới dạng một mảng và kiểm tra xem tổng bằng 0. Mô hình của chúng tôi trong db là chúng tôi có một cột số lượng duy nhất với các số âm là ghi nợ và số dương là tín dụng (nếu tôi là bắt đầu lại, tôi sẽ có các số dương là ghi nợ và số âm dưới dạng tín dụng vì điều này chỉ tự nhiên hơn một chút nhưng lý do ở đây không rõ ràng). Các khoản nợ và tín dụng được hợp nhất trên bộ lưu trữ và được phân tách khi truy xuất bởi lớp trình bày. Điều này làm cho việc chạy tổng cộng dễ dàng hơn nhiều.

  2. Chúng tôi sẽ sử dụng một trình kích hoạt ràng buộc hoãn lại để kiểm tra cam kết dựa trên các trường hệ thống trên bảng. Điều này có nghĩa là các dòng được nhập trong một giao dịch nhất định phải cân bằng, nhưng chúng ta có thể làm điều này ngoài chính các dòng đó.


BTW, nếu bạn đang thực hiện nhiều kế toán kép, e dự kiến ​​sẽ tái thiết kế lược đồ tài chính của chúng tôi (trên postgreQuery) trong năm tới hoặc lâu hơn. Tôi không biết liệu bạn có muốn hợp tác với một dự án nguồn mở hay không nhưng tôi nghĩ rằng tôi sẽ mở rộng một lời mời.
Chris Travers

Tôi đến bữa tiệc muộn, nhưng bạn có thể vui lòng giải thích - "sẽ kiểm tra cam kết dựa trên các trường hệ thống trên bàn" không? Bạn có đang sử dụng trường hệ thống xmin để tìm ra hàng nào được chèn không? Tôi phải đối mặt với tình huống chính xác này và đây là chủ đề duy nhất tiến gần đến một giải pháp. Tuy nhiên, tôi không biết gì.
Mã nhà thơ

Vâng. Chúng ta có thể nhìn vào các hàng được tạo bởi giao dịch và nhấn mạnh rằng tổng số tiền trong chúng là 0. Về cơ bản, kiểm tra các cột hệ thống như xmin.
Chris Travers

4

Một cách tiếp cận khác là chấp nhận vị trí đó là chuyển khoản số tiền tài chính bao gồm một hồ sơ.

Do đó, bạn có thể có cấu trúc:

create table ... (
  id                integer,
  debit_account_id  not null REFERENCES accounts (account_id),
  credit_account_id not null REFERENCES accounts (account_id),
  amount            numeric not null);

Ràng buộc kiểm tra có thể đảm bảo rằng các tài khoản ghi nợ và tín dụng khác nhau và chỉ có một số tiền để lưu trữ. Do đó, có tính toàn vẹn được đảm bảo, đó là những gì mô hình dữ liệu phải cung cấp một cách tự nhiên.

Tôi đã làm việc với các hệ thống áp dụng phương pháp này thành công. Có ít hiệu quả hơn trong việc truy vấn bất kỳ hồ sơ nào đối với một tài khoản cụ thể, nhưng bảng nhỏ gọn hơn và các truy vấn cho một tài khoản chỉ là ghi nợ hoặc vì tín dụng chỉ hiệu quả hơn một chút.

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.