In a 1993 interview Edgar F. Codd, the inventor of the relational model, explained the word: "I called it normalization because then President Nixon was talking a lot about normalizing relations with China. I figured that if he could normalize relations, so could I." (Interview in DBMS Magazine, December 1993, as quoted by Joe Reis and by Simon Willison.)
Normal forms: the key, the whole key, nothing but the key
After this lesson you will read the functional dependencies of a table, say which normal form it is in, split it step by step into tables that store every fact once — and say why the NoSQL half of the course builds the unsplit table on purpose.
Pine Valley Furniture's invoice table on p. 130 has five rows, and every value in it is right. Order 1006 really went to Value Furniture in Plano, TX; product 4 really is a Natural Maple entertainment center at 650.00. The slide still stamps it: "this is relation, but not a well-structured one".
Do three ordinary things with it. Value Furniture moves: you must edit three cells, and if you miss one the table contradicts itself. The company adds a new product to its catalogue: there is no row to put it in until somebody orders it. Furniture Gallery cancels its dresser: delete that line, and the company no longer knows that it sells a 4–Dr oak dresser at 500.00.
How can a table with no wrong value be wrong? Hold on to the question. The answer is one idea, and by the end of the lesson you will point at the exact arrow that causes each of the three troubles.
One fact, one place: what normalization is for
Start with the table itself. The highlighted cells below are not errors. Each of them repeats a fact that an earlier row already stated.
| Order_ID | Order_ | Customer_ | Customer_ | Customer_ | Product_ID | Product_ | Product_ | Unit_ | Ordered_ |
|---|---|---|---|---|---|---|---|---|---|
| 1006 | 10/24/2004 | 2 | Value Furniture | Plano, TX | 7 | Dining Table | Natural Ash | 800.00 | 2 |
| 1006 | 10/24/2004 | 2 | Value Furniture | Plano, TX | 5 | Writer's Desk | Cherry | 325.00 | 2 |
| 1006 | 10/24/2004 | 2 | Value Furniture | Plano, TX | 4 | Entertainment Center | Natural Maple | 650.00 | 1 |
| 1007 | 10/25/2004 | 6 | Furniture Gallery | Boulder, CO | 11 | 4–Dr Dresser | Oak | 500.00 | 4 |
| 1007 | 10/25/2004 | 6 | Furniture Gallery | Boulder, CO | 4 | Entertainment Center | Natural Maple | 650.00 | 3 |
"Value Furniture is at Plano, TX" is stored three times, once per line of its order. "Product 4 is a Natural Maple Entertainment Center at 650.00" is stored twice, once per order that contains it. None of these copies is wrong today. Each copy is a place where the table can become wrong tomorrow.
The slides define the cure on p. 120:
Normalization — "A two step process that puts data into tabular form by removing repeating groups and then removes duplicated data from the relational tables." Normalization theory "is based on the concepts of normal forms".
The two steps are different in kind. The first makes the data a relation at all: one value per cell, a key per row. That is first normal form, section 3. The second splits tables so that each fact is stored once, guided by rules called functional dependencies. That gives second and third normal form, section 4.
The goal, printed in bold on p. 121, is "to create a set of relational tables that are free of redundant data and that can be consistently and correctly modified or updated", and the slide draws the consequence: "all tables in a relational database should be in the third normal form (3NF)". Page 127 lists the same goals as two bullets — "Eliminate redundant data" and "Ensure data dependencies make sense (only storing related data in a table)" — and adds the benefits: less space, data "logically stored and easy to maintain".
What goes wrong in an unnormalized table has standard names in the textbooks; the slides describe the goal and leave the names out. They are the three troubles of the puzzle:
- update anomaly — one fact sits in several rows, so changing it means changing every copy. Value Furniture moves: three cells, and a forgotten one leaves two addresses for one customer.
- insertion anomaly — a fact cannot be stored without an unrelated one. A product nobody ordered needs an Order_ID, which is part of the primary key and cannot be NULL.
- deletion anomaly — deleting one fact deletes another. Cancelling the line (1007, 11) erases the only record that product 11 exists.
Page 122 compresses third normal form into one sentence: "A relational table is in 3NF if and only if all non-key columns are: Mutually independent and Fully dependent upon the primary key", and calls 1NF and 2NF "intermediate steps to achieve the goal of having all tables in 3NF". A mnemonic that is not on the slides, usually credited to William Kent (1983), says the same thing in three steps: every non-key column depends on the key, the whole key, and nothing but the key. The first phrase is 1NF, the second 2NF, the third 3NF, and the rest of this lesson unpacks them in that order.
Normalization stores each fact once: every non-key column depends on the key, the whole key, and nothing but the key.
Functional dependencies: the rules behind the repetition
Why is "Voyager" stored twice in the table of p. 125? Because Janeway likes two drinks, so she has two rows, and each row carries her address. The slide circles the repeated cells and writes the reason under each: "Because name -> addr".
| name | addr | drinkLiked | manf | favDrink |
|---|---|---|---|---|
| Janeway | Voyager | Bud | A.B. | WickedAle |
| Janeway | Voyager | WickedAle | Pete's | WickedAle |
| Spock | Enterprise | Bud | A.B. | Bud |
Page 124 lists the rules behind those repetitions as "Reasonable FD's to assert":
name -> addrname -> favdrinkdrinkLiked -> manf
Page 123 defines the idea:
Functional dependency — "A column, Y, of the relational table R is said to be functionally dependent upon column X of R if and only if each value of X in R is associated with precisely one value of Y at any given time." It is written R.x → R.y and read "column x functionally determines (identifies) column y". X is the determinant (p. 124).
The slide's definition speaks of single columns, but a determinant can be a set of columns: p. 133 needs "Order_ID, Product_ID" on the left of an arrow. For sets, the definition is a statement about pairs of rows:
- \(t_1, t_2\)
- any two rows of any legal instance of R
- \(t[X]\)
- the values of row t in the columns of X
Two consequences matter for everything that follows. First, keys: "If column X is a primary key, then all columns in the relational table R must be functionally dependent upon X" (p. 123). A key value picks out one row, hence one value of every column. Turned around, a set of columns that determines every column is a superkey, and a minimal superkey is what p. 95 calls a key (lesson 8). Textbooks say candidate key, because a table can have several; the primary key is the one the designer picks.
Second, the words "at any given time". A functional dependency is a rule about every legal state of the table, asserted from what the data means — a drinker has one address, a drink has one maker. That is why p. 124 says "reasonable FD's to assert". Rows can refute a rule: one pair that agrees on X and differs on Y is enough. Rows can never prove one. Pine Valley's five rows satisfy 28 single-column dependencies that do not follow from the rules of p. 133 — Unit_Price → Product_ID among them, although nothing stops two products from costing the same.
"Janeway appears twice with Voyager, so name → addr holds." The rows are only consistent with it. It holds because the designer asserts that a drinker has one address. The widget below shows the other side of the coin: rows that agree with a rule nobody asserted.
The table also shows why dependencies produce repetition. name is not the key of Drinkers — Janeway has two rows — so whatever name determines is copied into each of her rows. A determinant that is not a key of its table is the source of every copy in this lesson.
Following the rules: the closure
Page 126, "Basic Idea", is the rule for splitting tables: "To know what FD's hold in a projection, we start with given FD's and find all FD's that follow from given ones. Then, restrict to those FD's that involve only attributes of the projected schema." The slides do not say how to "find all FD's that follow". The standard tool is the attribute closure \(X^+\): start from X and keep adding the right side of every dependency whose left side is already inside, until nothing changes. Then
and X is a superkey exactly when \(X^+\) contains every column. Here is the closure of {name, drinkLiked} under the three rules of p. 124:
Start from the set itself — every set of columns determines itself: {name, drinkLiked}.
name is inside and name → addr: add addr. Now {name, drinkLiked, addr}.
name → favDrink fires as well: add favDrink. Now {name, drinkLiked, addr, favDrink}.
drinkLiked is inside and drinkLiked → manf: add manf. All five columns are in, so no rule can add anything: stop.
Conclusion: {name, drinkLiked} is a superkey. It is also minimal, since the closure of {name} is {name, addr, favDrink} and the closure of {drinkLiked} is {drinkLiked, manf}. So {name, drinkLiked} is the key of Drinkers.
Now the projection rule works. Split Drinkers into (name, addr, favDrink), (drinkLiked, manf) and (name, drinkLiked). The dependencies that hold in each piece are those of the closure that use only its columns: name → addr, favDrink in the first, drinkLiked → manf in the second, and only trivial ones in the third, whose key is the pair itself. Section 4 explains why this is the right split: name → addr hangs on half of the key.
1NF: first, be a relation
Before the invoice of p. 130 there is the invoice of p. 129, titled "Multivalued attributes". It is the same two orders written the way a paper invoice looks: order 1006 appears once, with three product lines stacked inside it. Fig. 1 shows three of its ten columns before and after.
Before — p. 129: "NOT a relation"
After — p. 130: a relation, "not a well-structured one"
Page 128 states the rules of the first normal form:
- "Eliminate duplicative columns from the same table" — no Product1, Product2, Product3 laid out side by side;
- "No multivalued attributes", "Every attribute value is atomic (i.e. no sets of values within a column)" — no list inside a cell, as on the left of Fig. 1;
- "Create separate tables for each group of related data and identify each row with a unique column or set of columns (the primary key)."
The last line of p. 128 explains the red verdict of p. 129: "All relations are in 1st Normal Form". A relation is a set of tuples that take one value from each domain (lesson 8), so a table with a set inside a cell is not in 1NF, and therefore "NOT a relation" at all. 1NF is not a quality grade. It is the entry ticket to the relational model.
It is also all that p. 130 has. The flat invoice is a legal relation with a legal key, and it still holds the 15 copies of section 1. Removing repeating groups removes nested lists, not repeated facts. That second job needs the dependencies.
Keep Fig. 1 in mind for later. A MongoDB order document with an embedded array of its lines is the left-hand picture, written on purpose: document stores give up 1NF deliberately (lesson 13).
2NF and 3NF: the whole key, and nothing but the key
Page 133 draws the dependencies of the 1NF invoice over its ten columns and lists them in red:
- Order_ID → Order_Date, Customer_ID, Customer_Name, Customer_Address
- Customer_ID → Customer_Name, Customer_Address
- Product_ID → Product_Description, Product_Finish, Unit_Price
- Order_ID, Product_ID → Order_Quantity
and concludes in blue: "Therefore, NOT in 2nd Normal Form". The key is the pair (Order_ID, Product_ID). Look at where each arrow starts: at the whole key, at half of it, or at a column outside it. That one question sorts every dependency into three kinds.
Full dependency — a non-key column depends on the whole key and on no part of it. Only Ordered_Quantity: an amount belongs to one product on one order.
Partial dependency — a non-key column depends on part of a composite key. Order_Date depends on Order_ID alone, Unit_Price on Product_ID alone.
Transitive dependency — a non-key column depends on the key only through another non-key column: the key determines Customer_ID, which determines Customer_Name.
Partial: Product_ID → Unit_Price
Transitive: Order_ID → Customer_ID → Customer_Name
The two normal forms forbid one kind each. Second normal form, p. 132: "1NF PLUS every non-key attribute is fully functionally dependent on the ENTIRE primary key" — "No partial functional dependencies". Page 131 adds that 2NF "deals with relationships between composite key columns and non-key columns". So a table whose key is a single column is in 2NF as soon as it is in 1NF: there is no "part of the key" for a column to hang on. (The fine print for a table with a second, composite candidate key is in section 5.)
Third normal form, p. 136: "2NF plus no transitive dependencies (functional dependencies on non-primary-key attributes)". The slide explains the name: "this is called transitive, because the primary key is a determinant for another attribute, which in turn is a determinant for a third". Page 135 says it shorter: 3NF "requires that all columns depend directly on the primary key".
The repair is the same both times. Page 131 moves the offending columns into new tables and says how to tie them back: "Create relationships between these new tables and their predecessors through the use of foreign keys"; p. 136 spells the recipe out for 3NF: "non-key determinant with transitive dependencies go into a new table; non-key determinant becomes primary key in the new table and stays as foreign key in the old table". Read the same sentence with "part of the key" in place of "non-key determinant" and you have the 2NF step.
Each arrow that does not start at the whole key becomes a table of its own: its determinant is the new key and stays behind as a foreign key.
Run the recipe on the invoice yourself. Draw the dependencies of the 1NF table, then let the widget split it as pp. 134 and 137 do, and test the three anomalies at each step.
The result is the slides' two pictures. After the first split, p. 134 shows ORDER_LINE (3NF), PRODUCT (3NF) and CUSTOMER_ORDER (2NF), with the caption "Partial Dependencies are removed, but there are still transitive dependencies". After the second, p. 137 shows ORDER (3NF), whose Customer_ID has a dashed underline, and CUSTOMER (3NF): "Transitive dependencies are removed". Four tables, every fact once:
- ORDER_LINE(Order_ID*, Product_ID*, Ordered_Quantity)
- PRODUCT(Product_ID, Product_Description, Product_Finish, Unit_Price)
- ORDER(Order_ID, Order_Date, Customer_ID*)
- CUSTOMER(Customer_ID, Customer_Name, Customer_Address)
Underlined columns are primary keys; a star marks a foreign key, as in the mapping slides of lesson 8.
Why must Customer_ID stay in ORDER?
Without it, nothing would say which customer placed order 1006: joining ORDER with CUSTOMER could not rebuild the invoice, and information would be lost. The shared column has to be the key of one side — here Customer_ID is the key of CUSTOMER — so the join returns exactly the original rows. Textbooks call this a lossless-join decomposition; the slides' recipe guarantees it by keeping the determinant as a foreign key.
"Customer_ID → Customer_Name is a partial dependency, because Customer_ID is an ID." Partial means the determinant is part of the key, and Customer_ID is not part of (Order_ID, Product_ID). It is a non-key column, so the dependency is transitive — and that is why 2NF leaves it alone.
The slides' second 3NF example, on p. 135, is a publisher with its address:
BCNF and the ladder: where the course stops
Page 138 draws normalization as a ladder. Each rung is the one above with one more kind of trouble removed, so the forms nest: every BCNF table is in 3NF, every 3NF table in 2NF, every 2NF table in 1NF.
The rung the course does cover last is defined on p. 139: "Boyce–Codd normal form (or BCNF or 3.5NF) is a slightly stronger version of the 3NF."
Boyce–Codd normal form — "For every one of its dependencies X → Y, at least one of the following conditions hold: X → Y is a trivial functional dependency (Y ⊆ X); X is a superkey for schema R" (p. 139).
In words: in BCNF every determinant is a superkey. That is "nothing but the key" applied to every arrow, without exceptions. Check it on the four Pine Valley tables: each has one arrow, starting at its own key, so all four are in BCNF as well as in 3NF.
Where does "slightly" come from? The general textbook definition of 3NF has an escape clause: for every non-trivial X → A, either X is a superkey or A belongs to some candidate key. BCNF drops the clause. The two differ only in tables with two or more candidate keys that overlap — none of the slides' examples. The standard one, from the textbooks, is a small teaching table:
| Student | Course | Teacher |
|---|---|---|
| Anna | Databases | Rossi |
| Bruno | Databases | Rossi |
| Carla | Databases | Verdi |
| Anna | Statistics | Bianchi |
Teacher → Course holds, and Teacher is not a superkey: BCNF fails, and the repetition is real. Yet Course is part of the candidate key (Student, Course), so the escape clause saves 3NF. Splitting into TEACHES(Teacher, Course) and FOLLOWS(Student, Teacher) removes the repetition, but the rule "one teacher per student per course" can no longer be checked inside a single table. Insert (Anna, Verdi) into FOLLOWS: both tables accept it, and only their join reveals that Anna now has two Databases teachers. That is why textbooks name 3NF, always reachable without losing a dependency, as the practical target — the target p. 121 sets.
"In 3NF, no column may depend on a non-key column." The slides phrase 2NF and 3NF with "the primary key", which is exact only when a table has a single candidate key. Take EMPLOYEE(Emp_ID, Tax_Code, Name) with primary key Emp_ID, where every tax code belongs to one employee. Name depends on Tax_Code, a column that is not the primary key — yet there is no repetition at all, because Tax_Code is a candidate key and therefore a superkey. Read "key" as "any candidate key" and "non-key" as "part of no candidate key", and the table is in BCNF. The same reading fixes 2NF: "a single-column key means 2NF" holds when every candidate key is a single column. At the exam, write the slides' definitions; the refinement matters only for a table with more than one candidate key.
The last two rungs leave functional dependencies behind. Fourth normal form removes multivalued dependencies: two independent lists stored in one table, such as an employee's skills and languages, which force every skill to be paired with every language. Fifth normal form handles the rarer tables that can be rebuilt without loss only by joining three or more of their projections. Neither can be stated with the arrows of this lesson, and the course stops at "3.5" (p. 120).
BCNF was developed in 1974 by Raymond F. Boyce and Edgar F. Codd. Boyce had co-developed SEQUEL — the language later renamed SQL — with Don Chamberlin. He died of an aneurysm in June 1974, aged 27.
Two routes to the same tables — and why NoSQL leaves them
Back to the puzzle. What was wrong with five rows that contained no wrong value? Their structure: facts about three different things — orders, customers, products — shared one row, glued together by arrows that did not start at the whole key. Each trouble traces back to an arrow. The three-cell move: the address hangs on Order_ID, half of the key, through Customer_ID, a non-key column — the 2NF split cut it to one copy per order, the 3NF split to one per customer. The product that could not be added and the dresser that vanished with its order line: both hang on Product_ID, the other half of the key, and PRODUCT cured both at once. Every arrow became a table, and every fact now sits in one cell.
There was a second route to the same place. Draw the ER diagram behind the invoice and translate it with the recipe of lesson 8, and the four tables appear directly, with no table ever holding a repeated fact.
Route 1: the ER diagram, translated
Route 2: the 3NF tables of the split
So the two halves of the deck meet. A correct ER diagram, translated by the rules, gives 3NF tables. Normalization is the check, and the repair, for tables that did not come from a good diagram: a spreadsheet, a CSV export, or the Employee table of p. 117 with its DeptName repeated on every employee (lesson 8).
The split has a price, and you pay it on every read. To see one invoice line again, the database must join the four tables back together:
-- returns the five invoice lines of p. 130
-- ("ORDER" is quoted: ORDER is an SQL keyword)
SELECT l.Order_ID, o.Order_Date, c.Customer_Name, c.Customer_Address,
p.Product_Description, p.Unit_Price, l.Ordered_Quantity
FROM ORDER_LINE l
JOIN "ORDER" o ON o.Order_ID = l.Order_ID
JOIN CUSTOMER c ON c.Customer_ID = o.Customer_ID
JOIN PRODUCT p ON p.Product_ID = l.Product_ID;
The result is a wide table like the data frames statistical models are fitted on: one row per observation, with every fact repeated where it applies. On one machine three joins are cheap. Across a cluster, where ORDER_LINE and CUSTOMER may live on different nodes, every join is network traffic (lesson 3, lesson 5). That is the main reason the NoSQL half of the course denormalises on purpose. MongoDB embeds the lines inside the order document — the left side of Fig. 1, chosen deliberately (lesson 13). Cassandra builds one table per query and copies the same data into each of them (lessons 20 and 21); the Cassandra exercise session sums it up on p. 1551: "No joins or foreign keys. Data is denormalized and duplicated for query efficiency." Those systems accept the update anomaly in exchange for reads without joins.
The normal forms do not stop being useful there. They are the yardstick that tells you exactly which anomalies you bought, and which application code must now keep the copies in step.
Exam-style questions
The practical part is about Neo4j, MongoDB, Elasticsearch, Redis and SparkQL, and no past paper asks for a decomposition there, so normalization belongs to the theory part: open questions, multiple-choice and true-or-false questions, where a wrong answer may carry a penalty (announced just before the exam). The restaurant exercise trains the same skill on the ER scenario of a past paper.
Define a functional dependency X → Y on a relational table R. Explain why the primary key of R functionally determines every column of R, and why the rows stored in R can show that a functional dependency does not hold but can never show that it holds.
Show model answer
Y is functionally dependent on X if each value of X in R is associated with precisely one value of Y at any given time: any two rows that agree on X also agree on Y. X is called the determinant. A primary key identifies exactly one row, so each key value is associated with one value of every column, and every column depends on the key; conversely, a set of columns that determines all columns is a superkey. A functional dependency is a constraint on every legal state of the table, asserted by the designer from the meaning of the data — for example "each drinker has one address". One pair of rows with the same X and different Y refutes it; rows that agree with it only show that the current instance is consistent with it, since a later row may break it.
A complete answer has three parts: the definition (the slides' "precisely one value of Y at any given time", or the two-row form), the key argument, and the instance-versus-rule distinction. An answer that "checks the FD on the data" misses the third.
Consider the table Employee(EmpID, EmpName, Payrate, Hours Worked, Dept#, DeptName) with primary key EmpID, where every employee works in one department and every department has one name. In which normal form is the table?
Show model answer
In 2NF but not in 3NF. The single-column key rules out partial dependencies, but EmpID → Dept# and Dept# → DeptName make DeptName transitively dependent on the key. Splitting off Department(Dept#, DeptName) and keeping Dept# in Employee as a foreign key gives 3NF.
This is the table of p. 117 ("Fixing One Fact Multiple Places", lesson 8): the two halves of the deck ask the same question. The trap is option 2 — "a fact in the wrong place" sounds partial, but with a one-column key nothing can be partial.
Which of the following statements are true? Select all that apply.
Show model answer
True: "Every table in BCNF is also in 3NF" and "A table in 1NF whose only candidate key is a single column is in 2NF". The other three are false: 3NF does not imply BCNF; a table with lists in its cells is not in 1NF; the definition given is that of a partial dependency.
A select-all question where a wrong tick may be penalised: tick only what you can justify in one line. The pair "partial versus transitive" is the most frequent confusion of this topic.
What are the goals of normalization? Using a table that stores orders, customers and products in the same rows, explain the update, insertion and deletion anomalies that normalization removes.
Show model answer
Normalization aims at a set of relational tables that are free of redundant data and can be consistently and correctly modified: it eliminates redundant data and ensures that each table only stores related data, which saves space and makes the data easier to maintain; the target is 3NF. In INVOICE(Order_ID, Product_ID, Order_Date, Customer_ID, Customer_Name, Customer_Address, Product_Description, Product_Finish, Unit_Price, Ordered_Quantity) with key (Order_ID, Product_ID): update anomaly — the customer's address is repeated on every line of every order, so a change of address must be applied to many rows or the table becomes inconsistent; insertion anomaly — a new product that nobody has ordered cannot be inserted, because Order_ID is part of the key and cannot be NULL; deletion anomaly — deleting the only order line of a product also deletes the product's description and price. Splitting the table into ORDER_LINE, PRODUCT, ORDER and CUSTOMER stores each fact once and removes all three.
The slides give the goals (pp. 121, 127) but not the anomaly names, which come from the textbooks; a complete answer gives both the goal sentence and one concrete example per anomaly. The Pine Valley invoice is the natural example to use.
Consider the restaurant ER diagram of the exam of 6 Sep 2024: Waiter (a Person, key Personal_ID, with Surname and Hiring Date) is related by Serve (1:N on both sides) to Table (key Table_ID, with Max Seats), and Table is related by Has (Table 1:1, Restaurant 1:N) to Restaurant (key Restaurant_ID, with Name). The Serve relationship has been exported to a single table:
SERVICE(Personal_ID, Table_ID, Surname, Hiring_Date, Max_Seats, Restaurant_ID, Restaurant_Name), primary key (Personal_ID, Table_ID).
(a) List the functional dependencies that follow from the ER diagram and classify each as full, partial or transitive. (b) In which normal form is SERVICE? (c) Decompose it into 3NF, marking primary and foreign keys.
Show model answer
(a) Personal_ID → Surname, Hiring_Date: partial (part of the key). Table_ID → Max_Seats, Restaurant_ID: partial; Restaurant_ID depends on Table_ID because every table belongs to exactly one restaurant. Restaurant_ID → Restaurant_Name: transitive, since the key reaches Restaurant_Name only through the non-key Restaurant_ID. No non-key column depends fully on the whole key: Serve has no attributes.
(b) 1NF (atomic values, a key), not 2NF (partial dependencies).
(c) 2NF: WAITER(Personal_ID, Surname, Hiring_Date), TABLE(Table_ID, Max_Seats, Restaurant_ID, Restaurant_Name), SERVE(Personal_ID*, Table_ID*). TABLE still has a transitive dependency, so for 3NF split it: TABLE(Table_ID, Max_Seats, Restaurant_ID*) and RESTAURANT(Restaurant_ID, Restaurant_Name). Final schema: WAITER, SERVE, TABLE, RESTAURANT; underlined = primary key, * = foreign key.
The scenario is the restaurant paper's ER; the table is made up for this lesson. A useful self-check: the result equals what the ER-to-table recipe of lesson 8 gives directly — Serve, many-to-many, becomes a separate table with a composite key; Has, with Table on the (1,1) side, posts Restaurant_ID into TABLE.
State the definition of Boyce–Codd normal form. How does it differ from third normal form, and why do the lecture slides call it "3.5NF"? Give an example of a table that is in 3NF but not in BCNF.
Show model answer
A table R is in BCNF if, for every functional dependency X → Y, either the dependency is trivial (Y ⊆ X) or X is a superkey of R. 3NF requires, for every non-trivial X → A, that X is a superkey or that A belongs to some candidate key; BCNF drops this second alternative, so it is slightly stronger, and every BCNF table is in 3NF — hence "3.5NF", between 3NF and 4NF. The two differ only when a table has overlapping candidate keys. Example: TEACHING(Student, Course, Teacher) with {Student, Course} → Teacher and Teacher → Course; the candidate keys are {Student, Course} and {Student, Teacher}. Teacher → Course violates BCNF because Teacher is not a superkey, but satisfies 3NF because Course is part of a candidate key. Decomposing into (Teacher, Course) and (Student, Teacher) reaches BCNF but loses the dependency {Student, Course} → Teacher, which is why 3NF is often the practical target.
The definition is on p. 139 almost word for word; the example and the dependency-preservation argument come from the textbooks the slides cite on p. 140. The example shows that you understand the difference instead of reciting it.
Check yourself
A table holds 10,000 rows, and any two of them with the same value of X also have the same value of Y. What can you conclude about X → Y?
In the 1NF invoice with key (Order_ID, Product_ID), what kind of dependency is Customer_ID → Customer_Name?
A table is in 1NF, and its only candidate key is a single column. Which statement is then guaranteed?
On the slide's five rows, which troubles of the 1NF invoice are already gone after the 2NF split of p. 134? Select all that apply.
The rule behind it: an anomaly disappears at the step that turns its arrow into a table — partial arrows at 2NF, the transitive arrow at 3NF.
Why does the 3NF split keep Customer_ID in ORDER instead of moving it entirely into CUSTOMER?
A table is in 3NF but not in BCNF. What must be true of it?
A MongoDB collection stores each order as one document with an array of its lines. In the slides' terms, this document is…
Key take-aways
- Normalization is "a two step process": remove repeating groups (1NF), then remove duplicated data by splitting tables along functional dependencies, until every non-key column depends on the key, the whole key and nothing but the key; the slides' target is 3NF (p. 121).
- A functional dependency X → Y means each value of X goes with precisely one value of Y at any given time. It is a rule from the meaning of the data: rows can refute it, never prove it. The key determines every column, and the closure \(X^+\) tells which dependencies follow from the given ones.
- 1NF means atomic values and a key; a table with sets in its cells "is NOT a relation". 1NF says nothing about repetition: the flat invoice of p. 130 is a relation "but not a well-structured one".
- Where an arrow starts decides its kind: at part of a composite key it is partial (2NF removes it), at a non-key column it is transitive (3NF removes it). The repair is the same both times — the determinant becomes the key of a new table and stays behind as a foreign key — and it turns the invoice into ORDER_LINE, PRODUCT, ORDER and CUSTOMER.
- BCNF ("3.5NF") demands that every determinant be a superkey. It differs from 3NF only with overlapping candidate keys, where reaching it can lose a dependency; 4NF and 5NF are beyond the course.
- A good ER diagram translated with lesson 8's recipe gives 3NF tables directly. NoSQL systems denormalise on purpose and pay for reads without joins with update anomalies — the normal forms say which ones.
What to watch and read
-
Learn Database Normalization — 1NF, 2NF, 3NF, 4NF, 5NF
Decomplexify
One table broken and repaired form by form, with the anomaly each form removes; its pictures of a partial dependency (an attribute hanging off half a key) and a transitive one are the drawings of p. 133. Stop after 3NF for the exam, watch 4NF and 5NF for the ladder of p. 138.
-
Functional Dependencies Checker
arjo129 (GitHub)
Type the dependencies of p. 133 or of the Drinkers table and ask for attribute closures, candidate keys and the 2NF, 3NF and BCNF checks — a second opinion on your own answers to the exam questions above.
-
Database Systems, chapter 8 "Normalization" (slides)
Atzeni, Ceri, Paraboschi, Torlone
The first reference the course prints on p. 140, free from the authors: the formal BCNF and 3NF definitions, and an example where BCNF cannot be reached without losing a dependency — the rigorous version of section 5.
-
Database normalization
Wikipedia
The table of all the normal forms with the years they were defined, from 1NF (1970) to 6NF (2003) — the full answer to the "5 normal forms" of p. 120.