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.
answer
- X superkey OR A prime
- Drop clause 2 and you get BCNF
- Prime = in some candidate key, not the primary key
- zip to city: city is prime, so 3NF holds
- 3NF synthesis: lossless AND dependency preserving
basics
~20 sFor 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.
solid answer
~50 sFormally: a relation R is in 3NF if for every non-trivial functional dependency X to A that holds in R, either **X is a superkey of R**, or **A is a prime attribute**, meaning A belongs to at least one candidate key. The first clause alone is Boyce-Codd Normal Form. The second clause is a deliberate relaxation, and it exists because BCNF is not always achievable without giving something up. The standard illustration is `ADDRESS(street, city, zip)` with candidate keys `(street, city)` and `(street, zip)`. The dependency `zip` to `city` has a non-superkey determinant, so BCNF fails. But `city` is prime, so 3NF holds. Decomposing to satisfy BCNF would put `zip` and `city` in one relation and `street` with `zip` in another, and the dependency `(street, city)` to `zip` could then no longer be enforced by any single relation's keys. So 3NF trades a small amount of residual redundancy for a guarantee: every schema has a lossless, dependency-preserving 3NF decomposition. BCNF has no such guarantee.
code
text · 9 linesFDs: (street, city) -> zip
zip -> city
Candidate keys: (street, city), (street, zip)
Prime attrs: street, city, zip
Test zip -> city
clause 1: is zip a superkey? no (does not determine street)
clause 2: is city prime? yes (in key (street, city))
=> satisfies 3NF, violates BCNFgo deeper
Recall the two clauses and that prime means the attribute appears in some candidate key; the informal transitive-dependency phrasing is acceptable at this level.
Apply the definition mechanically after enumerating candidate keys, and give an example where the prime clause changes the verdict.
Explain dependency preservation, present the address counterexample, and state the guarantee that a lossless dependency-preserving 3NF decomposition always exists.
Turn it into a policy question: when the residual redundancy 3NF tolerates is acceptable, when to push to BCNF and move enforcement out of the schema, and what that costs operationally.
## The definition, precisely Let R be a relation with a set F of functional dependencies. R is in **Third Normal Form** if, for every non-trivial dependency X to A in F (non-trivial meaning A is not contained in X), at least one holds: 1. **X is a superkey of R** (X functionally determines all attributes of R), or 2. **A is a prime attribute** (A belongs to at least one candidate key of R). Most textbook statements decompose the right-hand side to a single attribute, which is why the clause reads "A is prime" rather than "A is a set of prime attributes". This formal version is equivalent to the informal one, that no non-prime attribute is transitively dependent on a candidate key, but it is much easier to apply mechanically: enumerate the candidate keys, then test every dependency against the two clauses. ## Why clause 2 exists Drop clause 2 and you get **Boyce-Codd Normal Form**: every non-trivial dependency must have a superkey determinant. BCNF is cleaner conceptually and removes more redundancy. The price is that a lossless BCNF decomposition may fail to be **dependency preserving**, meaning some original dependency can no longer be enforced by checking keys within a single resulting relation. Enforcing it would require a join at every write, which no engine does with a declarative constraint. The classical example: `ADDRESS(street, city, zip)` under the simplifying assumptions that a zip code lies in exactly one city, and that street plus city identifies a zip. - Dependencies: `(street, city)` to `zip`, and `zip` to `city`. - Candidate keys: `(street, city)` and `(street, zip)`. - Prime attributes: `street`, `city`, `zip`. Every attribute is prime here. Test `zip` to `city`. Is `zip` a superkey? No, it does not determine `street`. Is `city` prime? Yes, it is in the key `(street, city)`. Clause 2 rescues it, so the relation is in 3NF but not in BCNF. To reach BCNF you would decompose into `ZIP_CITY(zip, city)` and `STREET_ZIP(street, zip)`. That is lossless, but the dependency `(street, city)` to `zip` now spans both relations: neither one can enforce it with a key constraint, so two rows could assert different zips for the same street and city without any single relation being violated. You lost a real business rule from the declarative schema. ## The guarantee 3NF buys There is a synthesis algorithm (from a minimal, or canonical, cover of the dependency set) that produces, for any relation schema, a decomposition that is simultaneously **in 3NF**, **lossless-join**, and **dependency-preserving**. Sketch: compute a minimal cover of F; create one relation per dependency in the cover, combining dependencies with the same determinant; if no resulting relation contains a candidate key of the original, add one relation consisting of a candidate key. The last step secures losslessness; one relation per cover dependency secures preservation. BCNF has only a lossless-join guarantee. A dependency-preserving BCNF decomposition does not always exist, and the address example above is a proof by counterexample. That asymmetry is the entire practical reason 3NF is the normal form named in design standards and interview answers, while BCNF is treated as "go further when it is free". ## Applying the definition in an interview 1. Derive the candidate keys from the dependency set, using attribute closure. Do not accept the declared primary key. 2. Mark every attribute appearing in any candidate key as prime. 3. For each non-trivial dependency, test clause 1, then clause 2. A dependency failing both is a violation and names the decomposition you need. This mechanical procedure is more reliable under pressure than hunting for chains, because chains are easy to miss when there are several candidate keys. ## The residual redundancy 3NF tolerates Be honest about the cost. Because clause 2 permits a non-superkey to determine a prime attribute, a 3NF relation can still repeat data. In `ADDRESS`, the fact "zip 10001 is in New York" is stored on every street row with that zip, and an update anomaly is possible: a partial update can leave two cities for one zip. 3NF does not stop that; only BCNF does, at the cost of the lost dependency. The design judgement is therefore explicit rather than automatic. If the tolerated dependency is over a stable, small domain such as zip codes, the residual redundancy is cheap and you keep 3NF plus the declarative constraint. If it is over volatile data with frequent updates, you may prefer BCNF and enforce the lost dependency in application logic or a trigger, accepting that the enforcement is no longer declarative. ## Common confusions - "Prime" means part of *some* candidate key, not part of the primary key. With multiple candidate keys the prime set is larger than people expect, and that changes the verdict. - Trivial dependencies, where the right side is contained in the left, are excluded; otherwise every relation would fail. - 3NF is defined over all candidate keys, so a relation can pass with respect to one key and fail with respect to another only if you applied the definition wrongly; the quantifier is over dependencies, not keys.
- What exactly does dependency preservation mean, and why do you care?A decomposition preserves dependencies when every functional dependency of the original can be enforced by checking constraints within a single resulting relation, with no join required. It matters because engines enforce keys and unique constraints per table; a dependency spanning two tables can only be checked by a query at write time, so it degrades from a declarative guarantee to application discipline that eventually gets bypassed.
- Give a relation that is in 3NF but not in BCNF and say where the residual redundancy sits.ADDRESS(street, city, zip) with (street, city) to zip and zip to city. The dependency zip to city has a non-superkey determinant, so BCNF fails, but city is prime so 3NF holds. The redundancy is that the zip-to-city mapping is repeated on every street row sharing that zip, allowing a partial update to leave two cities for one zip.
- How do you find the candidate keys before applying the definition?Use attribute closure. Start from attributes that never appear on the right-hand side of any dependency, since they must be in every key, compute the closure of candidate sets under the dependency set, and keep the minimal sets whose closure is all attributes. Enumerating all candidate keys matters because both the superkey test and the prime test depend on the full set.
saying these in an interview costs you the question
- Stating only the superkey clause, which defines BCNF rather than 3NF.
- Reading "prime" as "part of the primary key" instead of part of any candidate key.
- Claiming BCNF is always strictly better and should always be the target.
- Asserting that every schema has a dependency-preserving BCNF decomposition.
- Forgetting to exclude trivial dependencies when applying the test.