Modules/Database/ Normalization Lab

Normalization: 1NF, 2NF, 3NF

One messy table, split one rule at a time. Each split removes a specific kind of redundancy — and a specific kind of bug.

Stage

raw 1NF 2NF 3NF

The raw table: one row per order, a comma-separated list of products.

The Table(s) At This Stage

—

Redundancy

Redundant Cells
4
Tables1

 

Overview

Suppose a table repeats a department's address on every employee row. If the address changes, every row must be updated; missing one creates inconsistent data. The design also makes it awkward to record a department before it has employees. These are update, deletion, and insertion anomalies.

Why split a table

Normalization uses relational structure and keys to reduce that duplication. It is not a requirement to split every table as far as possible: the goal is a clear model whose updates preserve the intended facts.

The practical meaning of common normal forms

First normal form (1NF) is commonly taught as keeping each column value atomic for the operations the database must perform, rather than storing repeating lists in one field.

Second normal form (2NF) requires 1NF and that non-key attributes depend on the whole candidate key, not just part of a composite key. It matters when a relation has a multi-column key.

Third normal form (3NF) removes transitive dependencies: a non-key attribute should describe the key, the whole key, and nothing but the key. For example, store department_name with a department record rather than repeating it in every employee row.

These summaries are useful design tests, not a substitute for formal functional-dependency analysis. Start by identifying candidate keys and what each row represents.

A small split

Model employees(employee_id, department_id, name) and departments(department_id, name, address). The department's address now has one authoritative row, and department_id links employees to it. A foreign-key constraint can enforce that reference; see primary and foreign keys.

When denormalizing can help

For a measured read bottleneck, systems sometimes duplicate or precompute data to reduce joins. Treat the duplicate as a consistency responsibility: define which value is authoritative, how copies are updated, and how they are repaired. Do not denormalize speculatively. See star schema for an analytics-oriented design.

Find the dependency before splitting

Before separating columns, state the functional dependency: for example, department_id determines department_name and department_address. If those department attributes are stored in each employee row, they depend on department_id rather than employee_id, which creates duplicated facts. Moving them to a department table gives the dependency one home. Do not split columns merely because they look related; identify the key and the business fact each row represents. Constraints then protect the relationship after the split.

Further reading

Predict, then reveal

About to run: press Normalize →. Before it does — what happens to the readout?

Committing to an answer first is the point — the reveal runs the experiment on the visualisation above and reads the real value back, so nothing here is scripted.

Recall check

0 of 3

Say the answer out loud before you reveal it — recalling it is what makes it stick, and rereading it is not.

  1. What does this module say about “Start here”?

  2. What does this module say about “Why split a table”?

  3. What does this module say about “The practical meaning of common normal forms”?

Cheat sheet

Normalization (1NF, 2NF, 3NF) in SQL

One table with a multi-valued column, split step by step into 1NF, 2NF and 3NF. Watch the redundant cells that cause update anomalies drop to zero.

DATABASE · vizlearn.in/database/normalization_in_sql.html

Further reading

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.