Why Relational Databases for Inventory
Inventory systems require strict transactional consistency (ACID properties). Unlike document-based datastores which can suffer from data duplication and eventual consistency lag, PostgreSQL ensures every transaction is fully isolated and atomic.
Creating the Inventory Schema
We treat inventory as a double-entry ledger. Instead of just updating a 'current_stock' integer, we append a transaction record. The current stock is a materialized view or sum of all transactions.
CREATE TABLE inventory_ledgers (
id SERIAL PRIMARY KEY,
product_id INT REFERENCES products(id),
quantity_change INT NOT NULL,
transaction_type VARCHAR(50) NOT NULL,
reference_id VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Utilizing Trigger Hooks
To optimize read speeds, we use PostgreSQL triggers to update a cached 'stock_summary' table every time a new ledger entry is inserted. This gives us the auditability of an append-only ledger with the read-performance of a single row lookup.
CREATE OR REPLACE FUNCTION update_stock_summary()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO stock_summary (product_id, total_stock)
VALUES (NEW.product_id, NEW.quantity_change)
ON CONFLICT (product_id) DO UPDATE
SET total_stock = stock_summary.total_stock + NEW.quantity_change;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;