Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Dubious Database Design
Search
Andrew Godwin
September 07, 2015
Programming
310
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Dubious Database Design
My talk from DjangoCon US 2015.
Andrew Godwin
September 07, 2015
More Decks by Andrew Godwin
See All by Andrew Godwin
Reconciling Everything
andrewgodwin
1
410
Django Through The Years
andrewgodwin
0
340
Writing Maintainable Software At Scale
andrewgodwin
0
550
A Newcomer's Guide To Airflow's Architecture
andrewgodwin
0
430
Async, Python, and the Future
andrewgodwin
2
760
How To Break Django: With Async
andrewgodwin
1
840
Taking Django's ORM Async
andrewgodwin
0
870
The Long Road To Asynchrony
andrewgodwin
0
780
The Scientist & The Engineer
andrewgodwin
1
870
Other Decks in Programming
See All in Programming
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
300
Deep dive into the select statement (GopherCon UK)
jespino
0
180
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
140
Building an Out-of-Order CPU
latte72
1
750
Intent as Code
shoppingjaws
6
940
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.7k
Heart of Swift Concurrency
koher
0
270
新卒PdEのリアル
ryu1013
1
490
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
200
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
470
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
130
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
187
23k
New Earth Scene 8
popppiees
3
2.6k
Writing Fast Ruby
sferik
630
63k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.3k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
Ruling the World: When Life Gets Gamed
codingconduct
0
330
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
590
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
270
Why Our Code Smells
bkeepers
PRO
340
58k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
780
Transcript
DUBIOUS Database DESIGN
Andrew Godwin Hi, I'm Author of 1.7 Django & South
migrations Senior Software Engineer at Only hates MySQL a little
“Do this. Don't ask why.”
Learning from failure.
Spacelog 1
Spacelog 1
“Redis is fast!”
None
Spacelog 1
Read-only, forever.
“Redis is fast!”
GET chapter-1 GET chapter-2
GET entry-123 GET entry-124 GET entry-125
ZRANGEBYSCORE .... GET entry-123 GET entry-124 GET entry-125
Request page Look up key range Multi-get key range Get
speaker details
SELECT ... JOIN ... WHERE ...
Ignoring JOIN 2
“Joins are slow!”
{"id": 11, "post": "abc", "author": 1} {"id": 12, "post": "def",
"author": 2} {"id": 13, "post", "ghi", "author": 3} {"id": 1, "name": "Andrew"} {"id": 2, "name": "Brenda"} {"id": 3, "name": "Carol"}
n number of authors m × number of posts
scan all posts build dict of author -> posts scan
all authors and emit with posts
HASH JOIN
{ "id": 11, "post":"abc", "author": {"name": "Andrew"} }
{ "id": 11, "post":"abc", "author": { "name": "Andrew", "last_seen": 120993013,
} }
The server's running, it's fine! 3
Write new save file Write new save file Delete old
save file
Write new save file Write new save file ?
Tell payment processor to send Mark as processing Find unpaid
clients Mark as paid
Tell payment processor to send Mark as processing Find unpaid
clients Mark as paid
The Fastidious Modeller 4
TwitterUser FacebookUser LinkedInUser EmailUser
SELECT ... FROM TwitterUser SELECT ... FROM EmailUser SELECT ...
FROM LinkedInUser
None
None
The database isn't magic.
The Table Lover 5
“How do I make tables at runtime?”
None
Tables/columns per language Tables/columns per customer Configurable CMS columns
Columns per language 300 - 400 language variants x A
couple of translated cols per table x
DDL is very expensive.
Use JSON, hstore, or EAV-style table!
6 The Cold Boot
Decent cache hit rate Application servers mostly utilised
Great engineering!
What would happen if I deleted the entire cache?
None
The Optimist 7
Sharded PostgreSQL ElasticSearch Riak Redis Flat files + + +
+
Don't forget redundancy. And backups.
What happens if just one dies?
n services = n points of failure
The Primary Optimist 8
“The highest value PK is the most recent”
“Autoincrement will work and scale forever”
“IDs are numbers we can do maths on”
The Function Lover 9
"Why waste time fetching columns and rendering them separately?"
CREATE FUNCTION
CREATE FUNCTION ... import jinja2
bit.ly/whynotpg
None
SELECT render(template, id) FROM pages WHERE %s ~ url;
None
There's a reason behind every rule.
Ask why, or try yourself. Don't write it off without
context.
Thanks. Andrew Godwin @andrewgodwin