Why Redundant Data Causes Real Problems
Even after correctly identifying entities, attributes, and relationships as discussed earlier in this series, a table's internal structure can still allow the same piece of information to be stored in multiple places, creating three specific kinds of problems collectively called Anomalies.
Problematic table mixing multiple concepts:
| order_id | product_name | customer_name | customer_email |
|----------|---------------|----------------|-------------------|
| 1 | Widget | Alice Smith | [email protected] |
| 2 | Gadget | Alice Smith | [email protected] |
Update Anomaly: changing Alice's email requires
updating it in every row where she appears
Insertion Anomaly: cannot record a new customer's
information until they place their first order
Deletion Anomaly: deleting Alice's only order
accidentally erases her contact information entirelyNormalization is a formal set of rules, organized into progressive stages called Normal Forms, designed specifically to restructure tables so these anomalies become structurally impossible.
First Normal Form (1NF): Atomic Values Only
A table satisfies First Normal Form when every column holds a single, atomic value — no repeating groups and no multiple values crammed into one field.
Violates 1NF:
| book_id | title | authors |
|---------|------------|---------------------------|
| 1 | Deep Work | Cal Newport |
| 2 | Sapiens | Yuval Harari, Dan Editor |
Satisfies 1NF (using the junction table approach
discussed earlier in this series for the many-to-many
relationship between books and authors):
books: book_id, title
authors: author_id, name
book_authors: book_id, author_idThis directly connects to the multi-valued attribute problem discussed earlier in this series regarding entity design: any attempt to store multiple values in a single column violates 1NF and points toward the need for a separate related table.
Second Normal Form (2NF): No Partial Dependencies
Second Normal Form applies specifically to tables with a composite primary key (a key made of multiple columns), and requires that every non-key column depend on the entire key, not just part of it.
Violates 2NF:
| student_id | course_id | grade | course_name |
|------------|-----------|-------|--------------|
Primary key: (student_id, course_id)
Problem: course_name depends only on course_id,
not on the full composite key —
a "Partial Dependency"
Satisfies 2NF (split into two tables):
enrollments: student_id, course_id, grade
courses: course_id, course_nameThe course_name column was being repeated for every student enrolled in that course, wasting space and creating an update anomaly identical in structure to the customer email problem shown earlier. Separating it into its own table, keyed only by course_id, eliminates the redundancy entirely.
Third Normal Form (3NF): No Transitive Dependencies
Third Normal Form requires that non-key columns depend only on the primary key, not on other non-key columns — eliminating what is called a Transitive Dependency.
Violates 3NF:
| employee_id | department_id | department_name |
|-------------|----------------|-------------------|
Problem: department_name depends on department_id,
which itself is a non-key column —
a transitive dependency through department_id,
not a direct dependency on employee_id
Satisfies 3NF (split into two tables):
employees: employee_id, department_id
departments: department_id, department_nameWithout this split, updating a department's name would require updating it in every row of every employee assigned to that department — the exact same update anomaly pattern seen throughout this article, now resolved by ensuring department name lives in exactly one place.
Boyce-Codd Normal Form (BCNF): A Stricter Refinement
BCNF tightens 3NF by requiring that for every meaningful dependency between columns, the column on the determining side must be a candidate key (a column or set of columns capable of uniquely identifying a row). Most 3NF tables already satisfy BCNF, but certain tables with overlapping candidate keys can satisfy 3NF while still containing subtle redundancy that BCNF catches.
A table can satisfy 3NF yet still violate BCNF
in cases involving multiple overlapping candidate keys
— a relatively rare but important edge case where
a functional dependency exists whose determining
column is not itself a full candidate keyIn practice, most real-world database designs stop at 3NF, since BCNF violations are uncommon and the remaining redundancy they catch is usually minor compared to the anomalies already eliminated by reaching 3NF.
The Practical Trade-Off: Normalization Versus Performance
Full normalization eliminates redundancy and the anomalies it causes, but it comes at a cost: highly normalized data is split across many small tables, meaning even simple queries often require several JOINs, discussed earlier in this series, to reassemble a complete picture, which can slow down read-heavy workloads.
Denormalization trade-off example:
A fully normalized design might require joining
5 tables to display a single order confirmation page
A deliberately denormalized design might duplicate
a small amount of data (like a customer's name)
directly into the orders table, accepting some
redundancy risk in exchange for faster readsDenormalization — deliberately reintroducing some redundancy after normalizing — is a legitimate, common practice for performance-critical parts of a system, but it should always be a conscious trade-off made after understanding the anomalies being reintroduced, not a shortcut taken to avoid learning proper normalization in the first place.
Why Understanding Normalization Rules Matters
Normalization provides a rigorous, checkable methodology for catching design flaws that might otherwise only surface as confusing data bugs months or years after a database goes into production. Even in situations where deliberate denormalization is ultimately the right performance trade-off, understanding exactly which normalization rule is being relaxed, and exactly which anomaly risk is being deliberately accepted, is what separates an informed engineering trade-off from an accidental design flaw.