Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
SQL Antipatterns
                           Strike Back
                             Bill Karwin

                        ...
Antipattern Categories
                          Database Design                 Database Creation
                       ...
Antipattern Categories
                                                          Database Creation
                       ...
Database Design Antipatterns


                     1. Metadata Tribbles
                     2. Entity-Attribute-Value
  ...
Metadata Tribbles
                         I want these things off the ship. I don’t care if it takes
                    ...
Metadata Tribbles



                     • Objective:       improve performance
                         of a very large ...
Metadata Tribbles


                     • Antipattern:        separate into many tables
                         with sim...
Metadata Tribbles

                     • Must create a new table for each new value
                         CREATE TABLE...
Metadata Tribbles

                     • Automatic primary keys cause conflicts:
                         CREATE TABLE Bug...
Metadata Tribbles

                     • Difficult to query across tables
                         SELECT b.status, COUNT(...
Metadata Tribbles


                     • Table structures are not kept in sync
                             ALTER TABLE ...
Metadata Tribbles
                     • Solution #1:            use horizontal partitioning
                         •   ...
Metadata Tribbles
                     • Solution #2:         use vertical partitioning
                         •   Move ...
Metadata Tribbles


                     • Columns can also be tribbles:
                         CREATE TABLE Bugs (
    ...
Metadata Tribbles
                     • Solution #3:       add a dependent table
                         CREATE TABLE Bu...
Entity-Attribute-Value
                                  If you try and take a cat apart to see how it works,
            ...
Entity-Attribute-Value
                     • Objective: make a table with a variable
                           set of at...
Entity-Attribute-Value

                • Antipattern: store all attributes in a
                         second table, on...
Entity-Attribute-Value


                         bug_id   attr_name           attr_value
                          1234  ...
Entity-Attribute-Value
                     • Difficult to rely on attribute names

                         bug_id   attr_...
Entity-Attribute-Value
                     • Difficult to enforce data type integrity

                         bug_id   a...
Entity-Attribute-Value

                     • Difficult to enforce mandatory attributes
                         (i.e. NOT...
Entity-Attribute-Value
                     • Difficult to enforce referential integrity for
                         attri...
Entity-Attribute-Value
                • Difficult to reconstruct a row of attributes:
                         SELECT b.bu...
Entity-Attribute-Value


                     • Solution:         use metadata for metadata
                         •   D...
Entity-Attribute-Value
                     • Solution #1:                Single Table Inheritance
                       ...
Entity-Attribute-Value
                     • Solution #2:           Concrete Table Inheritance
                         •...
Entity-Attribute-Value
                     • Solution #2:         Concrete Table Inheritance
                         •  ...
Entity-Attribute-Value
                     • Solution #3:              Class Table Inheritance
                         •...
Entity-Attribute-Value
                     • Solution #3:          Class Table Inheritance
                         •   E...
Entity-Attribute-Value

                     • Appropriate usage of EAV:
                         •   If attributes must b...
Polymorphic Associations
                         Of course, some people do go both ways.
                                ...
Polymorphic Assocations
                • Objective: reference multiple parents
                                          ...
Polymorphic Assocations
                • Can’t make a FOREIGN KEY constraint
                         reference two table...
Polymorphic Assocations
                • Instead, you have to define table with no
                         FOREIGN KEY or...
Polymorphic Assocations
                                comment
                                        comment issue_type...
Polymorphic Assocations
                • You can’t use a different table for each row.
                         You must ...
Polymorphic Assocations
                • Instead, join to each parent table:
                         SELECT *
          ...
Polymorphic Assocations
                • Solution #1:                 exclusive arcs
                         CREATE TABL...
Polymorphic Assocations
                • Solution #1:             exclusive arcs
                         • Referential i...
Polymorphic Assocations
                • Solution #2:   reverse the relationship

                                 BUGS
 ...
Polymorphic Assocations
                • Solution #2:                 reverse the relationship
                         C...
Polymorphic Assocations
                • Solution #2:                   reverse the relationship
                        ...
Polymorphic Assocations
                • Solution #3:   use a base parent table

                     BUGS         ISSUES...
Polymorphic Assocations
                • Solution #3:                   use a base parent table
                         ...
Polymorphic Assocations
                • Solution #3:              use a base parent table
                         • Ref...
Polymorphic Assocations
                • Enforcing disjoint subtypes:
                         CREATE TABLE Issues (
    ...
Naive Trees



                              48
Monday, April 20, 2009                 48
Naive Trees


                • Objective:               store/query hierarchical data
                         •   Catego...
Naive Trees
                                                       (1) Fran:
                                             ...
Naive Trees
                • Adjacency List
                         •   Naive solution nearly everyone uses
            ...
Naive Trees
                • Adjacency List
                         •   Easy to inserting a new comment:
               ...
Naive Trees
                • Adjacency List
                         •   Querying a node’s immediate children is easy:
  ...
Naive Trees
                • Adjacency List
                         •   Hard to query all descendants in a deep tree:
  ...
Naive Trees
                • Solution #1:                   Path Enumeration
                         •   Store chain of ...
Naive Trees
                • Solution #1:               Path Enumeration
                         •   Easy to query all a...
Naive Trees
                • Solution #1:                Path Enumeration
                         •   Easy to add child ...
Naive Trees
                • Solution #2:               Nested Sets
                         •   Each comment encodes its...
Naive Trees
                • Solution #2:                          Nested Sets
                                          ...
Naive Trees
                • Solution #2:                 Nested Sets

             comment_id      nsleft        nsright...
Naive Trees
                • Solution #2:               Nested Sets
                         •   Easy to query all ancest...
Naive Trees
                • Solution #2:                          Nested Sets
                                          ...
Naive Trees
                • Solution #2:              Nested Sets
                         •   Easy to query all descend...
Naive Trees
                • Solution #2:                          Nested Sets
                                          ...
Naive Trees
                • Solution #2:                     Nested Sets
                         •   Hard to insert a n...
Naive Trees
                • Solution #2:                          Nested Sets
                                          ...
Naive Trees
                • Solution #2:                    Nested Sets
                         •   Hard to query the p...
Naive Trees
                • Solution #3:                  Closure Table
                         •   Store every path fr...
Naive Trees
                • Solution #3:                      Closure Table
                                            ...
Naive Trees
                • Solution #3:
                                                                              a...
Naive Trees
                • Solution #3:             Closure Table
                         •   Easy to query descendant...
Naive Trees
                • Solution #3:             Closure Table
                         •   Easy to query ancestors ...
Naive Trees
                • Solution #3:              Closure Table
                         •   Easy to insert a new ch...
Naive Trees
                • Solution #3:              Closure Table
                         •   Easy to delete a child ...
Naive Trees
                • Solution #3:              Closure Table
                         •   Easy to delete the subt...
Naive Trees
                • Solution #3:
                                                                ancestor descen...
Naive Trees
                • Summary of Designs:
                          Number of    Query         Query    Modify   R...
Antipattern Categories
                         Database Design                   Database Creation
                      ...
Database Creation Antipatterns


                     5. ENUM Antipattern
                     6. Rounding Errors
        ...
ENUM Antipattern



                                80
Monday, April 20, 2009                      80
ENUM Antipattern


                     • Objective:      restrict a column
                         to a fixed set of valu...
ENUM Antipattern


                     • Antipattern:       use ENUM data type,
                         when the set of ...
ENUM Antipattern


                     • Changing the set of values is a metadata
                         alteration
   ...
ENUM Antipattern

                     • Difficult to get a list of possible values
                         SELECT column_...
ENUM Antipattern


                     • Solution:        use ENUM only if values are
                         set in sto...
ENUM Antipattern
                     • Use a lookup table if values may change
                         CREATE TABLE BugS...
ENUM Antipattern


                     • Adding/removing a value is a data
                         operation, not a meta...
ENUM Antipattern

                     • Use an attribute to retire values, not
                         DELETE
          ...
Rounding Errors
                          10.0 times 0.1 is hardly ever 1.0.
                                      — Brian...
Rounding Errors



                     • Objective:         store real numbers exactly
                         •   Espec...
Rounding Errors


                     • Antipattern:          use FLOAT data type
                         ALTER TABLE Bu...
Rounding Errors

                     • FLOAT is inexact
                         SELECT hours FROM Bugs
                 ...
Rounding Errors



                     • Inexact decimals                      assuming infinite precision
               ...
Rounding Errors


                     • IEEE 754 standard for representing
                         floating-point numbers...
Rounding Errors

                     • Solution: use NUMERIC data type
                         ALTER TABLE Bugs
        ...
Indexes are Magical
                            Whenever any result is sought, the question will then
                    ...
Indexes are Magical



                • Objective: execute queries with optimal
                         performance




...
Indexes are Magical


                • Antipatterns:
                         •   Creating indexes blindly

             ...
Indexes are Magical
                • Creating indexes blindly:
                         CREATE TABLE Bugs (
             ...
Indexes are Magical
                • Executing non-indexable queries:
                         •   SELECT * FROM Bugs
   ...
Indexes are Magical
                • Telephone book analogy
                         •   Easy to search for Dean Thomas: ...
Indexes are Magical
                • Rejecting indexes because of their overhead:
                                       ...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                         Measure
                   ...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                                      • Profile your ...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                                      • Analyze the ...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                                     • Could an inde...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                                      • After creati...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                                     • Indexes are c...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                                      • Indexes requ...
Indexes are Magical
                • Solution: “MENTOR” your indexes
                         • Sounds like the name     ...
Antipattern Categories
                          Database Design                   Database Creation
                     ...
Query Antipatterns

                     8. NULL antipatterns
                     9. Ambiguous Groups
                   ...
NULL Antipatterns
                    As we know, there are known knowns; there are things we know
                  we kn...
NULL Antipatterns



                • Objective: handle “missing” values,
                         store them as missing,...
NULL Antipatterns



                • Antipatterns:
                         •   Use NULL as an ordinary value

         ...
NULL Antipatterns


                • Using NULL in most expressions results in
                         an unknown value....
NULL Antipatterns


                • The opposite of unknown is still unknown.
                         SELECT * FROM Bug...
NULL Antipatterns



                • Choosing an ordinary value in lieu of NULL:
                         UPDATE Bugs SE...
NULL Antipatterns


                • Choosing an ordinary value in lieu of NULL:
                         UPDATE Bugs SET...
NULL Antipatterns


                • Choosing an ordinary value in lieu of NULL:
                         •   Any given v...
NULL Antipatterns


                • Solution: use NULL appropriately
                         •   NULL signifies “missing...
NULL Antipatterns
                • Understanding NULL in expressions
                           Expression         Expect...
NULL Antipatterns
                • Understanding NULL in boolean expressions
                           Expression      E...
NULL Antipatterns
                • SQL supports IS NULL predicate that
                         returns true or false, ne...
NULL Antipatterns
                • SQL-99 supports IS DISTINCT FROM
                         predicate that returns true ...
NULL Antipatterns
                • Change NULL to ordinary value on demand
                         with COALESCE():
    ...
Ambiguous Groups
                         Please accept my resignation. I don’t want to belong
                           ...
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Naive Trees • Objective: store/query
Upcoming SlideShare
Loading in …5
×

Naive Trees • Objective: store/query Sql Antipatterns Strike Back

243,866 views

Published on

Naive Trees


• Objective: store/query hierarchical data
• Categories/subcategories

• Bill of materials

• Threaded discussions




49
Monday, April 20, 2009 49

  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Don’t failed to see the light. Deserve wealth in order to design your destiny as you wish and obtain fame and power to rule your world. become your title in just few days. If interested to join the Illuminati brotherhood headquarters at (U.S.A) Email chamberlinwilliams099@gmail.com For your online initiation.No matter where you are. No distance can affect the work of our baphomet.Do not be deceived and beware of online internet fraudsters claiming to be one of us do make sure you confirm first before making an inquiries… Email chamberlinwilliams099@gmail.com now and say yes to your dreams. Hail Baphomet…
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • For online course coupons and discount visit http://www.todaycourses.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Very Nice, If you want more good Presentations Please visit www.ThesisScientist.com, Its a wonderful website for latest Presentations and Research
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Njce! Thanks for sharing.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

×