Database Normalisation: 1NF, 2NF and 3NF Explained
Normalisation is the process of organising columns so that each fact is stored exactly once. The forms are not arbitrary rules — each removes a specific way that duplicated data goes wrong. Follow one table through the three forms and they stop needing memorisation.
The problem: update anomalies
| student_id | student_name | course_ids | dept | dept_head |
|---|---|---|---|---|
| 1 | Aditi | CS101, CS102 | CSE | Dr. Rao |
| 2 | Karan | CS101 | CSE | Dr. Rao |
| 3 | Meera | EC201 | ECE | Dr. Iyer |
- Update anomaly. The CSE head changes and you must update every CSE row; miss one and the database now holds two answers.
- Insert anomaly. A new department cannot be recorded until some student enrols in it.
- Delete anomaly. Removing the last ECE student deletes the only record that Dr. Iyer exists.
First normal form — atomic values
1NF: every cell holds a single value, and there are no repeating groups. course_ids holds a comma-separated list, which breaks it — you cannot join on it, index it usefully, or enforce a foreign key against it.
The fix is one row per student-course pair. The table gets longer and immediately more useful.
Second normal form — no partial dependency
2NF: in 1NF, and every non-key column depends on the whole composite key. With the key now (student_id, course_id), student_name depends on student_id alone — a partial dependency, which is why the name repeats on every row for that student.
Split into students(student_id, student_name, dept, dept_head) and enrolments(student_id, course_id).
Third normal form — no transitive dependency
3NF: in 2NF, and no non-key column depends on another non-key column. In students, dept_head depends on dept, which depends on student_id — a transitive dependency, and the original update anomaly still alive.
CREATE TABLE departments (
dept_code VARCHAR(8) PRIMARY KEY,
dept_head VARCHAR(80) NOT NULL
);
CREATE TABLE students (
student_id INT PRIMARY KEY,
student_name VARCHAR(80) NOT NULL,
dept_code VARCHAR(8) NOT NULL REFERENCES departments(dept_code)
);
CREATE TABLE enrolments (
student_id INT REFERENCES students(student_id),
course_id VARCHAR(8),
PRIMARY KEY (student_id, course_id)
);
Each fact now lives in exactly one row. Changing the CSE head is a single-row update, a department can exist with no students, and deleting a student cannot erase a department.
When to stop, and when to reverse
3NF is the practical target for transactional systems. BCNF, 4NF and 5NF exist and are worth naming, but they address edge cases you will rarely meet in an application schema.
Denormalisation is a deliberate trade
Read-heavy systems sometimes duplicate a column to avoid a join on a hot path — analytics tables, caches, materialised views. That is a considered decision with a plan for keeping the copies consistent, not a shortcut. Saying this unprompted is a strong signal in an interview.
| Form | Rule | Removes |
|---|---|---|
| 1NF | Atomic values, no repeating groups | Lists inside cells |
| 2NF | No partial dependency on a composite key | Duplicated per-entity attributes |
| 3NF | No transitive dependency between non-key columns | The remaining update anomalies |
| BCNF | Every determinant is a candidate key | Rare overlapping-key anomalies |
Key takeaways
- Normalisation exists to remove insert, update and delete anomalies — not for tidiness.
- 1NF: atomic values. 2NF: no partial dependency. 3NF: no transitive dependency.
- 3NF is the practical target for transactional schemas.
- Denormalise deliberately for read performance, with a plan for consistency.
Frequently asked questions
What is normalisation in DBMS?
Organising a database so each fact is stored once, by splitting tables to remove dependencies that cause insert, update and delete anomalies.
What is the difference between 2NF and 3NF?
2NF removes partial dependencies, where a non-key column depends on only part of a composite key. 3NF removes transitive dependencies, where a non-key column depends on another non-key column.
Is 3NF always the right target?
For transactional systems, usually yes. Read-heavy and analytical systems often denormalise deliberately to avoid expensive joins, accepting duplicated data in exchange for query speed.
Test yourself on DBMS & SQL
Reading is not recall. Take a timed quiz on this topic solo, or share a room code and battle friends on it.
⚡ Start the DBMS & SQL quiz