I'm in the process of designing my first database and I'm trying to follow the normalization rules up to 3NF. I am using the following definitions for normalization:
- 1NF: No repeating groups and a primary key is identified.
- 2NF: Partial key dependencies are removed. All non-key columns are fully dependent on the primary key.
- 3NF: Transitive dependencies and non-key dependencies are removed.
The table is for storing information about pet food. Here is a basic example of the table before any normalization:
╔════════════╦═════════╦═════════════╦════════════╦═══════════╦═══════════════╦═══════╗
║ Brand ║ Flavor ║ Animal Type ║ Breed Size ║ Age Group ║ Ingredients ║ Price ║
╠════════════╬═════════╬═════════════╬════════════╬═══════════╬═══════════════╬═══════╣
║ Purina ║ Chicken ║ Dog ║ Small ║ Adult ║ Chicken, Salt ║ 18.99 ║
╠════════════╬═════════╬═════════════╬════════════╬═══════════╬═══════════════╬═══════╣
║ BlueWilder ║ Chicken ║ Dog ║ Small ║ Adult ║ Chicken, Salt ║ 18.99 ║
╚════════════╩═════════╩═════════════╩════════════╩═══════════╩═══════════════╩═══════╝
Following the 1NF definition above, I added a primary key column. In this case, the only issue was in the Ingredients column containing multiple entries per record:
╔═════════╦════════════╦═════════╦═════════════╦════════════╦═══════════╦═════════════╦═══════╗
║ Food ID ║ Brand ║ Flavor ║ Animal Type ║ Breed Size ║ Age Group ║ Ingredients ║ Price ║
╠═════════╬════════════╬═════════╬═════════════╬════════════╬═══════════╬═════════════╬═══════╣
║ 1 ║ Purina ║ Chicken ║ Dog ║ Small ║ Adult ║ Chicken ║ 18.99 ║
╠═════════╬════════════╬═════════╬═════════════╬════════════╬═══════════╬═════════════╬═══════╣
║ 1 ║ Purina ║ Chicken ║ Dog ║ Small ║ Adult ║ Salt ║ 18.99 ║
╠═════════╬════════════╬═════════╬═════════════╬════════════╬═══════════╬═════════════╬═══════╣
║ 2 ║ BlueWilder ║ Chicken ║ Dog ║ Small ║ Adult ║ Chicken ║ 18.99 ║
╠═════════╬════════════╬═════════╬═════════════╬════════════╬═══════════╬═════════════╬═══════╣
║ 2 ║ BlueWilder ║ Chicken ║ Dog ║ Small ║ Adult ║ Salt ║ 18.99 ║
╚═════════╩════════════╩═════════╩═════════════╩════════════╩═══════════╩═════════════╩═══════╝
There is a repeating group now because of the Ingredients column. To fix this, I created two separate tables; An ingredients table, and an associative table that connects the ingredients table and food table together:
╔═══════════════╦════════════╗
║ Ingredient ID ║ Ingredient ║
╠═══════════════╬════════════╣
║ 1 ║ Chicken ║
╠═══════════════╬════════════╣
║ 2 ║ Salt ║
╚═══════════════╩════════════╝
╔═════════╦═══════════════╗
║ Food ID ║ Ingredient ID ║
╠═════════╬═══════════════╣
║ 1 ║ 1 ║
╠═════════╬═══════════════╣
║ 1 ║ 2 ║
╠═════════╬═══════════════╣
║ 2 ║ 1 ║
╠═════════╬═══════════════╣
║ 2 ║ 2 ║
╚═════════╩═══════════════╝
Now, I can remove the Ingredients column from the food table:
╔═════════╦════════════╦═════════╦═════════════╦════════════╦═══════════╦═══════╗
║ Food ID ║ Brand ║ Flavor ║ Animal Type ║ Breed Size ║ Age Group ║ Price ║
╠═════════╬════════════╬═════════╬═════════════╬════════════╬═══════════╬═══════╣
║ 1 ║ Purina ║ Chicken ║ Dog ║ Small ║ Adult ║ 18.99 ║
╠═════════╬════════════╬═════════╬═════════════╬════════════╬═══════════╬═══════╣
║ 2 ║ BlueWilder ║ Chicken ║ Dog ║ Small ║ Adult ║ 18.99 ║
╚═════════╩════════════╩═════════╩═════════════╩════════════╩═══════════╩═══════╝
At this point, I am unsure of how to proceed.
My line of thinking is this: If any of the non-primary key columns change its value, the Food ID must be different. For example, the brand, flavor, breed size, age group, ingredients, and price can all be the same. But if the animal type is a dog, and then changes to a cat, it must be a different record. This applies to all the non-primary key columns. Following this thinking, all the non-primary key columns ARE fully dependent on the primary key, and there are no transitive dependencies.
Is my line of thinking correct? Is 2NF and 3NF, by the definitions I listed above, already satisfied?