Mastering Database Normalization: From Chaotic Kitchens to Tidy Kitchens

When ever I went to kitchen trying to cook a simple meal. But I keep on messing all thing and make it hard for my mother by spreading ingredient spread across the counter.

Which make hard for her to cook in that kitchen.

The flour is kept next onions and spices are mixed with the vegetables and our cutting board has everything tomatoes, garlic and a slice of bread. It’s a chaotic kitchen! 🤦‍♂️

Where she is not been able to find a single thing easily. Here She can’t cook easily

This is what unnormalized database looks like where Data is mixed up, have duplicate entry and it’s hard to manage. Every time when we need an ingredient, you have to go through the mess to find it.

No one want’s to work in such a kitchen and with such a unorganized data?

Now if we organize that kitchen spices neatly arranged, vegetables in their own baskets and utensils organized. Here we know exactly where to find everything we need. That what a database normalization where our data is clean, well-structured and easy to find it called neat kitchen.

What is Database Normalization?

Normalization is a process of organizing our chaotic kitchen i.e. unnormalized data to tidy kitchen i.e. normalized data.

Normalization is the process of organizing data to minimize redundancy and dependency.

Who want there kitchen or database to get messy! 😄

Why Normalize? Or... Why Clean Your Kitchen?

Let’s Imagine kitchen as our database.

If knives, plates, onions, and spices are all stacked in one drawer. Every time when we need something, we have to dig through the mess.

That’s how a non-normalized database feels it’s an mess, inefficient and prone to errors.

Normalization helps us:

  • Avoid repeating the same ingredients (like storing the same garlic in 5 different drawers!)

  • Prevent updating the same info in multiple places (like checking if the salt is in 3 places before cooking)

  • Insert data easily without strange issues (like mixing chutney in your soup)

  • Delete data without accidentally throwing away the useful stuff (like tossing away a pan you still need)

Functional Dependencies = Relationships in Kitchens 😂

When we use ingredients in the kitchen. If we want to make a sandwich, we know that bread → butter. It's a functional relationship.(

Similarly, in databases:

OrderID → CustomerName

If we know the OrderID, we can easily find the CustomerName.

These dependencies help us identify the relationships between tables and normalize our data structure. Just like understanding that bread → butter is the secret to a perfect sandwich!

Normal Forms – The Recipe for a Perfect Kitchen

1NF (First Normal Form) - Keep Your Ingredients Separate

In a tidy kitchen, each ingredient has its own container no mixing of flour with onions. Similarly, in 1NF, each database cell should hold only one value. No lists, no multiple items in one cell.

Bad Kitchen (Chaotic):

| Recipe   | Ingredients             |
|----------|-------------------------|
| Pasta    | Noodles, Sauce, Cheese  |

Good Kitchen (Tidy):

| Recipe   | Ingredient    |
|----------|---------------|
| Pasta    | Noodles       |
| Pasta    | Sauce         |
| Pasta    | Cheese        |

Now you can easily find your noodles, sauce, or cheese without any mixing!

2NF (Second Normal Form) - No Half-Cooked Recipes

A well-organized kitchen ensures no partial ingredients are used out of context. In 2NF, we make sure there’s no partial dependency on composite keys. Ingredients should depend on the full recipe, not just part of it.

Imagine you're ordering pizza. Your order has:

1. Order ID
2. Pizza ID
3. Pizza Name

If your system uses Order ID + Pizza ID together as a key (to identify each pizza in each order)...
But Pizza Name depends only on Pizza ID, not the whole combo...
👉 That’s called partial dependency.

Scenario:

| RecipeID | IngredientID | RecipeName |

Here, RecipeName depends on RecipeID, not the entire composite key. This is not 2NF!

 composite key: A key made of two or more columns that together uniquely identify a row in a table.

Fix:

-- Recipe Table
CREATE TABLE Recipe (
  RecipeID INT PRIMARY KEY,
  RecipeName VARCHAR(100)
);

-- Ingredient Table
CREATE TABLE Ingredient (
  RecipeID INT,
  IngredientID INT,
  IngredientName VARCHAR(100),
  PRIMARY KEY(RecipeID, IngredientID)
);

3NF (Third Normal Form) - No Gossip in the Kitchen

In a well-kept kitchen, the ingredients don’t gossip with each other. Similarly, in 3NF, no non-key attribute should depend on another non-key attribute. If the pan depends on the cook’s name, then we have a problem!

Bad Kitchen (Gossipy Ingredients):

| RecipeID | CookID | CookName |

Here, CookName depends on CookID, not RecipeID. This is not 3NF.

Fix:

CREATE TABLE Cook (
  CookID INT PRIMARY KEY,
  CookName VARCHAR(100)
);

BCNF (Boyce-Codd Normal Form) – The Expert Chef’s Rule

Every kitchen ingredient should depend on the recipe!

In BCNF, every determinant must be a candidate key. No exceptions!

Case Study: Restaurant Database

Let’s take a look at a restaurant’s backend. Imagine we are creating an Indian food delivery system. The initial kitchen (database) is chaotic—ingredients are mixed, and you’re bound to make mistakes.

Messy Kitchen (Initial Table):

| OrderID | CustomerName | DishName  | DishPrice | CustomerEmail |

Problem:

  • Customer info is repeated for every order

  • Dish prices are repeated every time a dish is ordered

Time to Tidy Up! 🛠️

-- Customer Table
CREATE TABLE Customer (
  CustomerID INT PRIMARY KEY,
  Name VARCHAR(100),
  Email VARCHAR(100)
);

-- Dish Table
CREATE TABLE Dish (
  DishID INT PRIMARY KEY,
  Name VARCHAR(100),
  Price DECIMAL(10,2)
);

-- Orders Table
CREATE TABLE Orders (
  OrderID INT PRIMARY KEY,
  CustomerID INT,
  OrderDate DATE
);

-- OrderDetails Table
CREATE TABLE OrderDetails (
  OrderID INT,
  DishID INT,
  Quantity INT
);

Now, each part of your kitchen is organized, and you can easily find all the ingredients you need. Your database is like a well-organized kitchen, ready to serve tasty meals (queries) without chaos.

Normalization vs Denormalization — Clean Kitchen vs Speedy Cooking

Normalized Kitchen: Looks neat and easy to maintain, but you might have to walk a little to get all your ingredients (joins).
Denormalized Kitchen: Faster to grab everything from one pot (fewer joins), but you might mix the wrong spices together!

Normalized KitchenDenormalized Kitchen
Clean & organizedFaster cooking
More ingredients to walk toLess clean, more redundant
Great for detailed mealsGreat for quick, less complex dishes

Here are some Mistake we did while normalizing!

  • Not finding the right key for your ingredients

  • Mixing partial and transitive dependencies (spices mixed with main dishes)

  • Over-normalizing (too many trips to different shelves!)

  • Forgetting to label your ingredients (indexes, please!)

Just like I wouldn’t cook in a messy kitchen, just like that we should never store our data in a disorganized database. Normalize with care. Understand each form deeply and apply it only when needed. Don’t overdo it or we end up with too many ingredients to handle!

Happy cooking (and coding)! 🍲👨‍🍳

1
Subscribe to my newsletter

Read articles from SANKALP HARITASH directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SANKALP HARITASH
SANKALP HARITASH

Hey 👋🏻, I am , a Software Engineer from India. I am interested in, write about, and develop (open source) software solutions for and with JavaScript, ReactJs. 📬 Get in touch Twitter: https://x.com/SankalpHaritash Blog: https://sankalp-haritash.hashnode.dev/ LinkedIn: https://www.linkedin.com/in/sankalp-haritash/ GitHub: https://github.com/SankalpHaritash21 📧 Sign up for my newsletter: https://sankalp-haritash.hashnode.dev/newsletter