In proposing the relational model, Codd had some very specific advantages in mind.
Simple conceptual framework. Everything is a relation, and access is through the precise relational algebra
The structure of the database, and the rules of the DBMS, should ensure data integrity
Logical relationships among data items cannot be violated
He proposed certain constraints on how databases should be structured
Called normal forms
These form successively more strict rules
There are many – more than six
We will study the first three (most important)
Not in 1NF
Previous DBMSs allowed structures like this
Tables nested inside tables!
This is called a hierarchical database
Creates a complex data object that is hard to reason about
Can’t use relational algebra on it
In 1NF
The previous structure can be converted into two tables
Doing so puts the database in first normal form (1NF)
1NF
First normal form (1NF): everything is a relation
In other words, no attribute domain has relations as elements
This is enforced by relational algebra or SQL: it’s not possible to create tables that have tables as elements.
Advantages:
simplifies the data language (relational algebra or SQL)
supports one-one and many-to-many (wasn’t possible in previous systems)
makes further normalization levels possible
2NF
The next problem Codd wanted to solve using normalization was ‘hidden dependencies’
Consider this relation:
What can go wrong?
Assume each author only writes in one language
What can go wrong when this table is updated?
Second Normal Form (2NF)
Formally, a database is in 2NF when
It is in 1NF, and
It does not have any non-prime attribute that is functionally dependent on any proper subset of any candidate key
A non-prime attribute is an attribute that is not part of any candidate key (language is a non-prime attribute)
Proper subset: (author) is a proper subset of (title, author)
language is functionally dependent on author
3NF
The next problem Codd wanted to solve using normalization was ‘dependent updates’
Consider this relation:
What can go wrong?
What happens when Stephen King changes book agents?
Many updates need to be made, and this is error prone
3NF
The solution is:
First put the database in 2NF:
Then capture the functional relationship between agent and phone number in a separate relation
Now, when King changes agents, we only update a single record in the Retains relation
3NF (cont.)
This could be done as follows:
3NF (cont.)
Or alternatively:
Can you think of reasons for preferring this strategy to the previous slide’s strategy?
3NF (cont.)
Formally, a database is in 3NF when:
It is in 2NF, and
No non-prime attribute is transitively dependent on the primary key
A non-prime attribute is an attribute that is not part of any primary key
A transitive dependency is a functional dependency in which X → Z (X determines Z) indirectly, by virtue of X → Y, and Y → Z
Here: X is author, Y is agent, and Z is agent’s phone number
Benefits of Normal Forms
1NF: All relations are flat tables; conceptually simple
2NF: A legal database update cannot violate any hidden dependencies
3NF: A change to a dependent attribute only needs to be made in one place
Central Theme: the structure of the database, and the rules of the database management system, enforce integrity on the data
Criticisms of the Relational Model
Performance can worsen for some operations. If you are retrieving a many-to-one relation, you need to access multiple tables (perhaps three). In a non-relational model, we could store the “many” in the same table as the “one”, making it possible to retrieve them all more quickly.
Databases that store complex data structures do not map well to the relational model. Object-oriented databases, graph databases, and the new vector databases (used with LLMs) do not use the relational model.
For the above reasons, there are more databases in the world than just relational … and we will study them
But relational is far and away the most common structure for databases in practice
SQL Data Types
Numeric types include:
INTEGER
REAL: a real number (i.e., one that may have a fractional part)
Non-numeric types include:
DATE (e.g., ‘2017-02-23’)
TIME (e.g., ‘15:30:30’)
two types for strings (i.e., arbitrary sequences of characters)
CHAR
VARCHAR
Creating the Student table…
CREATETABLE Student(idCHAR(8) PRIMARYKEY, name VARCHAR(30));
Inserting a Row…
CREATETABLE Student(idCHAR(8) PRIMARYKEY, name VARCHAR(30));
4) Find the ids and names of everyone in the database who has acted in a movie directed by James Cameron. (Hint: One table is needed twice!)
SELECTFROMWHERE
SELECTFROM Person ActP, Actor A, Director D, Person DirPWHERE
SELECTFROM Person ActP, Actor A, Director D, Person DirPWHERE ActP.id= A.actor_id AND A.movie_id = D.movie_idAND D.director_id = DirP.id
SELECTFROM Person ActP, Actor A, Director D, Person DirPWHERE ActP.id= A.actor_id AND A.movie_id = D.movie_idAND D.director_id = DirP.idAND DirP.name ='James Cameron';
SELECTDISTINCT ActP.id, ActP.nameFROM Person ActP, Actor A, Director D, Person DirPWHERE ActP.id= A.actor_id AND A.movie_id = D.movie_idAND D.director_id = DirP.idAND DirP.name ='James Cameron';
6) For each person in the database born in Boston, Mass, find the number of movies in the database (possibly 0) in which the person has acted. You may assume that names are unique.
SELECTFROMWHERE
SELECTFROM Person LEFTOUTERJOIN Actor ONid= actor_idWHERE
SELECTFROM Person LEFTOUTERJOIN Actor ONid= actor_idWHEREGROUPBY name
SELECTFROM Person LEFTOUTERJOIN Actor ONid= actor_idWHERE pob LIKE'Boston, Mass%'GROUPBY name;
SELECT name, COUNT(____________)FROM Person LEFTOUTERJOIN Actor ONid= actor_idWHERE pob LIKE'Boston, Mass%'GROUPBY name;
SELECT name, COUNT(movie_id)FROM Person LEFTOUTERJOIN Actor ONid= actor_idWHERE pob LIKE'Boston, Mass%'GROUPBY name;
1) Find the Best-Picture winner with the best/smallest earnings rank. The result should have the form (name, earnings_rank). Assume no two movies have the same earnings rank.
SELECTFROMWHERE (SELECTFROM Movie M, Oscar OWHERE M.id= O.movie_id);
SELECTFROMWHERE (SELECTFROM Movie M, Oscar OWHERE M.id= O.movie_idAND O.type='BEST-PICTURE');
SELECTFROMWHERE (SELECTMIN(earnings_rank)FROM Movie M, Oscar OWHERE M.id= O.movie_idAND O.type='BEST-PICTURE');
SELECTFROM MovieWHERE earnings_rank = (SELECTMIN(earnings_rank)FROM Movie M, Oscar OWHERE M.id= O.movie_idAND O.type='BEST-PICTURE');
SELECT name, earnings_rankFROM MovieWHERE earnings_rank = (SELECTMIN(earnings_rank)FROM Movie M, Oscar OWHERE M.id= O.movie_idAND O.type='BEST-PICTURE');