SQL Server · Performance & Design

Normalization

Normalization is the process of organising tables so each fact is stored once. It prevents the update, insert and delete anomalies that plague spreadsheet-style designs.

Advanced 5 min Lesson 28 of 31Examples run on SQL Server 2022 and Azure SQL Database.
Before you start:Primary and Foreign Keys
0/31 in SQL Server
On this page · 5 min · Advanced

In simple words#

Instead of writing a class teacher’s phone number on every student’s row, keep it once in a Teachers register. Normalisation removes repeated data so it can’t get out of sync.

Normalisation
Organise tables to reduce duplication.
1NF · 2NF · 3NF
Atomic values · depend on whole key · nothing but the key.
Denormalise
Deliberately duplicate for read speed.

Learning objectives#

  • Explain 1NF, 2NF and 3NF
  • Spot redundancy and anomalies
  • Split a flat table into related tables
  • Know when to denormalize

Explanation#

First Normal Form (1NF): each column holds a single value and there are no repeating groups such as Phone1, Phone2, Phone3.

Second Normal Form (2NF): in a table with a composite key, every non-key column depends on the whole key — not just part of it.

Third Normal Form (3NF): non-key columns depend only on the key, not on other non-key columns (City should not determine State inside Orders).

Denormalization deliberately duplicates data for read speed — common in reporting databases — but adds the work of keeping copies in sync.

Code example: From a flat sheet to ShopDB#

SQLFrom a flat sheet to ShopDB Illustrative
-- ✗ Flat design: customer and product details repeated on every line
-- OrderLines(OrderId, OrderDate, CustomerName, CustomerCity, ProductName, Category, Price, Qty)


-- ✓ Normalized (3NF)
CREATE TABLE Customers (CustomerId INT PRIMARY KEY, Name NVARCHAR(60), City NVARCHAR(40));
CREATE TABLE Products  (ProductId INT PRIMARY KEY, Name NVARCHAR(60), Category NVARCHAR(30), Price DECIMAL(10,2));
CREATE TABLE Orders    (OrderId INT PRIMARY KEY, CustomerId INT REFERENCES Customers, OrderDate DATE);
CREATE TABLE OrderItems(OrderId INT REFERENCES Orders, ProductId INT REFERENCES Products,
                        Qty INT, UnitPrice DECIMAL(10,2), PRIMARY KEY (OrderId, ProductId));
Expected output
Each customer, product and order is stored once. Changing a customer’s city is now a single-row update instead of editing every past order line.

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. In the flat design, Asha’s city appears on every line she ever ordered — an update anomaly waiting to happen.
  2. Customers and Products move to their own tables (removing repeated groups and partial dependencies).
  3. OrderItems keeps only facts about the order line: quantity and the price at the time of sale.
  4. UnitPrice is intentionally stored on the line because the product price may change later — that is history, not redundancy.

Real-world use case#

Transactional systems (orders, banking, HR) are normalized for correctness; analytics warehouses denormalize into star schemas for fast reporting.

Common mistakes#

Comma-separated lists in a column

Storing 'React,Angular,Vue' in one column breaks 1NF and makes searching and joining painful. Use a related table.

Over-normalizing

Splitting every attribute into its own table makes simple queries need many joins. Stop at 3NF unless you have a reason.

Best practices#

  • Aim for 3NF in transactional databases
  • Store historical values (like UnitPrice) where they belong
  • Denormalize only with a measured reason
  • Use views to present convenient, joined shapes

Remember this#

Store each fact once.

1NF atomic · 2NF whole key · 3NF nothing but the key.

Denormalise only for proven read speed needs.

Practice exercise#

Your task: A Students table has columns Course1, Course2, Course3. Which normal form does it break and how would you fix it?

Show solution
Text Illustrative
It breaks 1NF (repeating group). Create Enrollments(StudentId, CourseId) with one row per student-course pair.

Mini quiz#

Normalization quizMultiple choice Question 1 of 1

Columns Phone1, Phone2, Phone3 violate which normal form?

Score so far: 0/0

Want more? Practise all SQL Server MCQs · SQL Server interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.