Database Design Patterns: Multi-Table Architecture

Advanced database design requires patterns that span multiple tables to handle auditing, relationship complexity, and temporal state.


I. Audit and Change Tracking

Audit Columns (Tier 1)

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.

History Tables (Tier 2)

A parallel table stores a snapshot of the main table's row on every change via a database trigger.

Event Sourcing (Tier 3)

Events are the immutable source of truth; state is a projection.


II. Relationship Patterns

Soft Delete

Mark rows as deleted via a deleted_at timestamp rather than physical removal.

Polymorphic Associations

When a table (e.g., comments) can link to one of several parents (e.g., posts, videos).


III. Performance and Scaling Patterns

Materialized Views

Stored, pre-computed aggregations refreshed periodically.

Idempotency Table

A dedicated table to track unique request keys for side-effect-producing operations.

Outbox Pattern

Atomically write data to the database and an outbox table in a single transaction.


IV. Temporal and Hierarchical Data

Effective-Dating

Track row values over time using effective_from and effective_until timestamps.

Hierarchical Storage


V. Strategic Alignment

Aging-well designs prioritize Correctness over Performance in the early phases.

  1. Enforce constraints (FKs, CHECKs) from day one.
  2. Use surrogate keys to decouple relationships from data volatility.
  3. Implement auditing and soft-delete for user-controlled data.
  4. Adopt the Outbox pattern for all external integrations.