-- normal.txt

Bringing tables into normal form usually involves splitting tables to reduce redundancy.  For example, PERSON can be split by adding a ZIPCODE table that is keyed off of ZIP, and provides the associated CITY and STATE information (and possibly STREET and AREA_CODE).  In this way, only the ZIP needs to be stored in the PERSON table - the rest of the data can be looked up as needed from the new ZIPCODE table.  This would bring the table into 2NF.

The ACCOUNT table could also be split, pulling the shipping address information into a new SHIPPING table, with one entry for each distinct shipping address, along with a SHIPPING_ID attribute as the primary key.  The ACCOUNT table would then contain the ID of the row that contains the shipping address.  If multiple accounts all ship to the same address, they would all refer to the same row.  This would bring the table into 3NF.

Note that bringing the entire schema into 3NF could result in many extra tables, without much additional value.  For example, pure 3NF would require us to build a STATE table, with a row for each STATE, along with a STATE_ID.  This would allow for easy maintenance if the name of a state ever changed - simply change the state name in the row, and every entry that refers to it through the associated STATE_ID will get the update.  But, this flexibility will probably never be needed - state names are very stable.

This gets fuzzy with attributes like STREET - 3NF would require a STREET table, with an entry for each STREET name used in the database.  That way, if several addresses were on the same street, and the street name changed, it would be easy to update them all at once.  However, this should be weighed against the likelihood of a street name being changed (it sometimes happens), how many addresses have a common street name, and how much extra data and complexity are introduced by including an extra table.