DBMS 📂 Functional Dependencies & Normalization · 9 of 9 34 min read

Fifth Normal Form (5NF) — Join Dependencies and the Last Step of Normalization

A focused DBMS tutorial that recaps 4NF, then exposes its limitation: multi-valued dependencies only certify two-way splits, so cyclic three-way redundancy survives 4NF untouched. It introduces the join dependency, shows the spurious-tuple trap of a two-way decomposition, and defines 5NF (PJ/NF) — every non-trivial join dependency implied by the candidate keys — through one Dealer–Brand–Product example with animated diagrams, the "triple is the fact" caveat, and academic vs industry viewpoints.

Section 01

The Story That Explains Third Normal Form

The Office Phone Directory Disaster
Imagine a company keeps one giant spreadsheet of employees. Each row stores the employee's name, their department, and — printed next to every single person — the department's office room and the department head.

The Sales team has 300 people, so "Sales · Room 4B · Mr. Khan" is copied 300 times. One Monday, Sales moves to Room 9A and Mr. Khan is replaced. Now somebody must hunt down and edit 300 identical rows. Miss even one, and the database says Sales is in two rooms at once.

Worse: a brand-new department "AI Research" is created, but no one has joined yet — so it cannot be recorded at all, because there is no employee row to attach it to. And if the last person in a department resigns, the room and head vanish with them.

The room and the head were never really facts about the employee. They were facts about the department, hiding in the wrong table. Removing that hidden indirection is exactly what Third Normal Form does.

This tutorial builds up gently — a quick look at Functional Dependencies, then 1NF and 2NF — before focusing on the real target: Third Normal Form (3NF), the problem 2NF leaves behind, and how 3NF fixes it. Every step uses one consistent example so the ideas connect, and we finish with the pitfalls, a second drill, and a self-test.


Section 02

The Foundation — Functional Dependencies

Normalization is built on one idea: the functional dependency (FD). We write X → Y and read it as "X determines Y" — meaning if you know the value of X, the value of Y is fixed and unambiguous.

📊 Animated — What "X determines Y" Means
StudentID the determinant (X) determines StudentName the dependent (Y)
One StudentID always maps to exactly one StudentName — but one name might be shared by many IDs. FDs point one way.
🔑
Three Terms You Must Lock In

A candidate key is a minimal set of attributes that uniquely identifies every row. A prime attribute is any attribute that is part of some candidate key. A non-prime attribute is everything else. Almost every normalization rule is phrased in terms of how non-prime attributes depend on candidate keys.

🔍 How Professionals Discover FDs in the Real World
Rules
Read the business rules. "Each instructor teaches one course" is an FD wearing plain clothes. Most dependencies are written down in policy before they're written in SQL.
People
Interview domain experts. Ask "if I know X, is Y always fixed?" — stakeholders can answer this even if they've never heard the word "dependency."
Data
Examine sample data for patterns — but only as a hint. Data can suggest an FD; only the business rule can confirm it. A 50-row sample where every manager has one office doesn't prove managers can't share.
Trap
Never declare an FD from data alone. An FD is a claim about all legal states of the table, not the rows you happen to have today. Semantics beat samples.

Section 03

Quick Recap — First Normal Form (1NF)

1NF has one job: every cell must hold a single, atomic value — no lists, no repeating groups, no comma-separated bundles. Each row must also be unique.

❌ Violates 1NF
StudentIDNameCourses
S1AaravDBMS, OS, CN
S2DiyaDBMS, AI
✅ In 1NF
StudentIDNameCourse
S1AaravDBMS
S1AaravOS
S1AaravCN
S2DiyaDBMS
S2DiyaAI
🌱
The Takeaway

The "Courses" cell held multiple values, so we couldn't reliably search, sort, or join on it. Splitting it into one course per row makes the data queryable. 1NF is the entry ticket — every higher normal form assumes you are already here.


Section 04

Quick Recap — Second Normal Form (2NF)

2NF attacks the partial dependency: a non-prime attribute that depends on only part of a composite (multi-column) key, rather than the whole key. This problem can only appear when the key is made of more than one attribute.

Take an ENROLLMENT table with composite key {StudentID, CourseID}:

StudentID (key)CourseID (key)StudentNameCourseTitleGrade
S1C1AaravDBMSA
S1C2AaravOperating SystemsB
S2C1DiyaDBMSA
⚖️ Spotting The Partial Dependencies
FD 1
StudentID → StudentName — name depends on only half the key. Partial.
FD 2
CourseID → CourseTitle — title depends on only the other half. Partial.
FD 3
{StudentID, CourseID} → Grade — grade needs the whole key. Full dependency — this one is fine.

To reach 2NF, we split each partial dependency into its own table:

👤
STUDENT
StudentID → StudentName
StudentID (key), StudentName. Each student stored once.
📚
COURSE
CourseID → CourseTitle
CourseID (key), CourseTitle. Each course stored once.
📝
ENROLLMENT
{StudentID, CourseID} → Grade
The composite key plus Grade — the only fully-dependent fact.
Now in 2NF

Every non-prime attribute now depends on the whole key of its table. We have eliminated partial dependencies. It feels finished — but a quieter, sneakier problem can still survive. That is the bridge to 3NF.


Section 05

The Issue That 2NF Leaves Behind

Here is the crucial insight most learners miss: a table can be perfectly in 2NF and still be badly designed. 2NF only guards against dependencies on part of the key. It says nothing about a non-prime attribute depending on another non-prime attribute. That hidden chain is called a transitive dependency — a non-prime attribute that contains a fact about another non-prime attribute, instead of a fact about the key.

Take a clean STUDENT table with a single-column key StudentID. Because the key is one attribute, partial dependency is impossible — so this table is automatically in 2NF:

StudentID (key)StudentNameDeptIDDeptNameDeptHead
S1AaravD1Computer ScienceDr. Rao
S2DiyaD1Computer ScienceDr. Rao
S3KabirD2MathematicsDr. Bose
S4MiraD1Computer ScienceDr. Rao

Look at how the dependencies actually flow:

🔎 The Dependency Chain
Direct
StudentID → DeptID — each student belongs to one department. Good.
Hidden
DeptID → DeptName, DeptHead — a non-prime attribute determines other non-prime attributes. Transitive!
Result
StudentID → DeptID → DeptName — DeptName depends on the key only indirectly, through DeptID.

That indirection is harmless in theory but toxic in practice. It reproduces the "Office Phone Directory Disaster" from Section 01. Watch the three classic anomalies appear:

Insertion Anomaly
can't add a dept alone
A new department "Physics (D3)" exists but has no students yet. You cannot record it — there is no StudentID to attach it to.
🔄
Update Anomaly
edit many rows
Dr. Rao is replaced as CS head. You must update every CS student row. Miss one, and the data contradicts itself.
🗑️
Deletion Anomaly
lose facts silently
If Kabir (the only Maths student) is deleted, the existence of the Mathematics department and Dr. Bose vanishes too.
⚠️
This Is The Whole Point

The table satisfies 2NF completely, yet it still suffers redundancy and all three anomalies. The culprit is the transitive dependency 2NF was never designed to catch. Third Normal Form exists specifically to remove it.


Section 06

Third Normal Form — The Definition (and Its History)

A relation is in Third Normal Form if it is already in 2NF and it contains no transitive dependency of a non-prime attribute on a candidate key. The formal test is a rule about every non-trivial functional dependency X → Y in the table:

Condition A
X is a superkey
The left-hand side uniquely identifies the row (it is, or contains, a candidate key).
Condition B
Y is a prime attribute
Every attribute on the right-hand side is part of some candidate key.
📝
The Rule, In One Sentence

For each functional dependency, at least one of the two conditions must hold. If you ever find a dependency where the left side is not a superkey and the right side is not a prime attribute, the table breaks 3NF.

📚
A Little History Worth Knowing

3NF was defined by E. F. Codd in 1971, the father of the relational model. The crisp two-condition test above is Carlo Zaniolo's 1982 reformulation — the version textbooks use today, because it makes the difference between 3NF and BCNF visible at a glance (BCNF simply deletes Condition B). And the famous mantra — "every non-key attribute must depend on the key, the whole key, and nothing but the key" — comes from Bill Kent's 1983 paper "A Simple Guide to Five Normal Forms," often quoted with the playful courtroom oath appended: "…so help me Codd."


Section 07

Animated Diagram — How a Transitive Dependency Forms and Breaks

Watch the dependency pulse travel from the key, through the non-prime attribute, to the final attribute — the indirect red path is what 3NF forbids.

🔮 Before — Transitive Dependency Inside One Table
StudentID candidate key DeptID non-prime DeptName non-prime indirect: StudentID → DeptName (transitive — forbidden in 3NF) direct & valid non-prime → non-prime
DeptName never touches the key directly. It rides on DeptID — the textbook transitive dependency.
✅ After — Decomposition Splits the Chain
STUDENT StudentID (PK) StudentName DeptID (FK) DEPARTMENT DeptID (PK) DeptName DeptHead joined by foreign key — no data duplicated
DeptName and DeptHead now live once, beside the key they truly belong to. The chain is gone.

Section 08

Worked Example — Converting the Table to 3NF

We remove the transitive dependency by lifting the offending group (DeptID, DeptName, DeptHead) into its own table, leaving only the foreign key DeptID behind.

❌ STUDENT (2NF, redundant)
SIDNameDeptIDDeptNameHead
S1AaravD1Comp SciRao
S2DiyaD1Comp SciRao
S3KabirD2MathsBose
S4MiraD1Comp SciRao
✅ STUDENT (3NF, lean)
SIDNameDeptID (FK)
S1AaravD1
S2DiyaD1
S3KabirD2
S4MiraD1
New table: DEPARTMENTDeptNameDeptHead
D1 (PK)Computer ScienceDr. Rao
D2 (PK)MathematicsDr. Bose
🎉 Every Anomaly Is Now Fixed
Insert
Add "Physics (D3)" to DEPARTMENT with zero students. Works.
Update
Change the CS head once, in one row of DEPARTMENT. No fan-out.
Delete
Remove the last Maths student; the Maths department survives in DEPARTMENT. Safe.
Verify
In STUDENT, the only FD is StudentID → Name, DeptID — left side is the key. In DEPARTMENT, DeptID → DeptName, DeptHead — left side is the key. Both in 3NF.

Section 09

Second Drill — The Geography Chain (a Classic Exam Pattern)

Transitive dependencies love to hide in address and geography columns. Here is the pattern that appears in countless real schemas and exam papers — a candidate registration table:

CandNo (key)CandNameStateCountryPinCode
C1AaravHimachal PradeshIndia173212
C2DiyaHimachal PradeshIndia173212
C3LiamCaliforniaUSA94016
🧭 Walk the Test Yourself
Spot
State → Country — Himachal Pradesh is always India. A non-prime attribute determines another non-prime attribute. Transitive via State.
Spot
PinCode → State — a postal code pins down the state too. Another hidden chain: CandNo → PinCode → State → Country. A two-link transitive chain!
Fix
Lift the geography into its own lookup: LOCATION(PinCode, State, Country), and keep only PinCode as a foreign key in CANDIDATE. Both tables now in 3NF.
Lesson
Chains can be longer than one hop. Whenever columns "travel together" (city/state/country, code/description, product/category/category-manager), suspect a transitive chain.

Section 10

2NF vs 3NF — Side by Side

AspectSecond Normal FormThird Normal Form
Target problemPartial dependencyTransitive dependency
Dependency removedNon-prime on part of the keyNon-prime on another non-prime
Needs composite key to occur?Yes — only multi-attribute keysNo — happens even with single-column keys
PrerequisiteMust already be in 1NFMust already be in 2NF
Rule of thumbDepend on the whole keyDepend on nothing but the key
Remaining riskTransitive chains still allowedRare overlapping-key cases → BCNF
🧠
The One-Line Mental Model

1NF = no repeating groups. 2NF = no partial dependency. 3NF = no transitive dependency. Each form removes exactly one species of redundancy the previous one couldn't see.


Section 11

Common Pitfalls & Misconceptions

These are the mistakes that show up again and again in code reviews, exams, and interviews — even from people who can recite the definition perfectly.

🧮
The Derived-Column Trap
TotalPrice = Qty × UnitPrice
Storing a computed column like TotalPrice alongside Qty and UnitPrice creates a dependency on non-key attributes — a 3NF violation in disguise. Compute it in a query or view instead, or accept it as deliberate, documented denormalization.
🔬
Judging FDs From Sample Data
semantics > samples
"In our data, every manager has one office, so Manager → Office." Maybe — or maybe the sample is just small. An FD is a business rule about all legal states, not a pattern in today's rows. Confirm with the domain, not the spreadsheet.
✂️
Over-Normalizing Everything
lookup-table mania
Splitting a two-value Status column ("Active"/"Inactive") into its own table adds joins without removing any real dependency. 3NF targets transitive facts, not every repeated string. Normalize dependencies, not vocabulary.
🔑
"Single Key = Automatic 3NF"
false comfort
A single-column key guarantees 2NF, not 3NF — our Student–Department table proved it. Transitive chains don't care how many columns your key has.
🔗
Missing Multi-Hop Chains
A → B → C → D
People check one hop and stop. The geography drill showed a two-link chain (PinCode → State → Country). Follow every arrow until it dead-ends; each link is its own violation.
🎯
Forgetting Why You're Doing It
3NF is a means, not a medal
The goal is integrity: one fact, one place, no anomalies. If a decomposition makes the schema unmaintainable for zero integrity gain, you've optimized for the certificate, not the database.

Section 12

Academic vs Industry Perspective

🎓 Academic View
Defined formally by E. F. Codd (1971); the modern two-condition test is Zaniolo's 1982 reformulation, built on functional dependencies and candidate keys.
3NF is provably lossless and dependency-preserving — you can always decompose into 3NF without losing data or FDs (the Bernstein synthesis algorithm constructs it).
Sits in the hierarchy 1NF ⊂ 2NF ⊂ 3NF ⊂ BCNF; every BCNF table is also 3NF, but not vice-versa.
Focus is on correctness: eliminating anomalies and redundancy by theorem, not by taste.
🏭 Industry View
3NF is the default target for transactional (OLTP) systems — banking, orders, inventory — where write integrity matters most.
Beyond integrity, 3NF pays off in smaller tables, leaner indexes, and simpler maintenance — schema changes touch one table instead of many.
Teams sometimes denormalize on purpose in analytics/reporting (data warehouses, star schemas) to make reads faster — the trade-off is joins vs controlled redundancy.
Practical rule: normalize to 3NF first, then denormalize only where profiling proves a real performance need.
⚖️
Where Theory Meets the Real World

Academia proves why 3NF is safe; industry decides where to apply it. A senior engineer designs the source-of-truth schema in 3NF, then makes a deliberate, measured choice to denormalize copies for speed — never by accident.


Section 13

When 3NF Is Enough — and When It Isn't

Most OLTP Schemas
For the vast majority of business databases, 3NF removes essentially all harmful redundancy. It is the sweet spot of safety and simplicity.
orders, users, payments
⚠️
Overlapping Candidate Keys
When a table has multiple overlapping candidate keys and a non-key determinant, 3NF can still permit redundancy. That edge case is what BCNF tightens.
go one step further → BCNF
📊
Read-Heavy Analytics
Dashboards and warehouses may deliberately denormalize below 3NF for query speed — a conscious, profiled trade, not a design failure.
star / snowflake schemas
🎯
BCNF in One Breath

BCNF is the stricter sibling: every determinant (left side of an FD) must be a superkey — no exceptions for prime attributes. If your table has a single candidate key (like most), reaching 3NF usually puts you in BCNF for free.


Section 14

Test Yourself — Three Interview-Style Questions

Commit to an answer for each before reading the solutions below. This is how the concept sticks.

Question 1
spot the violation
ORDER(OrderID, CustomerID, CustomerCity), key = OrderID, and CustomerID → CustomerCity. Is this in 3NF? If not, what's the fix?
Question 2
true or false
"3NF primarily eliminates partial dependencies." True or false — and which normal form actually owns that job?
Question 3
the subtle one
R(A, B, C) with FDs {A, B} → C and C → B. C is not a superkey — does the table break 3NF?
🔑 Solutions — Check Your Reasoning
A1
Not in 3NF. The chain OrderID → CustomerID → CustomerCity is transitive — CustomerCity is a fact about the customer, not the order. Fix: move City to a CUSTOMER table, keep CustomerID as the FK.
A2
False. Partial dependencies are 2NF's job. 3NF eliminates transitive dependencies. Keeping these two straight is the single most common normalization-exam slip.
A3
Still in 3NF! For C → B: C is not a superkey (Condition A fails), but B is part of candidate key {A, B} — so B is a prime attribute and Condition B saves it. (This exact pattern is why BCNF exists: BCNF would reject it.)

Section 15

Golden Rules

📝 Third Normal Form — Non-Negotiable Rules
1
Reach 2NF first. 3NF is meaningless until partial dependencies are gone. Normalization is a ladder — never skip a rung.
2
Hunt for non-prime → non-prime dependencies. If a non-key attribute is determined by another non-key attribute, you have a transitive dependency. That is the 3NF violation, every time — and follow chains multiple hops, not just one.
3
Apply the test: for every FD X → Y, either X is a superkey or Y is a prime attribute. If neither holds, decompose.
4
Decompose by lifting the dependent group into its own table, leaving the determinant behind as a foreign key. The decomposition is lossless — a join rebuilds the original.
5
Confirm FDs with the business, never with sample data alone. A dependency is a rule about every legal state of the table — today's rows can mislead you in both directions.
6
Watch for derived columns. A stored computed value (totals, ages, durations) depends on non-key attributes — either drop it, move it to a view, or document it as deliberate denormalization.
7
Remember Bill Kent's mantra: every non-key attribute depends on the key, the whole key, and nothing but the key — so help me Codd.
8
Normalize for correctness, denormalize for measured speed. Build the source-of-truth in 3NF; relax it only where profiling proves a real read-performance need — and if overlapping candidate keys still leave redundancy, check BCNF.
You have completed Functional Dependencies & Normalization. View all sections →