Normalisation: 1NF to BCNF
Watch one badly-designed table split apart until no fact is stored twice.
Skip to the animationNormalisation is the process of splitting a relation until every fact is stored in exactly one place, so that no update can leave the database contradicting itself.
The problem, in one table
Here is the table the animation starts from. Each row is an enrolment, but it also carries the student's name and the course's name:
| sid | sname | cid | cname | grade |
|---|---|---|---|---|
| S1 | Asha | C1 | Databases | A |
| S1 | Asha | C2 | Networks | B |
| S2 | Ravi | C1 | Databases | A |
| S3 | Meera | C1 | Databases | C |
"Databases" appears three times and "Asha" twice. Every repetition is a chance for two copies to disagree, and that is the whole disease. The three symptoms are worth naming because exam questions ask for them by name:
- Update anomaly
- Renaming course C1 means changing three rows. Miss one and the database now claims C1 has two different names.
- Insertion anomaly
- You cannot record a new course until some student enrols in it, because
sidis part of the key and cannot be null. - Deletion anomaly
- Delete the last enrolment for a course and you lose the course's name too — a fact you never meant to throw away.
The vocabulary
- Functional dependency (X → Y)
- Knowing X pins down Y. If two rows agree on X they must agree on Y. This is a statement about the world being modelled, not about the rows that happen to be in the table today.
- Superkey and candidate key
- A superkey determines every attribute in the relation. A candidate key is a superkey with nothing spare in it — remove any attribute and it stops working.
- Prime attribute
- One that appears in some candidate key. The normal forms are mostly rules about how non-prime attributes are allowed to depend on prime ones.
- Partial dependency
- A non-prime attribute determined by only part of a composite key. Forbidden by 2NF, and the direct cause of the update, insert and delete anomalies.
- Transitive dependency
- Key → X → Y where X is not a key. Forbidden by 3NF: the fact really belongs in a table keyed by X.
- Lossless decomposition
- Splitting a relation so that re-joining it gives back exactly the original rows — no more, no fewer. Guaranteed when the shared attribute is a key of one of the two pieces.
The normal forms, as a ladder
| Form | Requires | Fixes |
|---|---|---|
| 1NF | Every value atomic — no lists, no repeating groups | Rows you cannot query |
| 2NF | 1NF, and no partial dependencies | Facts about part of a composite key |
| 3NF | 2NF, and no transitive dependencies | Facts about a non-key attribute |
| BCNF | Every determinant is a superkey | The cases 3NF still lets through |
Each form assumes the one before it. The single question that drives all of them: for every arrow X → Y in this relation, is X a key of it? If yes, you are in BCNF and finished.
Working the example
- 1Find the key. Neither
sidnorcidalone identifies a row, so the key is the pair(sid, cid). - 2List the dependencies:
sid → sname,cid → cname,(sid, cid) → grade. - 3Check 2NF.
sid → snameandcid → cnameeach depend on part of the key. Both are violations. - 4Split on each determinant:
Student(sid, sname)andCourse(cid, cname). - 5What is left is
Enrol(sid, cid, grade), whose only dependency starts at its own key. - 6Re-check: every determinant is now a superkey of its relation, so this is BCNF.
Notice that no dependency was destroyed. Each one simply moved into a relation where its determinant is the key — which is what makes it harmless rather than dangerous.
3NF vs BCNF, and when to stop
3NF allows one exception BCNF does not: a dependency X → Y is acceptable to 3NF if Y is a prime attribute, even when X is not a superkey. BCNF removes that loophole. The example here lands in both, so it does not distinguish them — but the trade-off is real: every relation has a lossless 3NF decomposition that preserves all dependencies, whereas BCNF is sometimes only reachable by giving dependency preservation up.
In practice designers normalise to BCNF and then sometimes denormalise deliberately for read performance, accepting the redundancy with their eyes open. That is a different thing from never having normalised at all.
Advantages and disadvantages
Advantages
- Each fact stored once, so updates cannot produce a self-contradictory database.
- The insertion and deletion anomalies disappear — independent things become independently storable.
- Smaller, more focused relations index better and mean less to write on every update.
Disadvantages
- More relations means more joins, and joins cost time on read-heavy workloads.
- BCNF sometimes cannot preserve every dependency, so some constraints must be enforced in application code.
- Over-normalising rarely-changing reference data buys correctness you were never at risk of losing.
Watch it work
Check yourself
question 1 / 4
One question at a time. Pick an answer to see why it is right or wrong, then move on — there is no score to keep and nothing is saved.