La contabilidad de doble entrada es
un conjunto de reglas para registrar información financiera en un sistema de contabilidad financiera en el que cada transacción o evento cambia al menos dos cuentas contables nominales diferentes.
Una cuenta puede ser "debitada" o "acreditada", y la suma de todos los créditos debe ser igual a la suma de todos los débitos.
¿Cómo implementaría esto en una base de datos Postgres? Especificando el siguiente 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'))
);
Nota: la tabla transacción_detalles no especifica una cuenta explícita de débito / crédito, porque el sistema debería poder debitar / acreditar más de una cuenta en una sola transacción.
Este DDL crea el siguiente requisito: después de que una transacción de base de datos se confirma en la tabla transacciones_detalles, debe debitar y acreditar la misma cantidad para cada uno transaction_id
, por ejemplo :
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;
¿Es posible implementar esto en una base de datos PostgreSQL? Sin especificar tablas adicionales para almacenar estados de activación.
fuente
Otro enfoque es adoptar la posición de que es la transferencia del monto financiero que comprende un solo registro.
Por lo tanto, puede tener la estructura:
Una restricción de verificación puede garantizar que las cuentas de débito y crédito sean diferentes y que solo haya una cantidad para almacenar. Por lo tanto, hay integridad garantizada, que es lo que el modelo de datos debe proporcionar de forma natural.
He trabajado con sistemas que adoptaron este enfoque con éxito. Hay un poco menos de eficiencia en la consulta de cualquier registro en una cuenta en particular, pero la tabla era más compacta y las consultas para una cuenta solo como débito o como crédito solo eran un poco más eficientes.
fuente