skip to content

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

level: middleimportance: must knowfreq 70%

answer

  1. Non-prime attribute on part of a composite key
  2. Prime = in some candidate key
  3. Single-column key means 2NF for free
  4. Order line: product name belongs to product
  5. Project out the determinant, keep the FK

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.

solid answer

~50 s

A relation is in 2NF when it is in 1NF and **no non-prime attribute is functionally dependent on a proper subset of any candidate key**. A *prime* attribute belongs to some candidate key; everything else is non-prime. A dependency of a non-prime attribute on part of a composite key is a **partial dependency**. So 2NF only has teeth when a candidate key is composite. If every candidate key is a single column there are no proper non-empty subsets, and the table is in 2NF automatically. Example: `ENROLLMENT(student_id, course_id, grade, student_name)` keyed by `(student_id, course_id)`. `grade` needs the whole key, but `student_name` depends on `student_id` alone, which is partial. That repeats the name on every enrolment row and turns a rename into a multi-row update. The fix is projection: pull `student_name` into `STUDENT(student_id, student_name)` and keep `student_id` as a foreign key. The join back is lossless because `student_id` is the key of the new table.

code

sql · 8 lines
sql
CREATE TABLE enrollment (
  student_id   INT,
  course_id    INT,
  grade        CHAR(2),
  student_name VARCHAR(100),
  course_title VARCHAR(100),
  PRIMARY KEY (student_id, course_id)
);

go deeper

for a junior

Recall the definition in one sentence, spot the classic order-line or enrolment violation, and show the split into parent tables with foreign keys.

for a middle

Use the precise wording (non-prime attribute, proper subset of a candidate key), explain why only composite keys can violate it, and name the resulting insert, update and delete anomalies.

for a senior

Check all candidate keys rather than the primary key, argue losslessness of the decomposition, and show judgement on semantics-dependent columns such as charged price versus list price.

for a principal

Frame 2NF as one diagnostic in a normalization pass toward 3NF or BCNF, and connect it to where the team accepts duplication deliberately and how integrity is then enforced.

## The vocabulary 2NF is built on A **functional dependency**, written X to Y, means any two rows that agree on the attributes in X must also agree on Y. "Order number determines order date" is a functional dependency: one order number can never carry two different dates. A **candidate key** is a minimal set of attributes that functionally determines every other attribute of the relation. Minimality matters: `(order_id, product_id)` may be a candidate key while `(order_id, product_id, quantity)` is only a superkey, because you can drop `quantity` and still determine everything. A relation can have several candidate keys; one is designated the primary key. A **prime attribute** is any attribute that appears in at least one candidate key. Every other attribute is **non-prime**. This distinction is the whole of 2NF. ## The rule itself A relation is in Second Normal Form when both hold: 1. It is in First Normal Form (atomic, single-valued attributes, no repeating groups). 2. No non-prime attribute is functionally dependent on a **proper subset** of any candidate key. A violation of clause 2 is a **partial dependency**. Note three things about the scope. First, 2NF is defined against *all* candidate keys, not only the one you picked as primary. Second, it says nothing about dependencies whose determinant is a non-key attribute; that is Third Normal Form's job. Third, it says nothing about dependencies among prime attributes. A direct corollary: if every candidate key consists of a single attribute, the only proper subset is the empty set, so no partial dependency can exist and any 1NF relation is already in 2NF. Partial dependencies are a phenomenon of composite keys only. ## Why partial dependencies hurt Take `ENROLLMENT(student_id, course_id, grade, student_name, course_title)` keyed by `(student_id, course_id)`. `student_name` depends on `student_id` alone and `course_title` on `course_id` alone. - **Redundancy.** A student's name is stored once per enrolment row. A course title is stored once per enrolled student. - **Update anomaly.** Correcting a misspelled name requires touching every row for that student. Miss one and the database now holds two contradictory names, which no key constraint prevents. - **Insertion anomaly.** You cannot record a newly created course that nobody has enrolled in, because `student_id` is part of the primary key and cannot be null. - **Deletion anomaly.** Deleting the last enrolment for a course destroys the only record of its title. All three anomalies come from storing a fact about one entity in a table whose key identifies a different, finer-grained thing. ## The decomposition For each partial dependency, project the determinant plus the attributes it determines into a new relation keyed by that determinant, and drop those attributes from the original: - `STUDENT(student_id, student_name)` - `COURSE(course_id, course_title)` - `ENROLLMENT(student_id, course_id, grade)` with foreign keys to both The decomposition is **lossless**: each new relation shares its key with the residual relation, so the natural join reconstructs the original exactly, with no spurious rows. The original facts are all still derivable; only the duplication is gone. ## A method you can run in an interview 1. Enumerate the candidate keys from the stated functional dependencies. Do not just accept the declared primary key. 2. If every candidate key is a single attribute, stop: the relation is in 2NF. 3. Otherwise, for each composite candidate key, take each proper subset and ask whether any non-prime attribute is determined by that subset alone. 4. Every yes is a partial dependency. Extract it. 5. Re-check the residual relation, then continue to 3NF. ## Judgement, not mechanics Whether a dependency is partial depends on what the attribute *means*, not on its name. In `ORDER_LINE(order_id, product_id, quantity, unit_price)`, if `unit_price` is the price actually charged on this line then it depends on the full key and stays. If it means the product's current catalogue price then it depends on `product_id` alone, is partial, and belongs in the product table. Interviewers use exactly this pair to see whether you reason about semantics or pattern-match on column names. Finally, 2NF is a stepping stone. Nobody targets 2NF as a design goal; you pass through it on the way to 3NF or Boyce-Codd Normal Form. Its value in an interview is that it names the specific defect of composite keys precisely.

  • If a table's primary key is a single column, can it still violate Second Normal Form?
    No. A partial dependency requires a non-prime attribute to depend on a proper non-empty subset of a candidate key, and a single-attribute key has no such subset. But check every candidate key, not just the primary one: a table with a single-column surrogate primary key may still have a composite natural candidate key that carries partial dependencies.
  • In ORDER_LINE(order_id, product_id, quantity, unit_price), does unit_price violate 2NF?
    It depends on the attribute's meaning. If it records the price actually charged on that line, it is determined by the full key and is fine, which is also what you want for historical accuracy on invoices. If it means the product's current list price, it is determined by product_id alone, is a partial dependency, and belongs in the product table.
  • How do you know the decomposition did not lose information?
    Each extracted relation is keyed by the determinant of the dependency you removed, and that determinant remains in the residual relation as a foreign key. Because the shared attribute is a key of one side, the natural join reproduces the original rows exactly with no spurious tuples, which is the standard lossless-join condition.

A composite key is like a seat assignment (flight number plus seat). The passenger's frequent-flyer name belongs to the passenger, not to the seat, so writing it on every boarding pass is exactly a partial dependency.

saying these in an interview costs you the question

  • Saying 2NF means "no duplicate data" or "every table has a primary key" instead of naming partial dependency on part of a composite key.
  • Checking only the declared primary key when the relation has another composite candidate key.
  • Claiming a single-column primary key table can violate 2NF.
  • Confusing a partial dependency (determinant is part of a key) with a transitive one (determinant is a non-key attribute), which is 3NF's concern.
  • Deciding from column names rather than from what the attribute actually means, for example moving a historical charged price into the product table.

context