Lesson 1.3 – Normalization and Normal Forms
Normalization & Normal Forms
Turn a messy single-table design into a clean, healthy schema by applying 1NF, 2NF, and 3NF — and learn to spot the three classic anomalies before they corrupt your data.
Learning Objectives
By the end of this lesson, you will be able to:
- Explain what normalization is and why it matters for a healthy database.
- Apply First Normal Form (1NF) by removing repeating groups and ensuring atomic values.
- Apply Second Normal Form (2NF) by removing partial dependencies on composite keys.
- Apply Third Normal Form (3NF) by removing transitive dependencies.
- Identify the three classic data anomalies: insertion, update, and deletion anomalies.
- Refactor a messy single-table design into a clean, normalized multi-table schema in T-SQL.
📚 Key Vocabulary
| Term | Definition | SchoolHub Example |
|---|---|---|
| Normalization | The process of structuring a database to reduce redundancy and prevent anomalies. | Splitting one giant StudentClasses table into Students, Classes, and Enrollments. |
| 1NF | First Normal Form — every cell holds a single atomic value; no repeating groups; each row is unique. | Replace 'Math, History, Biology' in one cell with three separate rows. |
| 2NF | Second Normal Form — already in 1NF, plus every non-key column depends on the whole primary key. | Move ClassName out of Enrollments(StudentID, ClassID) because it only depends on ClassID. |
| 3NF | Third Normal Form — already in 2NF, plus no column depends on another non-key column. | Move TeacherName out of Classes because it depends on TeacherID, not on ClassID. |
| Atomic Value | A single, indivisible value — not a list, not a multi-part string. | 'Alice' is atomic; 'Alice; Bob; Carol' is not. |
| Functional Dependency | When one column's value determines another's. We write it as A → B. |
StudentID → FirstName: knowing the ID tells you the name. |
| Partial Dependency | A non-key column depends on only part of a composite primary key. | In (StudentID, ClassID), ClassName depends only on ClassID. |
| Transitive Dependency | A non-key column depends on another non-key column. | ClassID → TeacherID → TeacherName: TeacherName depends on TeacherID, not directly on ClassID. |
| Anomaly | A problem caused by bad design: data that's wrong, missing, or inconsistent after an operation. | Deleting a student also accidentally deletes a class — that's a deletion anomaly. |
💡 Real-World Analogy
Imagine a kitchen drawer where you throw everything: scissors, batteries, spare keys, soy sauce packets, takeout menus, the manual for the toaster oven you got rid of three years ago. Need a battery? Good luck. Need scissors? Empty everything out, find them, shove it all back. Lose the scissors? You won't know until the next emergency.
Now imagine the same drawer organized into compartments — one for stationery, one for batteries, one for keys, one for sauce packets. Each thing has one home. Finding anything takes seconds. Knowing what you have is trivial. Throwing out the toaster manual doesn't risk losing the scissors.
That's normalization. The messy drawer is a denormalized table — everything stuffed into one place, with duplication and tangled dependencies. The compartments are normalized tables: each one holds one type of thing, and the relationships are made explicit through keys.
🧱 Concept Explanation
The messy table we're starting from
Suppose someone built SchoolHub as a single table. It records every student's enrollment, the class they're in, who teaches it, and the teacher's email — all in one row:
This table breaks all three normal forms. Before we fix it, let's see why bad design causes real-world damage.
The three classic anomalies
You want to add a new teacher who isn't yet teaching any class. There's nowhere to put them — every row requires a student. The data can't be inserted at all.
Mr. Smith changes his email. You have to update every row where he appears. Miss one, and your data is now inconsistent — half the rows have the new email, half have the old.
Bob (the only Math student) graduates. You delete his row. Now there's no record at all that Math exists or that Mr. Smith teaches it. Deleting one fact accidentally erased others.
Normalization eliminates all three by giving every distinct fact its own home.
Step 1 — First Normal Form (1NF)
The 1NF rule: every cell holds a single, atomic value. No lists. No repeating groups. No "multi-value" cells.
Look at Alice's row: 'Math, History' is two values stuffed into one cell. That breaks 1NF. So does '201, 305' in the Room column. Fix it by splitting the rows so each cell holds exactly one value:
The composite primary key is now (StudentID, ClassName). But notice: Alice's name still appears twice, and so does "Lee" the teacher. We've fixed atomicity, but redundancy is alive and well. On to 2NF.
Step 2 — Second Normal Form (2NF)
The 2NF rule: you're in 1NF and every non-key column depends on the whole primary key — not just part of it.
Our composite key is (StudentID, ClassName). Let's check each non-key column:
FirstName,LastName,GradeLevel— depend only onStudentID. Partial dependency.TeacherName,Room,TeacherEmail— depend only onClassName. Partial dependency.
To reach 2NF, we move each partial dependency into its own table:
Better. But the Classes table still has a problem hiding inside it.
Step 3 — Third Normal Form (3NF)
The 3NF rule: you're in 2NF and no non-key column depends on another non-key column.
Look at the Classes table. The primary key is ClassName. But:
TeacherEmaildoesn't really depend on the class — it depends onTeacherName.- If Mr. Smith teaches Math and Algebra, his email will be repeated in both rows. Transitive dependency.
The fix is to give teachers their own table. Introduce a TeacherID in Teachers and reference it from Classes. While we're at it, give classes their own ID too — and replace ClassName in Enrollments with the new ClassID:
Now every fact lives in exactly one place. Change Mr. Smith's email? Update one row. Add a teacher who's not yet teaching anything? Just insert into Teachers. Delete Bob? Math still exists in Classes.
Quick recap of all three forms
| Form | Rule | Fix It By... |
|---|---|---|
| 1NF | Atomic values, no repeating groups. | Splitting multi-value cells into separate rows. |
| 2NF | 1NF + no partial dependencies on a composite PK. | Moving partially dependent columns into their own table. |
| 3NF | 2NF + no transitive dependencies (non-key → non-key). | Extracting groups of columns that depend on each other into a new table linked by ID. |
✍️ Best Practices
Every fact (a teacher's email, a class's room) lives in exactly one row of exactly one table. If you have it in two places, you'll eventually have it wrong in one.
For schoolwork, business apps, and certification — 3NF is the standard target. Go higher only when you have a clear reason.
Start with 1NF, then 2NF, then 3NF. Each pass is small and clear. Don't try to leap to 3NF in one go.
Ask: "If a teacher changes their email, how many rows do I update?" If the answer is more than one, you're not normalized enough.
Columns like 'Math, Bio, History' or 'Mon/Wed/Fri' are violating 1NF in disguise. Split them.
After normalization you'll have more tables and more JOINs — that's normal. Foreign keys make those joins safe.
🧪 Hands-On Practice
Spot the Normal Form Violations
1. Which Normal Form is Violated?
For each table below, decide which normal form is violated (1NF, 2NF, or 3NF) and explain why in one sentence.
(a)
(b) Composite PK is (StudentID, ClassID):
(c)
2. Anomaly Spotter
Using the messy denormalized table from the concept section, describe one insertion, one update, and one deletion anomaly in your own words. Use specific SchoolHub data.
3. Normalize It
Take this single-table design and walk it through 1NF → 2NF → 3NF on paper. List the final tables, their columns, and which column is the PK or FK.
4. Functional Dependency Drill
Write the functional dependencies you see in this list of columns, using A → B notation:
StudentID,FirstName,LastName,GradeLevel,GradeLevelDescription
(Hint: "GradeLevel 10" always corresponds to "Sophomore". What does GradeLevelDescription depend on?)
💻 Coding Lab — Activity 1.3
Refactor a Messy Table into 3NF
You're going to take a single denormalized table and refactor it into a clean 3NF schema in T-SQL. Then you'll prove the new schema works by running a JOIN that reconstructs the original information.
- Open the Coding Lab and create a new file
lesson1_3.sql. - Build the denormalized starting table to see the problem first-hand.
- Drop it and rebuild as three normalized tables with proper PKs and FKs.
- Insert sample data into all three tables.
- Run a 3-table
INNER JOINthat recreates the original combined view. - Save your file as lesson1_3_(FirstName_LastName).sql.
Teachers, not five times. To change his email, you update one row. No anomalies. That's the entire point of normalization.
🔁 Bonus Challenge
- Update Smith's email to
'jsmith@school.edu'with a singleUPDATE Teachers ...statement. Re-run the join. All Smith rows update at once! - Insert a fourth teacher who isn't yet teaching any class. Easy in the normalized schema; impossible in the original.
- Delete Bob from
Students(after removing his enrollment). Math still exists, Smith still exists. No data lost.
✅ Self-Check
StudentClasses_Bad table and saw the redundancy first-hand.Teachers, Students, Classes, and Enrollments in T-SQL.IDENTITY PK (or composite PK for Enrollments) and the correct FOREIGN KEY constraints.INNER JOIN returned the 5-row combined view.🎤 Questions to Think About
Discuss with your class or jot down your answers:
- Why do you think normalization is so often skipped by beginners — even though the rules are simple?
- Can you think of a real situation where you might intentionally denormalize a table (store some redundant data on purpose)? What's the trade-off?
- How does the foreign key constraint protect you when working in a 3NF schema? What would go wrong without it?
- If your school's report card system stored teacher names in 1000 enrollment rows and a teacher changed names, how many updates would the system have to do? What if it stored only
TeacherIDs? - Which of the three anomalies (insertion, update, deletion) do you think is the most dangerous in practice, and why?
