La comptabilité à double entrée est
un ensemble de règles d'enregistrement des informations financières dans un système de comptabilité financière dans lequel chaque transaction ou événement modifie au moins deux comptes différents du grand livre nominal.
Un compte peut être "débité" ou "crédité", et la somme de tous les crédits doit être égale à la somme de tous les débits.
Comment implémenteriez-vous cela dans une base de données Postgres? Spécification de la DDL suivante:
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'))
);
Remarque: la table transaction_details ne spécifie pas de compte de débit / crédit explicite, car le système doit pouvoir débiter / créditer plusieurs comptes en une seule transaction.
Cette DDL crée l'exigence suivante: Une fois qu'une transaction de base de données est validée sur la table transactions_details, elle doit débiter et créditer le même montant pour chacune transaction_id
, par exemple :
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;
Est-il possible de l'implémenter dans une base de données PostgreSQL? Sans spécifier de tables supplémentaires pour stocker les états de déclenchement.
la source
Une autre approche consiste à adopter la position selon laquelle c'est le transfert du montant financier qui comprend un seul enregistrement.
Ainsi, vous pourriez avoir la structure:
Une contrainte de vérification peut garantir que les comptes de débit et de crédit sont différents et qu'il n'y a qu'un seul montant à stocker. Ainsi, l'intégrité est garantie, ce que le modèle de données devrait fournir naturellement.
J'ai travaillé avec des systèmes qui ont adopté cette approche avec succès. Il y a un peu moins d'efficacité à interroger des enregistrements sur un compte particulier, mais le tableau était plus compact et les requêtes pour un compte car le débit uniquement ou le crédit uniquement étaient un peu plus efficaces.
la source