What does Boyce-Codd Normal Form (BCNF) require of a table's functional dependencies, and what is a determinant?
answer
- every determinant is a superkey
- non-trivial X -> Y, X must be superkey
- non-superkey determinant = repeated fact
- two-column table is always BCNF
- lossless split: X plus closure of X
basics
~10 sBCNF 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.
solid answer
~60 sA functional dependency X -> Y means any two rows agreeing on columns X must agree on Y. The left side X is the determinant. A superkey is a column set that determines every column of the table; a candidate key is a minimal superkey. BCNF is a single rule: every determinant of a non-trivial dependency is a superkey. Non-trivial means Y is not already contained in X. The motivation is redundancy. If a determinant X is not a superkey, the same X value can appear in many rows, and the Y it determines is copied into every one of them, so one fact is stored many times. That is what causes update anomalies: change it in one row and the table contradicts itself. To repair a violating X -> Y you decompose: put X plus everything X determines into its own table where X becomes the key, and keep X plus the remaining columns in the other. The join is lossless because the shared columns form a key of the new table.
code
sql · 16 lines-- FD: dept_id -> dept_location, but the key is employee_id
CREATE TABLE employee (
employee_id bigint PRIMARY KEY,
dept_id bigint NOT NULL,
dept_location text NOT NULL
);
-- decomposed: dept_id is now a key where it determines location
CREATE TABLE department (
dept_id bigint PRIMARY KEY,
dept_location text NOT NULL
);
CREATE TABLE employee (
employee_id bigint PRIMARY KEY,
dept_id bigint NOT NULL REFERENCES department(dept_id)
);go deeper
Be able to state the rule in one sentence, define determinant and superkey, and show a two-table fix for a simple violation such as dept_id -> dept_location.
Add the mechanics: compute attribute closures to test each determinant, and explain why a non-superkey determinant forces a fact to be stored once per row.
Connect the rule to operational pain — which anomaly bit you in production — and show the lossless decomposition plus the constraints that keep the split enforced.
Frame BCNF as a diagnostic rather than a target: it names precisely which redundancy a schema tolerates, and the interesting decision is which of those you accept and how you enforce them.
## The vocabulary the rule is built from **Functional dependency (FD).** Written X -> Y. It is a constraint, not an observation about today's rows: in every legal state of the table, any two rows that agree on all columns of X must also agree on all columns of Y. `employee_id -> email` says an employee has exactly one email. FDs come from business rules; sample data can disprove an FD but never establish one. **Determinant.** The left-hand side X. Read X -> Y as "X determines Y", so X is the determining column set. **Superkey.** A column set that functionally determines every column of the table — i.e. no two distinct rows may share its value. A **candidate key** is a minimal superkey (drop any column and it stops being one). A **prime attribute** is a column that belongs to at least one candidate key. **Trivial FD.** One where the right side is already inside the left side, such as (a, b) -> a. These hold automatically and are exempt from every normal form. ## The rule itself A relation is in BCNF if and only if, for every non-trivial FD X -> A that holds on it, X is a superkey. The slogan is *every determinant is a superkey*. There is no second clause, no exception for special columns — that austerity is exactly what distinguishes BCNF from Third Normal Form. ## Why non-superkey determinants create redundancy Suppose the table stores employees and their departments, with the FD `dept_id -> dept_location`. The key is `employee_id`, so `dept_id` is not a superkey: it repeats once per employee in the department. Because the FD forces every row with that `dept_id` to carry the same `dept_location`, the single fact "department 7 is in Berlin" is physically stored once per employee. That duplication is the root of the three classic anomalies. **Update anomaly:** relocating department 7 requires touching every one of its employee rows, and a partial update leaves two contradictory locations. **Insertion anomaly:** you cannot record a new department's location until someone is hired into it, because there is no row to put it in. **Deletion anomaly:** removing the last employee of a department erases the department's location entirely. BCNF removes these by construction: if only superkeys determine things, then every determinant value appears at most once in the table, so no determined fact can be stored twice. ## Checking a table List the FDs the business rules imply. For each non-trivial one, compute the **attribute closure** of its left side — start with X, and repeatedly add the right side of any FD whose left side you already have. If the closure contains every column, X is a superkey and that FD is fine. If any FD's left side closes to less than the full column list, the table violates BCNF. Two shortcuts are worth memorising. Any table with only two columns is automatically in BCNF. And a table with exactly one candidate key is in BCNF precisely when it is in 3NF — the two forms can only diverge when candidate keys overlap. ## Decomposing a violation Given a violating FD X -> Y, split R into R1 = X together with the closure of X, and R2 = X together with the columns not in that closure. X is a key of R1, and X is the shared column set, so joining R1 and R2 on X reconstructs R exactly — the decomposition is **lossless**. Repeat on any sub-table that still violates. The algorithm always terminates in BCNF, and always losslessly; the price, discussed under dependency preservation, is that some original FD may no longer be checkable inside a single table. ## In practice Most OLTP schemas designed the ordinary way — one entity per table, a surrogate primary key, real facts hung off foreign keys — land in BCNF without anyone invoking the theory. BCNF earns its keep as a diagnostic: when you notice the same value being typed into many rows, name the FD, check whether its determinant is a superkey, and if it is not, you have found a table that wants splitting.
- Is every table in BCNF also in Third Normal Form?Yes. BCNF is strictly stronger: 3NF allows a non-superkey determinant as long as the determined column is part of some candidate key, and BCNF removes that allowance. So the BCNF tables are a subset of the 3NF tables, and any table you bring to BCNF is automatically in 3NF, 2NF and 1NF.
- Why is a table with only two columns always in BCNF?With columns A and B the only possible non-trivial dependencies are A -> B and B -> A. If A -> B holds then A determines every column, so A is a superkey, and symmetrically for B. If neither holds, there is no non-trivial FD to violate the rule. Either way the condition is satisfied.
- Can you detect a functional dependency by inspecting the rows currently in a table?No, only refute one. Current data may happen to satisfy X -> Y by coincidence while the business permits a future row that breaks it. Dependencies are declared from domain rules and then enforced by keys and constraints; sampling rows is at best a way to find dependencies you forgot to write down.
A determinant is like a lookup key on a card index. If the card key is unique (a superkey) each fact is filed once. If it is not, you have written the same fact on hundreds of cards and must find them all to correct it.
saying these in an interview costs you the question
- Saying BCNF is about eliminating repeating groups or multi-valued columns — that is 1NF.
- Claiming BCNF means every non-key column depends on 'the key, the whole key and nothing but the key' — that phrase describes 3NF and hides exactly the case where the two differ.
- Treating a determinant as necessarily a single column; determinants are column sets and often composite.
- Deriving functional dependencies from the rows currently stored rather than from business rules.
- Forgetting trivial dependencies are exempt, and concluding every table violates BCNF because (a, b) -> a.