Greg Nudelman wrote:

> Design DB tables from the following Object scheme:
>
> CustomersAbstractSuperclass
> ----------------
> id
> name
> address
> ----------------
> ----------------
>
> inherited individualy by:
>
> Customer
> ----------------
> favorites
> comments
> ----------------
> ----------------
>
> and:
>
> WholesaleCustomer
> ----------------
> limit
> pin
> department
> ----------------
> ----------------
>
>
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> I proposed a single table:
>
> Customers
> ----------------
> id
> name
> address
> favorites
> comments
> limit
> pin
> department
> objectType
>
No good.  I assume the objectType field indicates if the record is that 
of a WholesaleCustomer or Customer.  That means there are some fields 
that depend on something other than the primary key.  This violates 
second normal form (2nf).  Right there, you should have known you needed 
at least a second table.  Keep everything that depends on the primary 
key (id) and ONLY the primary key in the first table and move everything 
else to a second table.  Thus:

Table1:
-------
id
objectType
name
address

Table2
-------
id
favorites
comments
limit
pin
department

As you can plainly see, Table2 has two independent sets of fields only 
one of which is dependent on the key at a time.  So break it into two 
separate tables.

Table2A (Customer)
---------
id
favorites
comments

Table2B (WholesaleCustomer)
--------
id
limit
pin
department

So now all fields in each table are related to the key of each table and 
the fields have no dependencies with each other.  If you wanted a list 
of all customers, you would select against Table1.  If you wanted a list 
of generic (Retail?) customers, you would join Table1 with Table2A.  If 
you wanted a list of Wholesale customers, you would join Table1 with 
Table2B.

You could also suggest two views, one for each join, to simplify working 
with this group of tables.

> to which Mr. interviewer replied: this will waste space.  As 
> WholesaleCustomer record will have Customer fields empty (and vice 
> versa). Also, you will be required to search one giant table by 
> specific objectType to get customers or wholesale customers:
>
> SELECT * FROM Customers WHERE objectType=1
>
Another problem is that this statement will return a result set with 
fields that are not applicable.  If objectType=1 represents 
WholesaleCustomer, the result set will still contain a favorites and 
comments columns.  Assuming the fields would contain null values, they 
still should not be there at all.

> I said OK, alternatively (WORSE) you can also split this in 2 tables, 
> Customer and WholesaleCustomer.
>
> However, if you often have to run queries against the whole set, 
> you'll end up with lots of redundant app logic or SQL joins/unions of 
> 2 tables to do composite sorts, paging through the whole collection, 
> and getting totals/averages from 2 types of objects.
>
True.  The name and address fields are common so should be in one table.

> He proposed a third scheme then.
>
> 1) Can you guess what it was (hint: he used 3 tables)?
>
My guess is above.

> 2) Would this third scheme be better then my single table?  Why?
>
Yes.  As all information common to all customer resides in one table, 
you can retrieve that information with a single select statement when 
you want to do something that uses all customers.  The information that 
is dependent on the type of customer is located in separate tables. 
 This is beneficial in two ways:

1. If you are working with one type of customer, you can retrieve all 
applicable information (and no non applicable information) with a single 
select statement.

  select t1.id, name, address, favorites, comments
    from table1 t1, table2a t2
    where t1.objectType=0 and t1.id = t2.id;
or
  select t1.id, name, address, limit, pin, department
    from table1 t1, table2b t2
    where t1.objectType=1 and t1.id = t2.id;

2. The arrangement is scalable.  Should there ever be a requirement for 
a third type of customer with a different set of data, simply add 
another table with the appropriate fields.  No modifications to the 
existing tables will be needed and existing applications will not break.


Tomm





To change your membership options, refer to:
http://www.sys-con.com/java/list.cfm

Reply via email to