Chapter 12 · Normalization and Practical Schema Design

Boyce-Codd Normal Form

BCNF strengthens third normal form: every determinant must identify an entire row. That rule removes subtle redundancy, but a BCNF decomposition can make some dependencies harder to enforce locally.

Intermediate110–135 minutesBCNF reasoning + decomposition tradeoffsLast reviewed: August 2026

Learning outcomes

01

Define BCNF and distinguish it precisely from third normal form.

02

Find determinants that are not superkeys.

03

Decompose a 3NF relation into BCNF relations using a violating dependency.

04

Test binary decompositions for losslessness.

05

Evaluate the tradeoff between stronger redundancy control and dependency preservation.

BCNF in one rule

\[\text{For every nontrivial dependency } X \rightarrow Y,\; X \text{ must be a superkey.}\]

Third normal form allows one exception: a dependency can have a non-superkey determinant when every dependent attribute is prime—that is, part of some candidate key. BCNF removes that exception.

Normal formAllowed nontrivial dependency X → A
3NFX is a superkey, or A is a prime attribute.
BCNFX must be a superkey. No prime-attribute exception.

A relation that is 3NF but not BCNF

Consider teaching(student_id, course_id, instructor_id) with these business rules:

text · dependencies
(student_id, course_id) -> instructor_idinstructor_id -> course_id

Each instructor teaches exactly one course, while a student may study with several instructors. Candidate keys are (student_id, course_id) and (student_id, instructor_id). Therefore course_id is prime. The dependency instructor_id → course_id satisfies 3NF’s exception but violates BCNF because instructor_id is not a superkey of the original relation.

See the redundancy

sqlite · 3NF but non-BCNF table
DROP TABLE IF EXISTS teaching;CREATE TABLE teaching (    student_id    INTEGER NOT NULL,    course_id     INTEGER NOT NULL,    instructor_id INTEGER NOT NULL,    PRIMARY KEY (student_id, course_id),    UNIQUE (student_id, instructor_id)) STRICT;INSERT INTO teaching VALUES(101, 501, 31),(102, 501, 31),(103, 501, 31),(101, 502, 32),(103, 502, 32);

The fact “instructor 31 teaches course 501” is repeated once per student. Reassigning that instructor requires several row updates.

sqlite · detect instructor-course contradictions
SELECT instructor_id, COUNT(DISTINCT course_id) AS course_countFROM teachingGROUP BY instructor_idHAVING COUNT(DISTINCT course_id) > 1;

Decompose on the violating dependency

teaching(student, course, instructor)
Violation: instructor → course
instructor_course(instructor, course)
student_instructor(student, instructor)

The determinant and its dependent form one relation; the determinant remains as the bridge in the other.

sqlite · BCNF decomposition
DROP TABLE IF EXISTS student_instructor;DROP TABLE IF EXISTS instructor_course;CREATE TABLE instructor_course (    instructor_id INTEGER PRIMARY KEY,    course_id     INTEGER NOT NULL) STRICT;CREATE TABLE student_instructor (    student_id    INTEGER NOT NULL,    instructor_id INTEGER NOT NULL REFERENCES instructor_course(instructor_id),    PRIMARY KEY (student_id, instructor_id)) STRICT, WITHOUT ROWID;INSERT INTO instructor_course VALUES(31, 501),(32, 502);INSERT INTO student_instructor VALUES(101, 31), (102, 31), (103, 31),(101, 32), (103, 32);

Reconstruct the teaching relation

sqlite · lossless join
SELECT    si.student_id,    ic.course_id,    si.instructor_idFROM student_instructor AS siJOIN instructor_course AS ic  ON ic.instructor_id = si.instructor_idORDER BY si.student_id, ic.course_id;

The shared attribute instructor_id is a key of instructor_course. That makes the binary decomposition lossless for the dependency used to decompose it.

The BCNF decomposition algorithm

text · iterative procedure
while some relation R violates BCNF:    choose a nontrivial dependency X -> Y    where X is not a superkey of R    replace R with:        R1 = X union Y        R2 = R - (Y - X)    repeat on R1 and R2

The algorithm guarantees a lossless decomposition, but it does not guarantee that every original dependency can be enforced without joining relations.

Dependency-preservation tradeoff

BCNF

Stronger redundancy control

Every determinant is a key, eliminating more update anomalies than 3NF.

3NF

Dependency-friendly synthesis

A canonical 3NF design can preserve all dependencies while remaining lossless.

Join

Possible enforcement cost

A lost dependency may require a cross-table assertion, trigger, materialized check, or application transaction.

Choice

Workload and risk

Prefer BCNF when the removed redundancy is material; prefer dependency-preserving 3NF when local enforcement is critical.

Do not infer dependencies from names alone

ClaimRequired business meaning
instructor_id → course_idEach instructor teaches exactly one course for the modeled time scope.
course_id → instructor_idEach course has exactly one instructor for the modeled time scope.
(course_id, term_code) → instructor_idOne instructor is assigned per course offering and term.
instructor_id → course_id is falseAn instructor may teach multiple courses.

Changing the time scope or cardinality changes the dependency set and therefore the correct schema.

Checkpoint

3NF or BCNF?

  1. What exception does 3NF allow that BCNF rejects?
  2. Why is instructor_id not a superkey of teaching?
  3. How does the decomposition remove redundancy?
  4. Why is the decomposition lossless?
  5. When might a dependency-preserving 3NF design be preferable?
Review the answers

3NF permits a non-superkey determinant when the dependent is prime. instructor_id does not identify a student row. The instructor-course fact is stored once. The shared determinant is a key of one component. 3NF may be preferable when every dependency must be enforced locally and the remaining redundancy is acceptable.

Summary and references

  • BCNF requires every nontrivial determinant to be a superkey.
  • A relation can satisfy 3NF while violating BCNF.
  • Decompose around a violating determinant to remove repeated facts.
  • The standard BCNF decomposition is lossless.
  • BCNF may sacrifice dependency preservation, so the final choice is an engineering tradeoff.

References

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.