E.F. Codd introduced the relational model in his 1970 paper “A Relational Model of Data for Large Shared Data Banks.” The model provides a mathematically rigorous foundation for data management Based on set theory and first-order predicate logic. Every SQL database is an approximation of this Model — and understanding where SQL deviates from the theory helps you write correct queries.
Codd defined 13 rules (numbered 0 through 12) that a system must satisfy to be considered truly Relational. No commercial database fully satisfies all 13, but they serve as the theoretical Benchmark:
Rule
Name
Summary
0
Foundation
A relational DBMS must manage databases through its relational capabilities alone
1
Information
All information is represented as values in tables
2
Guaranteed Access
Every value is accessible by table name, primary key, and column name
3
Systematic Treatment of NULL
NULL values are distinct from default values and represent missing information
4
Dynamic Online Catalog
The database description (catalog) is represented as relational tables
5
Comprehensive Sublanguage
Supports at least one relational language (SQL, QBE, etc.)
6
View Updating
All views theoretically updatable must be updatable by the system
7
High-level Insert/Update/Delete
Set-level operations, not row-by-row processing
8
Physical Data Independence
Application logic unaffected by physical storage changes
9
Logical Data Independence
Application logic unaffected by logical schema changes (view changes)
10
Integrity Independence
Integrity constraints are part of the schema, not the application
11
Distribution Independence
Applications unaffected by data distribution
12
Nonsubversion
Low-level language cannot bypass integrity constraints
In practice, Rule 6 (view updating) is the most commonly violated. Most SQL databases cannot update Through arbitrary views, especially those involving joins, aggregations, or DISTINCT.
A mathematical relation is a set of tuples, which means:
No duplicate tuples — SQL tables allow duplicates (unless you declare UNIQUE or PRIMARY KEY). To get true relational behavior, you must use SELECT DISTINCT.
No ordering of tuples — SQL ORDER BY operates on the result set, not on the base relation. A table has no inherent row order.
Attributes are identified by name, not position — SQL allows SELECT * which relies on column ordering. This is a deviation from the theory.
A domain defines the set of valid values for an attribute. SQL data types (INTEGERVARCHAR(255)``DATE) are a coarse approximation of domains. A true domain would include Constraints:
PostgreSQL arrays (INTEGER[]) technically violate 1NF but are a pragmatic extension. When you need To query individual elements or enforce referential integrity on array elements, model them as Separate rows.
A relation is in 2NF if it is in 1NF and no non-prime attribute is partially dependent on any Candidate key. “Partially dependent” means dependent on a proper subset of a candidate key.
2NF only matters for relations with composite candidate keys. If all candidate keys are single Attributes, the relation is automatically in 2NF if it is in 1NF.
A relation is in 3NF if it is in 2NF and no non-prime attribute is transitively dependent on any Candidate key. Equivalently, for every non-trivial FD X→A where A is non-prime, X Must be a superkey.
A relation is in BCNF if for every non-trivial FD X→Y, X is a superkey. BCNF is Stricter than 3NF: 3NF allows X→A where X is a superkey OR A is a prime attribute. BCNF removes the “or A is prime” exception.
R(student, course, instructor)
FDs: {student, course} → instructor
instructor → course
Neither student nor instructor alone is a superkey.
The candidate keys are {student, course} and {student, instructor}.
instructor → course violates BCNF (instructor is not a superkey).