← Back to list

Database Normalization Explained with Real Examples (Beginner Friendly)

How to Design Clean Databases Without Chaos

Yathu B. · 2026-06-01 18:59 · 0 claps · 9.9 min read
#database-normalization #database #normal-form
Open on Medium ↗

Database Normalization Explained with Real Examples (Beginner Friendly)

How to Design Clean Databases Without Chaos

When beginners start learning databases, they usually focus on:

  • Tables
  • SQL queries
  • Storing data

But in real-world systems, there is a hidden problem most people don’t notice at first:

Badly designed databases become messy very quickly.

Data gets duplicated, inconsistent, and hard to maintain.

This is where Database Normalization comes in.

Normalization is one of the most important database design concepts used in real software systems, such as:

  • Banking applications
  • E-commerce platforms
  • Social media systems
  • School management systems

Let’s understand it step by step in a simple, visual way.

The Problem: Data Duplication

Imagine we store order data like this:

+----------+----------------+-----------------------+------------+
| OrderID  |  CustomerName  |  CustomerPhoneNumber  |  Product   |
+----------+----------------+-----------------------+------------+
|   101    |     Alice      |      0771234567       |  Laptop    | 
|   102    |     Alice      |      0771234567       |  Mouse     |
|   103    |     Alice      |      0771234567       |  Keyboard  |
+----------+----------------+-----------------------+------------+

Alice’s information is repeated in every row.

The Hidden Problem

Now imagine Alice changes her phone number:

We must update:

  • Row 1
  • Row 2
  • Row 3

If we miss even one row:

Data becomes inconsistent

Some records show the old phone number, others show the new one.

This is called a Data Anomaly.

Types of Data Anomalies

1. Update Anomaly

Updating one piece of data requires multiple changes.

2. Insert Anomaly

You cannot add a customer unless they place an order.

3. Delete Anomaly

If you delete an order, you might accidentally lose customer information.

What is Normalization?

Normalization is the process of organizing database tables to:

  • Reduce duplication
  • Improve consistency
  • Avoid anomalies
  • Make data easier to maintain

In simple terms:

“Store each piece of data only once.”

Normalized Design (Fixing the Problem)

Instead of storing everything in one table, we split the data logically.

Step 1: Customers Table

+-------------+----------------+-----------------------+
| CustomerID  |  CustomerName  |  CustomerPhoneNumber  |
+-------------+----------------+-----------------------+
|      1      |     Alice      |      0771234567       | 
+-------------+----------------+-----------------------+

Now Alice exists only once.

Step 2: Orders Table

+----------+--------------+------------+
| OrderID  |  CustomerID  |  Product   |
+----------+--------------+------------+
|   101    |      1       |  Laptop    | 
|   102    |      1       |  Mouse     |
|   103    |      1       |  Keyboard  |
+----------+--------------+------------+

Instead of repeating Alice’s details, we use CustomerID as a reference.

Before normalization:

Alice → repeated in every row

After normalization:

Customers Table → stores Alice once
Orders Table → references Alice using ID

Why Normalization Matters

Normalization is not just a theory.

It directly improves real systems.

It prevents:

  • Duplicate data
  • Wrong updates
  • Data inconsistencies
  • Storage waste

Real-Life Example: E-Commerce System

Without normalization:

  • Customer details are repeated in every order

With normalization:

  • Customer stored once
  • Orders reference customer ID
  • Products stored separately

This is how Amazon-like systems are designed.

Normal Forms

You may hear:

  • 1NF
  • 2NF
  • 3NF

1NF, 2NF, and 3NF

1NF, 2NF, and 3NF

Don’t worry — these are just levels of normalization.

Let’s understand them simply.

1NF (First Normal Form)

1NF is the first step toward a clean database design.

Each column should contain only a single value.

One cell = One value

A database table should not store lists, arrays, comma-separated values, or multiple pieces of information inside a single column.

Bad Example

Imagine a school database:

+--------------+-------------+----------------------+
|  StudentID   |   Student   |   Subjects           |
+--------------+-------------+----------------------+
|      1       |    John     |  Math, Physics       |
|      2       |    Mary     |  Chemistry, Biology  |
+--------------+-------------+----------------------+

At first glance, this looks convenient.

But it creates several problems.

Problems with This Design

Problem 1: Difficult Searching

Suppose we want to find all students studying Physics.

The database must search inside text values like:

Math, Physics

instead of simply matching a single value.

Problem 2: Difficult Updates

Suppose John drops Physics.

We must edit the text:

Math, Physics

and change it to:

Math

This becomes messy and error-prone.

Problem 3: Difficult Relationships

What if later we want:

  • Subject codes
  • Subject lecturers
  • Subject credits

The comma-separated list becomes impossible to manage properly.

1NF Fix

Store one subject per row.

+--------------+-------------+-------------+
|  StudentID   |   Student   |   Subject   |
+--------------+-------------+-------------+
|      1       |    John     |  Math       |
|      1       |    John     |  Physics    |
|      2       |    Mary     |  Chemistry  |
|      2       |    Mary     |  Biology    |
+--------------+-------------+-------------+

Now:

  • Each cell contains one value
  • Searching becomes easier
  • Updating becomes easier
  • Relationships become possible

1NF removes repeating groups and multi-value columns.

Instead of storing:

Math, Physics

Store:

Math
Physics

as separate rows.

2NF (Second Normal Form)

Once a table satisfies 1NF, the next step is 2NF.

Remove partial dependency.

Every non-key column should depend on the entire primary key, not just part of it.

This rule mainly matters when a table uses a composite primary key (a primary key made from multiple columns).

Problem

Imagine a student enrollment system.

A student can enroll in many courses.

A course can have many students.

So we create this table:

+-------------+------------+---------------+--------------------+
|  StudentID  |  CourseID  |  StudentName  |     CourseName     |
+-------------+------------+---------------+--------------------+
|      1      |    C101    |      John     |  Database Systems  |
|      1      |    C102    |      John     |  Programming       |
|      2      |    C101    |      Mary     |  Database Systems  |
+-------------+------------+---------------+--------------------+

Assume the primary key is:

(StudentID, CourseID)

because that combination uniquely identifies each enrollment.

What’s Wrong Here?

Look carefully.

StudentName depends only on StudentID

StudentID → StudentName

For example:

1 → John
2 → Mary

CourseID is irrelevant.

CourseName depends only on CourseID

CourseID → CourseName

For example:

C101 → Database Systems
C102 → Programming

StudentID is irrelevant.

Why Is This a Problem?

Student names are repeated:

+-------------+---------------+
|  StudentID  |  StudentName  |
+-------------+---------------+
|      1      |     John      |
|      1      |     John      |
+-------------+---------------+

Course names are repeated:

+-----------+--------------------+
|  CourseID |    CourseName      |
+-----------+--------------------+
|    C101   |  Database Systems  |
|    C101   |  Database Systems  |
+-----------+--------------------+

This creates duplication.

2NF Fix

Separate the data into logical tables.

Students Table

+-------------+---------------+
|  StudentID  |  StudentName  |
+-------------+---------------+
|      1      |     John      |
|      2      |     Mary      |
+-------------+---------------+

Courses Table

+-----------+--------------------+
|  CourseID |    CourseName      |
+-----------+--------------------+
|    C101   |  Database Systems  |
|    C102   |  Programming       |
+-----------+--------------------+

Enrollments Table

+-------------+---------------+
|  StudentID  |  CourseID     |
+-------------+---------------+
|      1      |     C101      |
|      1      |     C102      |
|      2      |     C101      |
+-------------+---------------+

Now:

  • Student information is stored once
  • Course information is stored once
  • No unnecessary duplication
  • Every non-key attribute depends on the whole key

If part of a composite key determines a column, move that column into its own table.

3NF (Third Normal Form)

After reaching 2NF, we move to 3NF.

Remove transitive (indirect) dependencies.

A non-key column should not depend on another non-key column.

Everything should depend directly on the primary key.

Problem

Consider this employee table:

+--------------+----------------+----------------+------------------+
|  EmployeeID  |  EmployeeName  |  DepartmentID  |  DepartmentName  |
+--------------+----------------+----------------+------------------+
|     1        |      Alice     |      D01       |        HR        |
|     2        |      Bob       |      D02       |      Finance     |
|     3        |      Charlie   |      D01       |        HR        |
+--------------+----------------+----------------+------------------+

Primary key:

EmployeeID

Dependency Analysis

EmployeeID determines DepartmentID:

EmployeeID → DepartmentID

And DepartmentID determines DepartmentName:

DepartmentID → DepartmentName

Therefore:

EmployeeID → DepartmentID → DepartmentName

DepartmentName depends indirectly on EmployeeID.

This is called a:

Transitive Dependency

Why Is This a Problem?

Suppose HR changes its name to:

Human Resources

We must update every employee in that department.

+--------------+-------------------+
|  EmployeeID  |  DepartmentName   |
+--------------+-------------------+
|     1        |  Human Resources  | 
|     3        |  Human Resources  |
+--------------+-------------------+

If one row is missed:

+--------------+-------------------+
|  EmployeeID  |  DepartmentName   |
+--------------+-------------------+
|     1        |  Human Resources  |
|     3        |       HR          |
+--------------+-------------------+

The database becomes inconsistent.

3NF Fix

Separate department information.

Employees Table

+--------------+----------------+----------------+
|  EmployeeID  |  EmployeeName  |  DepartmentID  |  
+--------------+----------------+----------------+
|     1        |      Alice     |      D01       |
|     2        |      Bob       |      D02       |
|     3        |      Charlie   |      D01       | 
+--------------+----------------+----------------+

Departments Table

+----------------+-------------------+
|  DepartmentID  |  DepartmentName   |
+----------------+-------------------+
|      D01       |  Human Resources  | 
|      D02       |      Finance      |
+----------------+-------------------+

Now:

  • Department names are stored once
  • Easier updates
  • No indirect dependency
  • Better consistency

If a non-key column describes another non-key column, move that information into a separate table.

Simple Summary of Normal Forms

+-------+--------------------------------+------------------------------------------------------+
| Level |      Main Goal                 |      Problem Fixed                                   |  
+-------+--------------------------------+------------------------------------------------------+
|  1NF  |  Store atomic values           |  Multiple values in one column                       |
|  2NF  |  Remove partial dependency     |  Data depending on only part of a composite key      |
|  3NF  |  Remove transitive dependency  |  Non-key columns depending on other non-key columns  | 
+-------+--------------------------------+------------------------------------------------------+

Don’t memorize the rules. Just understand why the problems arise and how to fix them.

What matters is:

“We are breaking big messy tables into clean smaller ones.”

You will learn more about Other Normal Forms below.

How Normalization Feels in Real Systems

Let’s take a simple system:

Student Management System

Bad Design:

+-----------+----------+-------------+
|  Student  |  Course  |  Lecturer   |
+-----------+----------+-------------+
|   John    |   Math   |  Mr. Smith  |
|   Mary    |   Math   |  Mr. Smith  |
|   David   |   Math   |  Mr. Smith  |
+-----------+----------+-------------+

Problems:

  • Lecturer's name repeated
  • Hard to update
  • High duplication

Good Design (Normalized)

Students Table

+-------------+---------------+
|  StudentID  |  StudentName  |
+-------------+---------------+
|      1      |     John      |
|      2      |     Mary      |
|      3     |      David     |
+-------------+---------------+

Courses Table

+-----------+--------------+
|  CourseID |  CourseName  |
+-----------+--------------+
|    10     |     Math     |
+-----------+--------------+

Lecturers Table

+-------------+----------------+
|  LecturerID |  LecturerName  |
+-------------+----------------+
|    100      |     Mr.Smith   |
+-------------+----------------+

Enrollments Table

+-------------+-------------+
|  StudentID  |  CourseID   |
+-------------+-------------+
|      1      |     10      |
|      1      |     10      |
|      2      |     10      |
+-------------+-------------+

Now everything is:

  • Clean
  • Reusable
  • Scalable
  • Consistent

The Big Idea Behind Normalization

Normalization is not about making tables “complicated”.

It is about making them:

Predictable, Clean, and Scalable

When NOT to Over-Normalize

In real-world systems, sometimes:

  • Too many JOINs slow performances
  • Reading becomes complex

So developers sometimes:

Intentionally denormalize (slightly duplicate data)

This is where theories and usage both come into play.

You might have heard about BCNF, 4NF, and 5NF.

Yes, they do exist. But here’s the important truth:

They are real in theory, but rarely used in everyday software development.

You can skip them for now if you are just a beginner.

BCNF (Boyce–Codd Normal Form)

It is a stronger version of 3NF.

It fixes some special cases where 3NF still allows subtle redundancy.

Why BCNF exists

Even after 3NF, you can still get:

  • Hidden redundancy
  • Weird dependency issues

BCNF says:

“Every determinant must be a candidate key.”

i.e.

A table is in BCNF if:

Every “rule that decides another column” must come from a unique identifier.

Example (intuitive)

Problem table:

+-----------+----------+-------------+
|  Student  |  Course  |  Teacher    |
+-----------+----------+-------------+
|   Alice   |   Math   |  Mr. Smith  |
|   Bob     |   Math   |  Mr. Smith  |
+-----------+----------+-------------+

Assume:

  • One teacher teaches one course
  • Course → Teacher (important rule)

So: Course determines Teacher

Problem

We are repeating:

  • Mr. Smith again and again for Math

Even though:

Course already defines Teacher

BCNF Fix

Split into:

Courses

+-----------+------------+
|  Course   |  Teacher   |
+-----------+------------+
|   Math    |  Mr.Smith  |
+-----------+------------+

Enrollments

+-----------+----------+
|  Student  |  Course  |
+-----------+----------+
|   Alice   |   Math   | 
|   Bob     |   Math   |
+-----------+----------+

Now:

  • No redundancy
  • No hidden dependency issues

4NF and 5NF

They exist in advanced theoretical database design.

4NF (Fourth Normal Form)

It solves Multi-valued dependency.

One entity has multiple independent lists.

Example:

+-----------+---------+------------+
|  Student  |  Hobby  |  Language  |
+-----------+---------+------------+
|  Alice    |  Music  |   English  | 
|  Alice    |  Music  |   French   |
|  Alice    |  Sports |   English  | 
|  Alice    |  Sports |   French   |
+-----------+---------+------------+

Problem

Hobbies and languages are independent, but they are mixed.

This creates:

  • Unnecessary combinations
  • Data explosion

4NF solution

Split into two tables:

Student-Hobbies

+-----------+---------+
|  Student  |  Hobby  | 
+-----------+---------+
|  Alice    |  Music  | 
|  Alice    |  Sports |
+-----------+---------+

Student-Languages

+-----------+-----------+
|  Student  |  Language | 
+-----------+-----------+
|  Alice    |  English  | 
|  Alice    |  French   |
+-----------+-----------+

Simply 4NF says:

“Don’t mix independent multi-value data in one table.”

5NF (Fifth Normal Form)

It solves Complex join dependency problems.

This is very rare in real systems.

Sometimes:

A table can only be correctly reconstructed by breaking it into 3 or more tables.

Example

Imagine:

  • Supplier
  • Product
  • Warehouse

A relationship depends on all three together.

So, instead of one table, we split it into multiple tables and reconstruct using joins.

Simply:

“Break tables until they can be perfectly rebuilt using joins.”

IMPORTANT REAL-WORLD TRUTH

Here is what the industry actually does:

+---------------+-------------------------+
| Normal Forms  |  Used in real systems?  |
+---------------+-------------------------+
|     1NF       |     Always              |
|     2NF       |     Very common         |
|     3NF       |     Standard design     |
|     BCNF      |     Sometimes           |
|     4NF       |     Rare                |
|     5NF       |     Extremely rare      |
+---------------+-------------------------+

Why are higher normal forms rarely used

Because in real systems:

  • Performance matters more than perfect theory
  • Too many joins = slow queries
  • Complexity increases

So engineers often:

Normalize up to 3NF (or BCNF), then optimize.

Simply:

  • BCNF → Fixes edge cases of 3NF
  • 4NF → Fixes multi-value duplication problems
  • 5NF → Theoretical perfect decomposition using joins

One-line intuition

Normalization beyond 3NF is about perfection in theory, not daily engineering practice.

Final Thoughts

Database Normalization is one of the core skills of backend engineering.

It helps you:

  • Design clean databases
  • Avoid duplication
  • Prevent data errors
  • Build scalable systems

While many real-world systems intentionally balance normalization with performance considerations, understanding the normal forms gives you the knowledge needed to design robust databases and make informed architectural decisions.

Now that you understand the normalization, next you can learn more about:

  • Database Indexing and How Databases Become Fast

Where you can understand:

  • Why searches are slow
  • How indexes fix performance
  • How Google/Amazon systems stay fast
  • Real indexing examples

Thanks for reading! 🙂

If this article helped you understand normalization, from 1NF to 5NF and BCNF, through real-world examples, feel free to share your thoughts or questions in the comments. 👍

A clap or share would be greatly appreciated, and follow for more beginner-friendly articles on databases, SQL, software engineering, and system design.

Happy learning and happy database designing! 🚀


메타데이터
post_id
685f3d261aea
slug
database-normalization-explained-with-real-examples-beginner-friendly-685f3d261aea
url
https://medium.com/@Yathu_B/database-normalization-explained-with-real-examples-beginner-friendly-685f3d261aea
canonical_url
https://medium.com/@Yathu_B/database-normalization-explained-with-real-examples-beginner-friendly-685f3d261aea
author_url
https://medium.com/@Yathu_B
status
ok
fetched_at
2026-06-12 18:14:10