skip to content

Normalization Theory

Functional dependencies and the ladder of normal forms that tell you when a table should be split — and when to deliberately walk it back. Interviewers use 'explain 3NF vs BCNF' as a fast litmus for whether you understand why schemas are shaped the way they are.

part ofRelational database conceptsoverview, primer and where to startread it →
on this pageshow

questions

page 1 of 2

What does it mean for a table to be in first normal form, and what exactly does the requirement that values be 'atomic' rule out?

level: juniorimportance: must knowfreq 70%

answer

  1. one value per cell, one row per fact
  2. no phone1/phone2/phone3
  3. no duplicate rows — declare a key
  4. atomic = database never parses it
  5. fix = child table + foreign key

basics

~20 s

A table is in first normal form when every column holds one single value of its declared type — no lists, no nested structures, no repeating groups such as phone1/phone2/phone3 — and every row is uniquely identifiable, normally by a primary key.

solid answer

~60 s

First normal form is the entry condition for the relational model. It requires that: - **Every cell holds a single value** of the column's domain, not a list, a set, or a nested record. `tags = 'sql,indexing,oltp'` breaks this because the application must split the string to use it. - **There are no repeating groups** — no `phone1`, `phone2`, `phone3` encoding a one-to-many relationship across columns. - **Every row is distinguishable**: no duplicate rows, which in practice means declaring a primary key. Row and column order carry no meaning. "Atomic" is defined relative to how the database is asked to use the value, not by any absolute notion of indivisibility. A date is one value even though it contains a year; a full address in one column is a violation the moment you need to filter or group by city. The test is: does anything have to decompose this value inside a query or in application code to do its job? The fix is always the same shape — move the repeating part into its own table, one row per value, joined by a foreign key.

code

sql · 27 lines
sql
-- violates 1NF: list in a column, repeating group, no key
CREATE TABLE customer_bad (
  name    VARCHAR(100),
  tags    VARCHAR(200),   -- 'vip,newsletter'
  phone1  VARCHAR(20),
  phone2  VARCHAR(20),
  phone3  VARCHAR(20)
);

-- 1NF
CREATE TABLE customer (
  id    BIGINT PRIMARY KEY,
  name  VARCHAR(100) NOT NULL
);

CREATE TABLE customer_tag (
  customer_id BIGINT NOT NULL REFERENCES customer(id),
  tag         VARCHAR(50) NOT NULL,
  PRIMARY KEY (customer_id, tag)
);

CREATE TABLE customer_phone (
  id          BIGINT PRIMARY KEY,
  customer_id BIGINT NOT NULL REFERENCES customer(id),
  phone       VARCHAR(20) NOT NULL,
  kind        VARCHAR(10) NOT NULL
);

go deeper

for a junior

State the three requirements — single-valued cells, no repeating groups, uniquely identifiable rows — and give the comma-separated-list example.

for a middle

Explain that atomicity is relative to how the data is queried, and describe the child-table fix including an explicit position column when order matters.

for a senior

Discuss the concrete costs — lost foreign keys, unusable indexes, lost updates on read-modify-write of a list — and when a document column is a considered trade-off rather than an accident.

for a principal

Frame 1NF as the precondition that makes the rest of normalization and the engine's integrity machinery applicable at all, and describe how you decide per-attribute whether the database needs to see inside a value.

## Where 1NF sits Normalization is a series of conditions that progressively remove redundancy from a schema. 1NF is the first and most basic: it is not really about redundancy at all, it is about a table being a *relation* in the first place. The higher forms (2NF, 3NF, BCNF) assume you already have a well-formed relation and then talk about dependencies between attributes. If a table is not in 1NF, those questions cannot even be asked. ## The three requirements **1. Single-valued columns.** Each cell contains one value drawn from the column's domain. Violations look like: - `tags VARCHAR(200)` holding `'sql,indexing,oltp'` — a list crammed into a string. - `skills` holding a serialized array or a nested document that the application unpacks. - `full_name` holding `'Ada Lovelace'` in a system where you must sort by surname. **2. No repeating groups.** The other way people encode a one-to-many relationship is horizontally: `phone1`, `phone2`, `phone3`, or `item1_sku`, `item1_qty`, `item2_sku`, `item2_qty`. Structurally this is the same violation turned sideways — the column set encodes a collection. **3. Row uniqueness.** A relation is a *set* of tuples, so duplicates are meaningless. SQL tables permit duplicates, so you get this property only by declaring a primary key (or at minimum a unique constraint on the business identity). Without one, two identical rows are indistinguishable and you cannot address one of them. A fourth, often forgotten point: **order carries no information**. You may not rely on "the third row" or "the first column"; if position means something (priority, sequence), that meaning must become a column. ## What "atomic" really means This is the part candidates get wrong. There is no absolute test for indivisibility — every string can be split, every number has digits. `1996-04-12` is a date, and nobody calls it a violation even though it contains a month. A JPEG in a BLOB is one value even though it has internal structure. The useful, engineering definition: **a value is atomic with respect to a schema if the database is never asked to look inside it.** Atomicity is therefore a property of the pairing between the data and its use: - Storing a postcode inside `address_line` is fine if the system only ever prints the address on a label. - The same design is a 1NF violation the day someone needs "all customers in postcode area SW1", because now a query must decompose the value. The practical interview test is: *does any query, index, constraint or piece of application code have to parse this column to do its job?* If yes, it is not atomic for this schema. ## Why the violations hurt Once a column holds a list, the database stops being able to help you: - **No integrity.** You cannot point a foreign key at an element inside a string, so nothing stops `'sql,sqll,SQL '` from accumulating. - **No useful indexing.** A B-tree indexes the whole string. Finding rows containing one tag becomes a wildcard scan, and the wildcard also matches substrings — searching for `sql` matches `nosql`. - **Awkward everything.** Counting per tag, joining to a tag description, adding or removing one element — each becomes string surgery instead of a row insert or delete. - **Concurrency hazards.** Two sessions adding a different tag both read-modify-write the same string; one update is lost. Two rows in a child table would not have collided. - **Type erasure.** A comma-joined list of numbers is text; comparisons and range predicates no longer behave numerically. Repeating-group columns fail differently but just as badly: the arity is fixed and arbitrary (why three phones?), most cells are NULL, adding a fourth means DDL and a code change, and any search has to check every column. ## The canonical fix Both violations resolve into the same move: **extract the repeating part into its own table, one row per value, with a foreign key back to the parent.** `customer(id, name)` plus `customer_phone(customer_id, phone, kind)`. Each phone is now a first-class row that can be constrained, indexed, counted, joined and validated. If ordering matters, add an explicit `position` column, because row order in a table means nothing. ## Nuance worth voicing Modern engines offer array and document column types, and a well-scoped document column can be a defensible engineering choice even though it is formally not 1NF. The test is the same one as always: if the database has to reach inside the value to filter, join or enforce integrity, you have paid for a violation without the benefit. Say the trade-off out loud rather than pretending array columns do not exist — but be able to state that strictly they place the table outside 1NF.

  • Is storing a full postal address in a single column a 1NF violation?
    It depends entirely on how the system uses it. If the address is only ever printed or displayed as a block, the whole string is one atomic value and the design is fine. The moment a requirement appears to filter by city, group by country, or validate a postcode, the database has to reach inside the value, and it becomes a violation that should be split into separate columns.
  • Does the relational model require a primary key, and how does that relate to 1NF?
    A relation is a set of tuples, so duplicates cannot exist and every tuple is identifiable — that is where row uniqueness in 1NF comes from. SQL tables are bags rather than sets and do permit duplicate rows, so you must recover the property by declaring a primary key. Without one, two identical rows cannot be told apart and an UPDATE or DELETE cannot target just one of them.

1NF is the difference between a spreadsheet cell containing 'milk, eggs, bread' and three separate rows on a shopping list — only the second lets you tick one item off, count them, or sort them.

saying these in an interview costs you the question

  • Defining atomic as 'cannot be divided at all', which would make dates and strings violations
  • Believing 1NF is about eliminating redundancy — that is 2NF and 3NF; 1NF is about being a well-formed relation
  • Thinking phone1/phone2/phone3 is fine because each cell holds a single value
  • Claiming a table without a primary key can still be in 1NF as long as its columns are atomic
  • Assuming any use of a JSON or array column is automatically acceptable relational design

context

open as a page

Given a table ORDER_LINE(order_id, product_id, quantity, product_name, order_date) whose primary key is (order_id, product_id), does it satisfy Second Normal Form? Walk through your reasoning and the fix.

level: juniorimportance: must knowfreq 62%

basics

~10 s

No. product_name depends only on product_id and order_date only on order_id, both parts of the composite key, so both are partial dependencies. Split into ORDER(order_id, order_date), PRODUCT(product_id, product_name), and ORDER_LINE(order_id, product_id, quantity).

open as a page

You are shown EMPLOYEE(emp_id, emp_name, dept_id, dept_name, dept_location) with primary key emp_id. Is it in Third Normal Form, and how would you change it?

level: juniorimportance: must knowfreq 66%

basics

~10 s

No. dept_id determines dept_name and dept_location, so both depend on the key only through a non-key attribute. Split out DEPARTMENT(dept_id, dept_name, dept_location) and leave EMPLOYEE(emp_id, emp_name, dept_id) with a foreign key.

open as a page

Explain insertion, update, and deletion anomalies in a table that repeats the same fact across many rows, and give a concrete example of each.

level: juniorimportance: must knowfreq 65%

basics

~20 s

Repeating a fact means you cannot record it without an unrelated row (insertion anomaly), must rewrite every copy to change it (update anomaly, with drift if partial), and lose it when the last carrier row is deleted (deletion anomaly). Move the fact to its own table with a foreign key.

open as a page

What does Boyce-Codd Normal Form (BCNF) require of a table's functional dependencies, and what is a determinant?

level: juniorimportance: must knowfreq 50%

basics

~10 s

BCNF requires that for every non-trivial functional dependency X to Y in a table, X is a superkey. The determinant is X, the left-hand side. Nothing but a superkey may determine anything.

open as a page

What does it mean to denormalize a transactional database schema, and what do you gain and give up by doing it?

level: juniorimportance: must knowfreq 58%

basics

~20 s

Denormalizing means deliberately storing redundant data — a copied column, a precomputed count, a summary table — so reads avoid joins or aggregation. You gain read speed and simpler queries; you give up a single source of truth, so every write path must keep the copies in step or they drift.

open as a page

In relational schema design, what does it mean to say that a functional dependency X -> Y holds on a table, and how do you decide whether one actually holds for a given set of columns?

level: juniorimportance: must knowfreq 70%

basics

~20 s

X -> Y means any two rows that agree on every column of X must also agree on Y: X determines Y. It is a rule about all legal data, so sample rows can disprove it but never prove it.

open as a page

Explain the difference between a superkey, a candidate key and a primary key in the relational model, and what makes an attribute 'prime'.

level: juniorimportance: must knowfreq 65%

basics

~20 s

A superkey is any column set that determines all other columns. A candidate key is a minimal superkey - remove any column and it stops being one. The primary key is the candidate key you designate. Prime attributes are those inside some candidate key.

open as a page

A table stores each row's tags in one VARCHAR column as a comma-separated list such as 'sql,indexing,oltp'. What concretely breaks as the system grows, and what does the normalized design look like?

level: middleimportance: must knowfreq 60%

basics

~20 s

You lose foreign keys, useful indexing and typing: substring matching finds false hits, per-tag counts need string surgery, adding one tag rewrites the whole string so concurrent updates lose each other, and typos accumulate. Fix: a child table with one row per (entity, tag).

open as a page

What does Second Normal Form (2NF) require of a table, and what exactly is a partial dependency?

level: middleimportance: must knowfreq 70%

basics

~20 s

2NF means the table is in 1NF and no non-key attribute depends on only part of a composite candidate key. That part-of-the-key dependency is a partial dependency; remove it by moving the attribute into a table keyed by that part.

open as a page

What does Third Normal Form (3NF) require, and what is a transitive dependency?

level: middleimportance: must knowfreq 76%

basics

~20 s

3NF means the table is in 2NF and no non-key attribute is determined by another non-key attribute. That indirect chain, key determines A and A determines B, is a transitive dependency; move A and B into their own table keyed by A.

open as a page

What makes a decomposition of one table into two tables lossless-join, and what goes wrong when that condition does not hold?

level: middleimportance: must knowfreq 40%

basics

~20 s

A split is lossless when the natural join of the two pieces returns exactly the original rows. The condition: the shared columns must functionally determine all of at least one piece, meaning they form a superkey there. Otherwise the join invents spurious rows that were never in the original.

open as a page

Give a table that is in Third Normal Form but violates Boyce-Codd Normal Form, and explain what structural feature makes that possible.

level: middleimportance: must knowfreq 42%

basics

~20 s

Take (student, course, teacher) where each course has one teacher and a student takes a course from one teacher. Candidate keys are (student, course) and (student, teacher). The dependency course to teacher has a non-superkey determinant, but teacher is part of a candidate key, so 3NF permits it and BCNF does not.

open as a page

You add a stored comment_count column to a posts table instead of counting child rows. What are the ways to keep that counter correct, and how do they differ?

level: middleimportance: must knowfreq 45%

basics

~20 s

Three options: a database trigger on the child table, an application write inside the same transaction, or an asynchronous job. Triggers catch every write path; application code misses backfills and scripts; async jobs are cheap but stale. Always update with a relative change, and add a reconciliation query to repair drift.

open as a page

Given a set of columns X and a set of functional dependencies, how do you compute the attribute closure X+, and what design questions does that closure let you answer?

level: middleimportance: must knowfreq 55%

basics

~20 s

Start with X, then repeatedly add the right side of any dependency whose left side is already contained in the set, until nothing changes. The result X+ is everything X determines. If X+ covers all columns, X is a superkey; X+ also tests whether X -> Y is implied.

open as a page

Why is a relation whose only candidate key is a single column automatically in Second Normal Form, and what does that tell you about when to check for 2NF at all?

level: juniorimportance: should knowfreq 45%

basics

~20 s

A partial dependency means a non-key attribute depends on a proper subset of a candidate key. A one-attribute key has no non-empty proper subset, so no partial dependency can exist. Only composite candidate keys can violate 2NF.

open as a page

A table course_offering(course_id, textbook, instructor) stores one row for every combination of a course's textbooks and its instructors, so a course with 3 textbooks and 2 instructors occupies 6 rows. What problems does that shape create, and how would you restructure it?

level: juniorimportance: should knowfreq 35%

basics

~20 s

Textbooks and instructors are unrelated facts about a course, so the table is forced to store their cross product. Row counts multiply, adding one textbook costs one insert per instructor, and partial writes imply pairings that are not real. Split into two tables keyed by course_id.

open as a page

A customer table has the columns phone1, phone2 and phone3. Why is that treated as a repeating group and a first normal form violation, and what does the corrected design look like?

level: middleimportance: should knowfreq 48%

basics

~20 s

It encodes a one-to-many relationship horizontally: the limit of three is arbitrary, most cells are NULL, a fourth phone needs DDL and code changes, and any search must check all three columns. Fix: a child table with one row per phone plus a foreign key.

open as a page

First normal form also requires that every row be uniquely identifiable. What goes wrong in a table that permits exact duplicate rows and has no primary key, and how would you repair one that already exists?

level: middleimportance: should knowfreq 45%

basics

~20 s

Duplicates are indistinguishable, so you cannot update or delete just one of them, an ORM or replication cannot identify a row, and joins multiply counts silently. Repair: find the duplicate groups, decide which to keep, delete the rest, then add a primary key and a unique constraint on the business identity.

open as a page

What is a multivalued dependency in relational design, and what does Fourth Normal Form (4NF) require of a table with respect to multivalued dependencies?

level: middleimportance: should knowfreq 40%

basics

~20 s

A multivalued dependency X to Y means fixing X fixes a whole set of Y values, independently of the table's other columns. 4NF says every nontrivial multivalued dependency must have a superkey on its left side, otherwise split the table so each independent set lives on its own.

open as a page

Relational engines now offer array and document (JSON) column types that hold a whole collection in one cell. Does using one violate first normal form, and when is it nonetheless a defensible design decision?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Strictly yes: a cell holding a collection the schema must decompose is not atomic. It is defensible when the value is opaque to the database — always read and written whole with its row, never filtered per element, never joined, and never subject to a foreign key or per-element constraint.

open as a page

A teammate argues that giving every table a surrogate integer primary key removes the need to think about Second Normal Form. How do you respond, and how would you prove the redundancy is still there?

level: seniorimportance: should knowfreq 34%

basics

~20 s

A surrogate key hides the composite natural key, it does not remove the duplicated facts or their update anomalies. If the natural key is still declared unique it remains a candidate key and 2NF is still violated; prove it by counting distinct dependent values per determinant.

open as a page

State the formal definition of Third Normal Form in terms of functional dependencies, and explain why it includes the clause allowing the dependent attribute to be prime.

level: seniorimportance: should knowfreq 33%

basics

~20 s

For every non-trivial dependency X to A, 3NF requires X to be a superkey or A to be a prime attribute (part of some candidate key). The second clause is the relaxation that makes 3NF strictly weaker than BCNF and always reachable by a lossless, dependency-preserving decomposition.

open as a page

A CUSTOMER table keyed by customer_id stores street, zip_code, city and state, and the business says a zip code determines its city and state. Is that a Third Normal Form violation, and would you actually split it out?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Formally yes: zip_code is a non-key attribute determining city and state, a transitive dependency, so 3NF fails. Whether to split is a judgement call, because the assumed dependency often does not hold in real postal data and the reference table needs an owner and a refresh process.

open as a page

Most production OLTP schemas are normalized to Third Normal Form or Boyce-Codd Normal Form and no further. Why do Fourth and Fifth Normal Form rarely appear as an explicit design step, and when is it still worth checking for them?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Entity-per-table modelling with one junction table per relationship produces 4NF schemas by accident, so there is nothing left to fix. Higher forms also need semantic input no tool can derive and no constraint can enforce. Check them when you see wide attribute tables, spreadsheet imports, or multiplying row counts.

open as a page

What does it mean for a decomposition to be dependency-preserving, and what is the practical cost when a decomposition is lossless but not dependency-preserving?

level: seniorimportance: should knowfreq 25%

basics

~20 s

A decomposition is dependency-preserving when every original functional dependency can still be checked inside a single resulting table. If one spans two tables, no single-table constraint can enforce it, so every write needs a join-based check via trigger or application logic, with race conditions under concurrency.

open as a page

You inherit an orders table that stores the customer's address on every order row, and rows for the same customer now disagree with each other. How would you assess the damage and fix the design without losing information?

level: seniorimportance: should knowfreq 30%

basics

~20 s

First decide whether the column is a point-in-time snapshot of where the order shipped, which is legitimate, or a stale copy of the current address, which is a defect. Quantify the drift, pick an authoritative source, extract addresses to their own table with a foreign key, and close the write paths that let copies diverge.

open as a page

Why can decomposing a relation into Boyce-Codd Normal Form lose a functional dependency, and what do you do about it in a real schema?

level: seniorimportance: should knowfreq 26%

basics

~20 s

BCNF decomposition is always lossless-join but not always dependency-preserving: some original dependency ends up spanning two tables, so no single table's keys enforce it any more. You either accept 3NF instead, or decompose and enforce the stray dependency with a trigger, a redundant column plus a unique index, or reconciliation.

open as a page

How do you decide that a join or aggregation is expensive enough to justify permanently storing redundant data in a transactional schema?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Measure first: confirm the query is hot and that the join or aggregate dominates its plan. Exhaust cheaper fixes — indexes, especially covering ones, query rewrites, caching. Denormalize when the cost grows with data you cannot bound, the read rate greatly exceeds the write rate, and you can name a sync mechanism and a drift check.

open as a page

What are Armstrong's axioms for functional dependencies, and how do you use them to reduce a declared dependency set to a minimal (canonical) cover?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Armstrong's axioms are reflexivity, augmentation and transitivity; they are sound and complete, so everything implied can be derived from them. A minimal cover is an equivalent dependency set with single-attribute right sides, no extraneous left-side attributes and no redundant dependencies.

open as a page

showing 1–30 of 35