Advanced database design requires patterns that span multiple tables to handle auditing, relationship complexity, and temporal state.
The universal default. Every table includes created_at, updated_at, created_by, and updated_by. This identifies when and who, but not the specific delta.
A parallel table stores a snapshot of the main table's row on every change via a database trigger.
orders, profiles).Events are the immutable source of truth; state is a projection.
event_store table. Replay events to reconstruct state at any point in time. Use for financial ledgers or high-compliance domains.Mark rows as deleted via a deleted_at timestamp rather than physical removal.
UNIQUE (email) WHERE deleted_at IS NULL) to allow reuse of natural identifiers after deletion.When a table (e.g., comments) can link to one of several parents (e.g., posts, videos).
CHECK constraint ensuring exactly one is populated. This maintains referential integrity, which is lost in "type-tag + ID" patterns.Stored, pre-computed aggregations refreshed periodically.
user_lifetime_value).REFRESH MATERIALIZED VIEW CONCURRENTLY in Postgres to avoid blocking reads during updates.A dedicated table to track unique request keys for side-effect-producing operations.
idempotency_key and the result of the first successful execution. Subsequent retries with the same key return the stored result without re-executing business logic.Atomically write data to the database and an outbox table in a single transaction.
Track row values over time using effective_from and effective_until timestamps.
TSTZRANGE types with exclusion constraints to prevent overlapping time windows at the database layer.parent_id referencing the same table. Best for simple trees; query via Recursive CTEs.A.B.C). Best for deep trees and prefix-based retrieval.Aging-well designs prioritize Correctness over Performance in the early phases.