Cover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Table of Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16
Notes on the Second Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17
Who This Book Is For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17
About This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
Online Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
1. What's an Antipattern? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20
Types of Antipatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20
Anatomy of an Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21
Entity-Relationship Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
Example Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
Part I—Logical Database Design Antipatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26
2. Jaywalking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28
Objective: Store Multivalue Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29
Antipattern: Format Comma-Separated Lists . . . . . . . . . . . . . . . . . . . . . . . . . .29
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .32
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Solution: Create an Intersection Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Mini-Antipattern: Splitting CSV Into Rows . . . . . . . . . . . . . . . . . . . . . . . . . .36
3. Naive Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
Objective: Store and Query Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41
Antipattern: Always Depend on One's Parent . . . . . . . . . . . . . . . . . . . . . . . . .41
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
Solution: Use Alternative Tree Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
Mini-Antipattern: It Works on My Computer . . . . . . . . . . . . . . . . . . . . . . . . . .58
4. ID Required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .60
Objective: Establish Primary Key Conventions . . . . . . . . . . . . . . . . . . . . . . .61
Antipattern: One Size Fits All . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .67
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .67
Solution: Tailored to Fit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .68
Mini-Antipattern: Is a BIGINT Big Enough? . . . . . . . . . . . . . . . . . . . . . . . . . .70
5. Keyless Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .72
Objective: Simplify Database Architecture . . . . . . . . . . . . . . . . . . . . . . . . . .73
Antipattern: Leave Out the Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .76
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77
Solution: Declare Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77
6. Entity-Attribute-Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .80
Objective: Support Variable Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .80
Antipattern: Use a Generic Attribute Table . . . . . . . . . . . . . . . . . . . . . . . . .82
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .87
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .88
Solution: Model the Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89
7. Polymorphic Associations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96
Objective: Reference Multiple Parents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .97
Antipattern: Use Dual-Purpose Foreign Key . . . . . . . . . . . . . . . . . . . . . . . . . .97
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Solution: Simplify the Relationship . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102
8. Multicolumn Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .108
Objective: Store Multivalue Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . .108
Antipattern: Create Multiple Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .112
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
Solution: Create Dependent Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
Mini-Antipattern: Storing Prices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .115
9. Metadata Tribbles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .118
Objective: Support Scalability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
Antipattern: Clone Tables or Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .124
Solution: Partition and Normalize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
Part II—Physical Database Design Antipatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
10. Rounding Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .132
Objective: Use Fractional Numbers Instead of Integers . . . . . . . . . . . . .133
Antipattern: Use FLOAT Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
Solution: Use NUMERIC Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
11. 31 Flavors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140
Objective: Restrict a Column to Specific Values . . . . . . . . . . . . . . . . . . .140
Antipattern: Specify Values in the Column Definition . . . . . . . . . . . . . .141
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .145
Solution: Specify Values in Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .145
Mini-Antipattern: Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
12. Phantom Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .150
Objective: Store Images or Other Bulky Media . . . . . . . . . . . . . . . . . . . . . .151
Antipattern: Assume You Must Use Files . . . . . . . . . . . . . . . . . . . . . . . . . . . .151
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
Solution: Use BLOB Data Types As Needed . . . . . . . . . . . . . . . . . . . . . . . . . . .156
13. Index Shotgun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160
Objective: Optimize Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
Antipattern: Using Indexes Without a Plan . . . . . . . . . . . . . . . . . . . . . . . . .161
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .166
Solution: MENTOR Your Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .166
Mini-Antipattern: Indexing Every Column . . . . . . . . . . . . . . . . . . . . . . . . . . .171
Part III—Query Antipatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
14. Fear of the Unknown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176
Objective: Distinguish Missing Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176
Antipattern: Use Null as an Ordinary Value, or Vice Versa . . . . . . . . .177
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .180
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181
Solution: Use Null as a Unique Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182
Mini-Antipattern: NOT IN (NULL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
15. Ambiguous Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
Objective: Get Row with Greatest Value per Group . . . . . . . . . . . . . . . . . .189
Antipattern: Reference Nongrouped Columns . . . . . . . . . . . . . . . . . . . . . . . . .189
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .192
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .192
Solution: Use Columns Unambiguously . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .193
Mini-Antipattern: Portable SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198
16. Random Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .200
Objective: Fetch a Sample Row . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .201
Antipattern: Sort Data Randomly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .201
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .202
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .203
Solution: In No Particular Order… . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .203
Mini-Antipattern: Query for Multiple Random Rows . . . . . . . . . . . . . . . . . .207
17. Poor Man's Search Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210
Objective: Full-Text Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210
Antipattern: Pattern Matching Predicates . . . . . . . . . . . . . . . . . . . . . . . . . .211
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212
Solution: Use the Right Tool for the Job . . . . . . . . . . . . . . . . . . . . . . . . . .213
18. Spaghetti Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .224
Objective: Decrease SQL Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .225
Antipattern: Solve a Complex Problem in One Step . . . . . . . . . . . . . . . . . .225
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .227
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .228
Solution: Divide and Conquer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .230
19. Implicit Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .234
Objective: Reduce Typing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235
Antipattern: A Shortcut That Gets You Lost . . . . . . . . . . . . . . . . . . . . . . . .235
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .238
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .238
Solution: Name Columns Explicitly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .239
Part IV—Application Development Antipatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .242
20. Readable Passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244
Objective: Recover or Reset Passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244
Antipattern: Store Password in Plain Text . . . . . . . . . . . . . . . . . . . . . . . . .245
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .247
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .248
Solution: Store a Salted Hash of the Password . . . . . . . . . . . . . . . . . . . . .249
Mini-Antipattern: Storing Hash Strings in VARCHAR . . . . . . . . . . . . . . . . .256
21. SQL Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .258
Objective: Write Dynamic SQL Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .259
Antipattern: Execute Unverified Input As Code . . . . . . . . . . . . . . . . . . . . .259
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .266
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .267
Solution: Trust No One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .267
Mini-Antipattern: Query Parameters inside Quotes . . . . . . . . . . . . . . . . . .274
22. Pseudokey Neat-Freak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .276
Objective: Tidy Up the Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .277
Antipattern: Filling in the Corners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .277
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .279
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .280
Solution: Get Over It . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .280
Mini-Antipattern: Auto-Increment per Group . . . . . . . . . . . . . . . . . . . . . . . .283
23. See No Evil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .284
Objective: Write Less Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .285
Antipattern: Making Bricks Without Straw . . . . . . . . . . . . . . . . . . . . . . . . . .285
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .288
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .288
Solution: Recover from Errors Gracefully . . . . . . . . . . . . . . . . . . . . . . . . . .288
Mini-Antipattern: Reading Syntax Error Messages . . . . . . . . . . . . . . . . . . .290
24. Diplomatic Immunity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .292
Objective: Employ Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .292
Antipattern: Make SQL a Second-Class Citizen . . . . . . . . . . . . . . . . . . . . . .293
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .294
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .295
Solution: Establish a Big-Tent Culture of Quality . . . . . . . . . . . . . . . . .295
Mini-Antipattern: Renaming Things . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
25. Standard Operating Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .306
Objective: Use Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .307
Antipattern: Follow the Leader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .308
How to Recognize the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .311
Legitimate Uses of the Antipattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .312
Solution: Adopt Modern Application Architecture . . . . . . . . . . . . . . . . . . .313
Mini-Antipattern: Stored Procedures in MySQL . . . . . . . . . . . . . . . . . . . . . .314
Part V—Bonus: More Foreign Key Mini-Antipatterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .318
26. Foreign Key Mistakes in Standard SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .320
Reversing the Direction of Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .320
Referencing Tables Before They Have Been Created . . . . . . . . . . . . . . . . . .321
Referencing No Key of the Parent Table . . . . . . . . . . . . . . . . . . . . . . . . . . . .323
Creating Separate Constraints for Each Column in a Compound Key . . .323
Using the Wrong Column Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .324
Using Mismatched Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .325
Using Mismatched Character Collations . . . . . . . . . . . . . . . . . . . . . . . . . . . . .327
Creating Orphan Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .328
Using the SET NULL Option for Non-Nullable Columns . . . . . . . . . . . . . . . .329
Making Duplicate Constraint Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . .330
Using Incompatible Table Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
27. Foreign Key Mistakes in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332
Using Incompatible Storage Engines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332
Using Large Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .333
MySQL Foreign Keys to Non-Unique Indexes . . . . . . . . . . . . . . . . . . . . . . . . . .334
Using Inline References Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .336
Using Default References Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .337
Using Incompatible Table Types in MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . .338
A1. Rules of Normalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340
What Does Relational Mean? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340
Myths About Normalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .342
What Is Normalization? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .343
Common Sense . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .354
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .356
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358
– SYMBOLS – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358
– DIGITS – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358
– A – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358
– B – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .359
– C – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .359
– D – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .360
– E – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .362
– F – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .362
– G – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
– H – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
– I – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
– J – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .364
– K – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .364
– L – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .364
– M – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .365
– N – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .366
– O – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .367
– P – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .367
– Q – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .369
– R – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .369
– S – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .370
– T – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .372
– U – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .372
– V – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .373
– W – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .373
– X – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .373
– Z – . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .373
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .129
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .139
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .223
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .241
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .305
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .317
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .319
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .339
Blank Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .355
Each chapter of the book helps to identify, explain and correct a unique and dangerous antipattern. In the four parts of the book, antipatterns are grouped in terms of logical database design, physical database design, queries, and application development.
There is a high probability that the database layer of your application already contains problems such as Index Shotgun, Keyless Entry, Fear of the Unknown and Spaghetti Query. This book will help you and your team find them.
Even better, it will show you how to eliminate them and how to avoid these and other problems in the future.