Normalization isnt always obvious or clear-cut; mistakes are possible, and
its important not to get carried away. For example, the client_name column may also be a candidate for its own table, especially if other client-related col- umns are added, such as phone number, billing address, and so on. The shipping_address column may not be one of those columns, however. It may be more closely related to the order than the client, especially if one client has more than one shipping address, or if an order can be shipped to a third party.
1.16.4 Boyce-Codd Normal Form
Boyce-Codd Normal Form (BCNF) eliminates any dependent column that does not depend on a candidate key. A candidate key is one or more columns that uniquely identify rows in the table. A table may have more than one candidate key, only one of which may be chosen as the primary key. BCNF is slightly stronger than 3NF. BCNF refers to any dependent col- umn whereas 3NF talks about any non-key column. Another difference is that BCNF refers to candidate keys, not just primary keys. In the following example, salesperson_skill identifies which skills are pos- sessed by which salespersons. Both salesperson_id and salesperson_name are unique for all salespersons. That means salesperson_name, together with sales_skill_id, forms a candidate key for salesperson_skill; this is shown as a UNIQUE constraint separate from the PRIMARY KEY. CREATE TABLE sales_skill ( sales_skill_id INTEGER NOT NULL PRIMARY KEY, description LONG VARCHAR );
CREATE TABLE salesperson_skill (
salesperson_id INTEGER NOT NULL, salesperson_name VARCHAR ( 100 ) NOT NULL, sales_skill_id INTEGER NULL REFERENCES sales_skill, PRIMARY KEY ( salesperson_id, sales_skill_id ), UNIQUE ( salesperson_name, sales_skill_id ) ); The salesperson_skill table is in Third Normal Form because there are no col- umns that violate the rule that non-key columns must depend on the primary key, simply because there are no non-key columns at all; every column in sales- person_skill is part of one or the other candidate keys. However, salesperson_skill is not in Boyce-Codd Normal Form because salesperson_name depends on salesperson_id, and vice versa, and neither one of those columns forms a candidate key all by itself. The solution is to move one of the offending columns, either salesperson_id or salesperson_name, to the salesperson table. CREATE TABLE salesperson ( salesperson_id INTEGER NOT NULL PRIMARY KEY, salesperson_name VARCHAR ( 100 ) NOT NULL UNIQUE );
CREATE TABLE sales_skill (
sales_skill_id INTEGER NOT NULL PRIMARY KEY, description LONG VARCHAR );