18. 3. No Real Keys
ID first_name last_name email login password active level
21 Josh Berkus josh@pgexperts.com josh jehosaphat TRUE u
47 Joshua Berkus josh@pgexperts.com joshb dbguy TRUE u
198 Josh Berkus josh@postgresql.org joshb jehosaphat FALSE u
204 Josh Berkus josh@agliodbs.com jberkus joshiam TRUE a
19. 4. No Foreign Keys
posts.content
Josh Berkus
What's up?
users.login
I'm going crazy!
Josh Berkus
jberkus
www.pornking.com
jerkyboy
Why?
selena
www.whitehouse.com
OSCON! It's too much!
www.whiteslavery.com
www.lolcats.com
I told you so ...
20. 4. Fun with Orphan Rows
posts.content
Josh Berkus
What's up?
users.login
I'm going crazy!
Josh Berkus
jberkus
Why?
selena
www.whitehouse.com
OSCON! It's too much!
www.lolcats.com
I told you so ...
21. 4. Fun With Updates
INSERT INTO threads VALUES ( .... );
if $dbh('success') then
while $these_posts.date > $cutdate
UPDATE posts SET thread = $newthread
WHERE id = $these_posts.id;
if not $dbh('success') then
while $these_posts.id > $last_id
UPDATE posts
SET thread = $oldthread
WHERE id = $these_posts.id;
DELETE FROM threads
WHERE id = $newthread;
22. 5. No Constraints
β
Users
β
userID AUTONUMBER PRIMARY KEY
β
frst_name TEXT
β
last_name TEXT
β
login TEXT
β
email TEXT
β
is_active TEXT
24. 5. No Constraints
first_name last_name email login password active level
Josh Berkus josh@pgexperts.com jberkus jehosaphat TRUE a
NULL NULL kelley@ucb k NULL FALSE u
Mike Hunt www.pornking.com c34521 c34521 TRUE I
S F gavin@sf.gov gavin twitter NULL x
25. 6. Non-Atomic Fields
name
Josh Berkus
SELECT SUBSTR(name,STRPOS(name, ' ')) ...
status
a
β¦ WHERE status = 'a' OR status = 'u' ...
26. 6. Non-Atomic Fields
name
Josh Berkus
SELECT SUBSTR(name,STRPOS(name, ' ')) ...
status
i
β¦ WHERE status = ??? ...
27. 6. Non-Atomic Fields
β
Account Type
β
5400 active individual
β
5401 inactive individual
β
5600 active board individual
β
5601 inactive board individual
β
6600 active corporate donor
β
6601 active corporate board member
β
6602 inactive corporate donor
β
6603 inactive corporate board member
31. 7. Magic Numbers
2008-02-30
SELECT user_id, min(date)
FROM user_posts
WHERE NOT (
extract(month from date) = 2
and extract (day from date) = 30 )
GROUP BY user_id;
37. 8. Polymorphic Fields
Name AccountType PrefContact ContactInfo
Josh Berkus Individual Email josh@pgexperts.com
John Dillinger Board Phone 415-555-1212
Pearson Company NULL www.pearson.com
Clorox Company Jackie 510-555-1111 x202
38. 9. EAV (entity-attribute-value)
ID Property Setting
407 Eyes Brown
407 Height 73in
407 Married? TRUE
408 Married? FALSE
408 Smoker FALSE
408 Age 37
409 Height 66in
39. 9. EAV (entity-attribute-value)
β
Diffcult tasks:
β
Find out how many men have brown hair and are
over 6 feet?
β
Make marital status and age required, but not
other things.
β
Apply constraints to feld values.
42. The Ten Ways
1.one big 6.non-atomic felds
spreadsheet 7.magic numbers
2.random naming 8.polymorphic
3.no keys felds
4.no foreign keys 9.EAV & EBlob
5.no constraints 10.ORM
43. Ten Ways to Fix Your Database
1.normalization 6.atomic felds
2.consistent 7.atomic felds
naming 8.atomic felds
3.keys 9.limit EAV &
4.foreign keys EBlob
5.constraints 10.DB design
44. More Wreckage
β
Simplifying Database Design Tutorial
β OSCON, Monday 8:30 AM
β
PostgreSQL Day San Jose
β Before OSCON, Sunday 19th, all day
β wiki.postgresql.org/wiki/PgDaySanJose2009
β
Me
β PostgreSQL Experts: www.pgexperts.com
β blog: it.toolbox.com/blogs/database-soup
β email: josh@pgexperts.com
This presentation copyright 2009 Josh Berkus, licensed for distribution under the
Creative Commons Attribution License.