Search code examples
performancedatabase-designreadabilitymaintainability

Database normalization design - single or multiple tables


Should this be represented in the database as 1 table or 3 tables? I and my friend have different opinions about this so I'd like to see the general views on this. (Maybe it should be a vote for either solution?)

Create Table Order
// Basic fields of the table
 - ID (Primary key)
 - CustomerID  (integer, with a FK)
 - Quantity
 - ProductID  (integer, with a FK)

 // Then depending on user selection, either these fields need to be specified 
 // (could be factored out to a separate table):
 {
 - InternalAccountID (integer, with a FK)
 - InternalCompanyID (integer, with a FK)
 }

 // Or these (could be factored out to a separate table):
 {
 - ExternalAccountNumber (free text string)
 - ExternalCompanyName (free text string)
 - ExtraInformation (free text string)
 }

1 table approach:

Pros:

  • performance (one insert as opposed to two, FK check, no joins)
  • probably takes less space (the extra tables have overhead + indexes + extra ID field)
  • one table as opposed to three
  • hardly justifiable to have split out to new tables just for 2+3 fields (or what?)

Cons:

  • Nullable fields
  • Potentially extra "type" column (can be skipped)
  • Breaks 3NF (?)

Pros and cons kindly requested as well as personal opinions. :)

EDIT: I tried simplifying the example by using different entities than I am actually using so any suggestions to altering the model wouldn't really help me. I.e. focus on the technical aspects more than the domain model please.


Solution

  • My opinion would be that if

     // Then depending on user selection, either these fields need to be specified 
     // (could be factored out to a separate table):
     {
     - InternalAccountID (integer, with a FK)
     - InternalCompanyID (integer, with a FK)
     }
    
     // Or these (could be factored out to a separate table):
     {
     - ExternalAccountNumber (free text string)
     - ExternalCompanyName (free text string)
     - ExtraInformation (free text string)
     }
    

    are always 1:1 with an order (i.e., you can't have 3 accountIDs), then leave it as one table. To take care of your null issue, you could add one more column called InternalCustomer (boolean) or CustomerType (varChar) that you could use to define an internal or external customer to know which of the two sets of fields you should look at for a specific customer.

    Since we don't know the full use of this data or the schema for the entire DB, any response on this can't really be fully qualified.