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
320
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
Working With Risk: Lessons From Mountain Rescue
andrewgodwin
1
28
Reconciling Everything
andrewgodwin
1
420
Django Through The Years
andrewgodwin
0
350
Writing Maintainable Software At Scale
andrewgodwin
0
560
A Newcomer's Guide To Airflow's Architecture
andrewgodwin
0
440
Async, Python, and the Future
andrewgodwin
2
770
How To Break Django: With Async
andrewgodwin
1
860
Taking Django's ORM Async
andrewgodwin
0
880
The Long Road To Asynchrony
andrewgodwin
0
790
Other Decks in Programming
See All in Programming
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
590
Engineering Biometric UX Across Android Versions | DroidKnights 2026
ryunen344
0
120
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
3.1k
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
6.1k
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
5
670
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.8k
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
1.2k
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
160
クラウドゲーミングのパフォーマンス最適化に挑む / Cloud Gaming Performance Tuning
vivion
0
320
パスワード再設定メールのURLについて知っておこう
uyuki234
0
210
Kotlinの15年とServer-Side Kotlin
n_takehata
1
190
No More NoSuchMethodError
exoego
1
120
Featured
See All Featured
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
440
WENDY [Excerpt]
tessaabrams
14
40k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
Fireside Chat
paigeccino
43
4.1k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Leo the Paperboy
mayatellez
10
2.4k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
560
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
890
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
600
How GitHub (no longer) Works
holman
316
150k
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