Integrity Constraints & Normal Forms
Normalisation looks like a list of rules to memorise, and understanding why it is not saves a great deal of effort.
The organising fact is that every update anomaly traces to a functional dependency whose determinant is not a key. If a non-key attribute determines something, that something is stored redundantly, once per row sharing the determinant, and the copies can disagree.
Each normal form is therefore a statement about which dependencies are permitted to exist, and the forms get stronger by permitting fewer of them. Boyce-Codd normal form is the limiting case: every determinant must be a superkey.
The second organising fact is that decomposition must not lose information, and the test for that is purely mechanical. A binary decomposition is lossless exactly when the shared attributes determine one of the two halves.
The third is a trade-off that cannot be escaped. Third normal form is always achievable with both losslessness and dependency preservation. Boyce-Codd normal form is always achievable losslessly, but sometimes only by giving up a dependency.
1. Functional Dependencies
A functional dependency says that any two tuples agreeing on must agree on .
It is a statement about every legal instance, not about the rows currently present. A dependency that happens to hold in the sample data is not necessarily a dependency of the schema.
A trivial dependency has contained in and holds automatically.
Armstrong's axioms are sound and complete, meaning they derive exactly the dependencies logically implied by a given set.
Reflexivity: if then .
Augmentation: if then .
Transitivity: if and then .
Three derived rules save time. Union combines and into . Decomposition splits into and . Pseudotransitivity turns and into .
Decomposition applies only to the right side. From one may not conclude , and assuming otherwise is the single most common error in this topic.
2. Attribute Closure and Candidate Keys
The closure is the set of all attributes functionally determined by .
The algorithm is simple. Start with . Repeatedly, if some dependency's left side is contained in the current set, add its right side. Stop when nothing changes.
is a superkey exactly when contains every attribute of the relation.
Finding candidate keys uses two shortcuts that turn a search into an inspection.
Any attribute appearing on no right side must belong to every candidate key, because nothing else can determine it.
Any attribute appearing on no left side and on some right side belongs to no candidate key, because it determines nothing.
The procedure is therefore: collect the attributes that must be in every key, take their closure, and if that is everything, it is the unique candidate key. Otherwise extend it with one attribute at a time from the remaining pool.
A prime attribute is one belonging to some candidate key. Non-prime attributes are the ones normalisation is mostly about.
3. Canonical Cover
A canonical cover is a minimal set of dependencies equivalent to the original.
Three conditions define it. Every right side is a single attribute. No dependency is redundant, meaning removing it changes the closure of nothing. No left side has a redundant attribute.
The computation proceeds in that order. Split all right sides. Then, for each dependency, test whether its left side still determines its right side without it. Then, for each left side attribute, test whether it can be dropped.
Order matters and the result is not unique, so different valid canonical covers exist for the same set, and an exam answer is judged on the checks rather than on matching a particular list.
The canonical cover is what the 3NF synthesis algorithm consumes, which is why it is worth computing correctly.
4. Anomalies and the Normal Forms
Three anomalies motivate the whole subject.
Insertion anomaly: a fact cannot be recorded because another, unrelated fact is unknown.
Deletion anomaly: removing one fact silently removes another.
Update anomaly: a fact stored in many rows must be changed in all of them, and a partial update leaves the database inconsistent.
First normal form requires atomic attribute values, with no repeating groups or nested relations. It is a condition on the data model rather than on dependencies.
Second normal form forbids a partial dependency, meaning a non-prime attribute determined by a proper subset of some candidate key. It matters only when a candidate key is composite.
Third normal form requires that for every non-trivial dependency , either is a superkey or is prime.
The second clause is what makes 3NF weaker than BCNF, and it exists precisely so that dependency preservation is always achievable.
Boyce-Codd normal form requires that for every non-trivial dependency , is a superkey. There is no escape clause.
A relation with only two attributes is always in BCNF, which is a useful sanity check.
5. Decomposition
A decomposition is lossless if joining the pieces recovers exactly the original relation, with no spurious tuples.
For a binary decomposition into and , the test is that or .
In words: the shared attributes must be a key of at least one piece.
Dependency preservation asks whether every original dependency can be checked on a single piece, without a join.
The union of the projected dependency sets must be equivalent to the original set, which is tested by checking each original dependency against the closure computed from the union.
Losing a dependency is not a correctness failure but an enforcement cost. The constraint still holds logically; it simply cannot be verified without joining, which is expensive enough that systems typically stop enforcing it.
The 3NF synthesis algorithm builds one relation per dependency in the canonical cover, adds a relation containing a candidate key if none of the pieces contains one, and removes any relation contained in another. It guarantees 3NF, losslessness and dependency preservation together.
BCNF decomposition is analytical rather than synthetic. Find a violating dependency , split the relation into and plus the remaining attributes, and repeat. It guarantees losslessness but not preservation.
6. Multivalued Dependencies and 4NF
A multivalued dependency, written double-arrow , says that the set of values associated with an value is independent of the remaining attributes.
It captures redundancy that no functional dependency can. A relation recording a course's instructors and its textbooks, where any instructor may use any textbook, must store every instructor-textbook pair, and no functional dependency is violated.
Every functional dependency is a multivalued dependency, but not conversely.
Fourth normal form requires that for every non-trivial multivalued dependency double-arrow , is a superkey.
The fix is the same shape as before: split the relation so each independent set lives with its determinant.
Fifth normal form, or project-join normal form, handles join dependencies that only a decomposition into three or more pieces resolves, and appears rarely in examinations.
Constraints the Schema Enforces Directly
Normalisation removes redundancy; declared constraints enforce validity, and the two are separate concerns that the chapter title joins.
A domain constraint restricts an attribute's permitted values, either through its declared type or through a CHECK clause on the column.
A key constraint declares uniqueness, and a primary key adds the prohibition on nulls that entity integrity requires.
A referential constraint declares a foreign key and specifies what happens on delete or update: cascade, set null, or restrict.
An assertion states a condition over the whole database rather than one table, and is the only declarative way to express constraints spanning relations, though few systems implement it, leaving triggers as the practical mechanism.
7. Worked Examples
Example 1. Find all candidate keys of with dependencies , , , .
First classify the attributes.
Right sides contain , , , and . Every attribute appears on some right side, so no attribute is forced into every key by that test.
Left sides contain , , , and , so every attribute appears on some left side too, and none is excluded.
Both shortcuts fail, so compute closures of single attributes.
: start with ; add from ; add from ; now is present so add . The closure is , so is a candidate key.
: , then from . That is only, so is not a key.
: , then from , then everything gives. The closure is , so is a candidate key.
is just and is just .
Now try pairs involving , and .
: , add , then , then . That is everything, so is a candidate key.
: , add from , now gives , then . Everything, so is a candidate key.
is only. Not a key.
Check minimality: and are both minimal since no single attribute among them is a key.
The candidate keys are , , and , and the prime attributes are , , , and , which is all of them.
Example 2. Determine the highest normal form of that relation.
Every attribute is prime, which was the conclusion above.
Check 3NF. The condition is that for each dependency , either is a superkey or is prime.
: is a candidate key, so this passes on the first clause.
: is a candidate key, passes.
: is a candidate key, passes.
: is not a superkey, since is only . But is prime, being part of . So it passes on the second clause.
The relation is in 3NF.
Check BCNF. Every determinant must be a superkey, with no escape clause.
violates it, since is not a superkey.
So the relation is in 3NF but not BCNF, which is exactly the situation the second clause of 3NF was designed to permit.
Example 3. Test whether decomposing with and into and is lossless.
Compute the shared attributes. is empty.
The test requires the intersection to determine one of the halves. An empty set determines only attributes that everything determines, which here is nothing.
The decomposition is lossy.
A concrete counterexample makes it vivid. Suppose holds two tuples, and .
holds and . holds and .
Their natural join, with no common attribute, is a Cartesian product giving four tuples, two of which never existed.
The repair is to include a connecting attribute. Decomposing into and gives intersection , and since means determines all of , the decomposition is lossless.
Example 4. Decompose with and into BCNF, and show which dependency is lost.
First find the candidate keys.
is , so is a key. : , add from , giving , so is a key.
is , is , is . So the candidate keys are and , and the prime attributes are , and .
Check 3NF. has a superkey determinant. has a non-superkey determinant, but is prime. So the relation is in 3NF.
Check BCNF. violates it, since is , not everything.
Decompose on the violating dependency. Put and its closure together as , and keep with the remaining attributes as .
Verify losslessness. The intersection is , and means determines all of . Lossless.
Now check dependency preservation.
is checkable on alone.
is checkable on neither. lacks and lacks , so verifying it requires joining the two pieces.
The dependency is lost.
This is the standard illustration that BCNF and dependency preservation can conflict, and no other BCNF decomposition of this relation preserves it either.
The practical consequence: a system using this decomposition cannot enforce cheaply, so two rows could be inserted that jointly violate it, and only a periodic join would detect the problem. Designers often stop at 3NF for exactly this reason.
Example 5. Compute a canonical cover for , , , .
Step one: make all right sides single attributes.
This gives , , , again, and .
Removing the literal duplicate leaves , , , .
Step two: remove redundant attributes from left sides.
Consider . Is redundant? Compute using the current set: , then , then . Since contains , is redundant and the dependency becomes .
That duplicates an existing dependency, so the set is now , , .
Step three: remove redundant dependencies.
Test . Remove it and compute from : , then , then . is still reachable, so is redundant.
Remove it, leaving , .
Test . Removing it leaves only , and would be just . Not redundant, so keep it.
Test . Removing it leaves only , and would be just . Not redundant, so keep it.
The canonical cover is .
Example 6. A relation Course(cid, instructor, textbook) records that any instructor of a course may use any textbook of that course. Identify the dependency and normalise.
No functional dependency is violated. The key is all three attributes, since no attribute determines any other.
The relation is therefore in BCNF, trivially, because the only determinant is the full key.
Yet the redundancy is obvious. A course with 3 instructors and 4 textbooks needs 12 rows, and adding a fifth textbook requires 3 new rows rather than 1.
The dependency present is multivalued. Course double-arrow instructor holds, because the set of instructors for a course does not depend on which textbook the row mentions.
Course double-arrow textbook holds symmetrically, and in fact the two always come in pairs within a relation.
4NF is violated, since cid is not a superkey.
Decompose into CourseInstructor(cid, instructor) and CourseTextbook(cid, textbook).
Now the course needs 3 plus 4, which is 7 rows instead of 12, and adding a textbook costs exactly one row.
The decomposition is lossless because the intersection cid multidetermines each half, which is the multivalued analogue of the functional test.
The general lesson is that BCNF is not the end of the story. A relation can satisfy every functional dependency requirement and still store the cross product of two independent facts.
Summary
Every anomaly traces to a dependency whose determinant is not a key, and each normal form restricts which dependencies may exist.
A functional dependency constrains every legal instance, not just the current rows. Armstrong's axioms are reflexivity, augmentation and transitivity, and are sound and complete. Decomposition applies to right sides only.
Attribute closure decides superkeys. An attribute on no right side is in every candidate key; one on no left side but some right side is in none.
A canonical cover has single-attribute right sides, no redundant dependency and no redundant left-side attribute, and it is not unique.
1NF requires atomic values. 2NF forbids partial dependencies and matters only with composite keys. 3NF requires each determinant to be a superkey or each determined attribute to be prime. BCNF drops the second clause.
A binary decomposition is lossless exactly when the intersection determines one of the halves. Dependency preservation asks whether every dependency is checkable without a join.
3NF synthesis from a canonical cover gives 3NF, losslessness and preservation together. BCNF decomposition gives losslessness but may lose a dependency, and the classic example is with and .
Multivalued dependencies capture redundancy no functional dependency can, and 4NF requires their determinants to be superkeys. A relation can be in BCNF and still store a cross product of independent facts.
Separately from normalisation, the schema declares domain, key and referential constraints directly, while conditions spanning several relations need an assertion or, in practice, a trigger.