AWS Cloud Architect & Developer · Databases
Second, Third and Boyce–Codd Form
Split the campus-shop leftovers: partial FDs, transitive wardens, and BCNF determinants.
The kiosk tables are already split. This lesson is what goes wrong when they are not: item_name stuck on a composite sale key (2NF), a warden stuck on Student (3NF), a stall that determines an item without being a key (BCNF), and the insert that must bounce when student 99 does not exist.
- AWS Cloud Architect & Developer
- Hard level
- 4 concepts
- 5 practice questions
1Second normal form: no partial dependency
Imagine we stuffed item_name onto a table whose key is {sale_id, item_id} — a line-item sheet. item_id → item_name still holds, but item_id is only part of the key. That is a partial dependency: a non-key column determined by a piece of the key. Second normal form forbids it. 2NF = 1NF and no non-prime attribute depends on only part of a candidate key.
The kiosk already avoids this by keeping item_name on Item, keyed by item_id alone. The stuffed sheet would repeat "Tea" on every tea sale. Updating Tea's name would mean finding every copy. The 2NF fix is the split we already did: Item(item_id, item_name, price_rs) and Sale(sale_id, student_id, item_id, qty).
Figure. item_name hanging off a composite sale key is a partial dependency. It belongs on Item.
Spot a partial dependency
- Composite keyThe sheet is keyed by {sale_id, item_id}.
- Leftover FDitem_id → item_name uses only item_id.
- SplitGive item_name its own table keyed by item_id.
| FD | On {sale_id, item_id} sheet | 2NF? |
|---|---|---|
| item_id → item_name | depends on part of the key | no — split out |
| {sale_id, item_id} → qty | depends on the whole key | yes |
Highest normal form of a line-item sheet
LineItem(sale_id, item_id, qty, item_name) has the dependencies {sale_id, item_id} -> qty and item_id -> item_name. Find the candidate key and the highest normal form the table satisfies.
- closure of {sale_id, item_id}: it gives qty, and item_id gives item_nameall four attributes, so the candidate key is {sale_id, item_id}
- item_id -> item_name uses only part of that composite keya partial dependency of a non-prime attribute
- a partial dependency is presentfails 2NF, so the highest normal form is 1NF
Pro tip. A non-prime attribute (item_name) determined by part of a composite key is the 2NF failure; split item_name onto an Item table keyed by item_id alone.
A relation is in 2NF if it is in 1NF and
- Every attribute is a key
- No non-prime attribute is partially dependent on a candidate key
- There are no foreign keys
2NF removes partial dependencies. 3NF is the next cut (transitive dependencies).
2Third normal form: no transitive dependency
Suppose we add warden to Student: student_id → hostel and hostel → warden. Then student_id → warden by transitivity. warden is not a fact about the student; it is a fact about the hostel. That leftover hop is a transitive dependency. Third normal form forbids a non-prime attribute that depends on the key only through some other non-key column.
The 3NF test on an FD X \to Y: either X is a superkey, or Y is prime (part of some candidate key). hostel → warden fails both — hostel is not a key of Student, and warden is not prime. The fix is a Hostel table: hostel → warden lives there, and Student keeps only hostel as a foreign key.
Figure. Key to hostel to warden. The second hop is the 3NF leftover — warden belongs with hostel.
Split the transitive hop
- See the chainstudent_id → hostel → warden.
- Name the leftoverwarden should move with hostel.
- New tableHostel(hostel, warden); Student keeps hostel as a foreign key.
| FD | X superkey? | Y prime? | 3NF? |
|---|---|---|---|
| student_id → name | yes | no | yes |
| hostel → warden | no | no | no — split |
3NF split for the warden
CREATE TABLE hostel (
hostel TEXT PRIMARY KEY,
warden TEXT
);
CREATE TABLE student (
student_id INT PRIMARY KEY,
name TEXT,
hostel TEXT REFERENCES hostel(hostel)
);student_id → hostel → warden violates 3NF because
- warden depends on the key only through hostel, and warden is not prime
- hostel is a primary key
- 3NF forbids all foreign keys
The transitive hop hostel → warden is the leftover. Move warden to a Hostel table.
3BCNF: every determinant is a key
Boyce–Codd normal form is 3NF with the prime-attribute exception removed. For every non-trivial FD X \to Y, X must be a superkey. 3NF still allows that leftover when the right side is prime. BCNF does not.
A kiosk-shaped example: StallSale(student_id, item_id, stall) with {student_id, item_id} → stall (who bought what at which stall) and stall → item_id (each stall sells only one item). stall is a determinant but not a superkey, so the table is not BCNF. item_id is prime, so 3NF may still hold. The BCNF split is Stall(stall, item_id) plus a sale table that names student and stall.
Figure. 3NF lets a non-key determinant survive when Y is prime. BCNF does not. stall → item_id is that leftover.
3NF versus BCNF on StallSale
- Key{student_id, item_id} → stall. That FD is fine for both.
- Leftoverstall → item_id. stall is not a superkey.
- 3NF exceptionitem_id is prime, so 3NF can hold; BCNF still fails.
| Test on X \to Y | 3NF | BCNF |
|---|---|---|
| X is a superkey | pass | pass |
| Y is prime, X is not a key | pass | fail |
| neither | fail | fail |
3NF but not BCNF
StallSale(student_id, item_id, stall) has {student_id, item_id} -> stall and stall -> item_id, because each stall sells exactly one item. Is the table in 3NF? Is it in BCNF?
- candidate keys from the two dependencies{student_id, item_id} and {student_id, stall}
- test stall -> item_id: is stall a superkey?no
- 3NF exception: is item_id a prime attribute? it is part of key {student_id, item_id}yes, so 3NF holds
- BCNF needs every determinant to be a superkey, but stall is notfails BCNF
Pro tip. 3NF forgives a non-key determinant when its right side is a prime attribute; BCNF removes that exception, so stall -> item_id is exactly the dependency that separates the two forms.
BCNF is stricter than 3NF because it requires that
- Every attribute must be atomic
- For every non-trivial FD X → Y, X must be a superkey
- There must be no multivalued dependencies
BCNF drops 3NF's "or Y is prime" exception. Multivalued dependencies are 4NF, which this course does not invent a sixth form to reach.
4Integrity constraints
Keys and normal forms are not the only rules. Entity integrity: a primary key cell is never NULL — sale_id 100 must exist. Referential integrity: a foreign key is either NULL (if the design allows) or matches a live key — Sale.student_id = 1 must be Asha's row, not a dangling 99. Domain integrity: qty is a positive integer, not "two" and not −1.
These are the database saying no. Inserting sale 104 for student_id 99 should fail if 99 is not in Student. That failure is the point: the shop cannot record a purchase by nobody.
Figure. A dashed pointer to a student who is not there. Referential integrity rejects the insert.
| Rule | On this shop |
|---|---|
| Entity | sale_id, student_id, item_id are never NULL |
| Referential | Sale.student_id must match Student |
| Domain | qty ≥ 1; price_rs ≥ 0 |
A sale that should bounce
-- student 99 does not exist
INSERT INTO sale VALUES (104, 99, 11, 1);
-- referential integrity: rejectINSERT sale (104, 99, 11, 1) when Student has only ids 1, 2, 3 should fail by
- Entity integrity, because 104 is new
- Referential integrity: 99 is not a Student key
- 1NF, because 104 is a number
The new sale_id is fine. The foreign key 99 does not match Student. That is referential integrity.
Notes
- 2NF: 1NF and no non-prime attribute depends on part of a candidate key.
- 3NF: for each FD X→Y, X is a superkey or Y is prime. Transitive hops fail this.
- BCNF: for each non-trivial FD X→Y, X is a superkey. No prime-attribute exception.
- Entity integrity: primary key not NULL. Referential: foreign key matches or is NULL.
Formulas
- 2NF = 1NF + no partial dependency of a non-prime on a candidate key.
- 3NF: X superkey OR Y prime.
- BCNF: X superkey for every non-trivial X→Y.
Exam traps & shortcuts
- item_name on a {sale, item} sheet is the 2NF leftover.
- hostel → warden on Student is the 3NF leftover.
- stall → item_id with item_id prime can be 3NF and not BCNF.
Reference tables
| Form | What it removes on this shop |
|---|---|
| 1NF | lists in a cell ("Samosa, Tea") |
| 2NF | item_name hanging off part of a composite key |
| 3NF | warden hanging off hostel on Student |
| BCNF | stall → item_id when stall is not a key |
Recap
Each form removes one leftover FD.
- 2NF
- No non-prime on part of a key. item_name belongs on Item.
- 3NF
- X superkey or Y prime. hostel → warden fails; split Hostel.
- BCNF
- Every determinant is a superkey. No prime exception.
- Integrity
- PK not NULL; FK matches; qty is a sensible domain.
Practise Second, Third and Boyce–Codd Form
Reading is free and needs no account. Practice, mocks and progress live in the app.
- 5 exam-style questions on this topic, with explanations
- A 2-question practice set that ends the chapter
- Timed mocks scored with the real marking scheme
- Readiness tracked per topic, kept on your device