ALTER TABLE users ADD COLUMN full_name TEXT GENERATED ALWAYS AS (first_name || ' ' || last_name) STORED;
3. Combining Tables
Strategy
When
Merge 1:1 tables
Always joined together, low NULL ratio
Embed 1:N as array/JSON
Small child set, never queried independently
Pre-join fact + dimensions
OLAP wide tables for analytics
4. Using Materialized Views
Feature
Postgres
Oracle
Create
CREATE MATERIALIZED VIEW
CREATE MATERIALIZED VIEW
Refresh
REFRESH MATERIALIZED VIEW [CONCURRENTLY]
DBMS_MVIEW.REFRESH
Auto-refresh
External (cron/trigger)
ON COMMIT / scheduler
Indexable
Yes
Yes
Example: Materialized Sales Summary
CREATE MATERIALIZED VIEW daily_sales ASSELECT date_trunc('day', placed_at) AS day, SUM(total) AS revenue, COUNT(*) AS ordersFROM ordersGROUP BY 1WITH DATA;CREATE UNIQUE INDEX ON daily_sales(day);REFRESH MATERIALIZED VIEW CONCURRENTLY daily_sales;
5. Implementing Summary Tables
Type
Update Strategy
Rollup table
Incremental via trigger or batch job
Pre-aggregated counters
UPDATE on each write
Bucketed snapshots
Hourly/daily snapshot of metrics
6. Handling Data Consistency in Denormalized Schemas
Mechanism
Use
Triggers
Synchronous propagation within DB
Change Data Capture (CDC)
Debezium → downstream sinks
Outbox + Event Bus
Reliable async propagation
Scheduled Reconciliation
Nightly diff + fix drift
Application Transactions
Same tx writes source + copy
Warning: Denormalized data WILL drift. Always have a reconciliation job to detect and repair inconsistencies.