Chapter 20 — Further Reading
The balance (everyone)
- Articles on "normalization vs. denormalization trade-offs." Read several; the judgment is what matters. Pair with Chapter 19 so you hold both directions at once.
- "When to denormalize" practitioner posts — concrete signals (read/write ratio, hot aggregations) and cautionary tales of drift (Case Study 2).
- Martin Kleppmann, Designing Data-Intensive Applications — chapters on data models and on derived data; an excellent treatment of when precomputation/denormalization is the right call.
Techniques (💻 Developer · 🏗️ DBA)
- Materialized views & refresh strategies (PostgreSQL docs +
pg_cron) — the preferred, managed denormalization (Case Study 1). - Trigger-maintained aggregates — patterns for keeping counts/totals correct across all write paths, including cascades (Case Study 2's Option B).
- "Counter tables" and high-write counters — advanced patterns for maintaining counts under heavy concurrent writes (ties to Chapters 26–27).
Analytics & warehousing (📊 Analyst) — pairs with Chapter 34
- Kimball, The Data Warehouse Toolkit — dimensional modeling and star schemas: denormalization as the correct default for analytics, with the reasoning.
- OLTP vs. OLAP explainers — why transactional schemas normalize and analytical schemas denormalize.
Performance first (🏗️ DBA) — pairs with Chapter 23
- "Index before you denormalize." Reinforces the professional sequence — an index often removes a read bottleneck with no redundancy. Read after Chapter 23.
- Markus Winand, use-the-index-luke.com — many "slow query" problems are index problems, not modeling problems.
Reference (this book)
- Chapter 15 — Materialized Views: the managed denormalization tool.
- Chapter 23 — Indexing: the lower-risk first resort for read speed.
- Chapter 34 — Data Warehousing: denormalized star schemas in depth.
- Appendix I — SQL Cookbook: maintained-aggregate and summary-table recipes.
Do, don't just read
- Build Case Study 1 on Mercado: a
product_review_statsmatview + scheduled refresh; compare query speed to the live aggregation (ongenerate_data.sql). - Reproduce Case Study 2's drift: add a hand-maintained count, then delete rows via a cascade and watch the count go wrong. Fix it with a trigger.
- Practice the sequence: for one slow read, try an index first, and only denormalize if the index doesn't suffice.
Next: Chapter 21 — Data Modeling Patterns: reusable solutions to recurring design problems.