Doppelte Buchführung ist
eine Reihe von Regeln für die Erfassung von Finanzinformationen in einem Finanzbuchhaltungssystem, in dem jede Transaktion oder jedes Ereignis mindestens zwei verschiedene nominale Sachkonten ändert.
Ein Konto kann "belastet" oder "gutgeschrieben" werden, und die Summe aller Gutschriften muss gleich der Summe aller Belastungen sein.
Wie würden Sie dies in einer Postgres-Datenbank implementieren? Angabe der folgenden DDL:
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'))
);
Hinweis: In der Tabelle transaction_details wird kein explizites Debit- / Kreditkonto angegeben, da das System in der Lage sein sollte, mehr als ein Konto in einer einzelnen Transaktion zu belasten / gutzuschreiben.
Diese DDL schafft die folgende Anforderung: Nachdem eine Datenbanktransaktion für die Tabelle transaction_details festgeschrieben wurde, muss sie für jeden den gleichen Betrag belasten und gutschreiben transaction_id
, z .
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;
Ist es möglich, dies in einer PostgreSQL-Datenbank zu implementieren? Ohne Angabe zusätzlicher Tabellen zum Speichern von Triggerzuständen.
quelle
Ein anderer Ansatz besteht darin, die Position einzunehmen, dass die Übertragung des Finanzbetrags einen einzelnen Datensatz umfasst.
So könnten Sie die Struktur haben:
Eine Prüfbeschränkung kann sicherstellen, dass die Debit- und Kreditkonten unterschiedlich sind und nur ein Betrag gespeichert werden muss. Somit ist die Integrität garantiert, was das Datenmodell natürlich bieten sollte.
Ich habe mit Systemen gearbeitet, die diesen Ansatz erfolgreich übernommen haben. Es ist etwas weniger effizient, Datensätze für ein bestimmtes Konto abzufragen, aber die Tabelle war kompakter und Abfragen für ein Konto, da nur die Lastschrift oder nur das Guthaben etwas effizienter waren.
quelle