Ruben Gamboa
Professor
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
<Movies>
<Movie title="Gone With the Wind">
<Year>1939</Year>
<Length>231</Length>
<Genre>drama</Genre>
</Movie>
<Movie title="Star Wars">
<Year>1977</Year>
<Length>124</Length>
<Genre>scifi</Genre>
</Movie>
<Movie title="Wayne's World">
<Year>1992</Year>
<Length>95</Length>
<Genre>comedy</Genre>
</Movie>
</Movies>
[
{ "title":"Gone With the Wind",
"year":1939,
"length":231,
"genre":"drama"
},
{ "title":"Star Wars",
"year":1977,
"length":124,
"genre":"scifi"
},
{ "title":"Wayne's World",
"year":1992,
"length":95,
"genre":"comedy"
}
]
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
("Star Wars", 1977, 124, "scifi")
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
Movies(title, year, length, genre)
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
title:string
The entire relation is written as
Movies(title:string, year:integer, length:integer, genre:string)
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
Wayne's World | 1992 | 95 | comedy |
Title | Genre | Year | Length |
---|---|---|---|
Star Wars | scifi | 1977 | 124 |
Gone With the Wind | drama | 1939 | 231 |
Wayne's World | comedy | 1992 | 95 |
Consider a schema like
Movies(title:string, year:integer, length:integer, genre:string)
This describes a relation, which is an abstract ideal
By abstract, I mean any possible set of rows that follows this schema
A specific set of rows makes up a relation instance
So a relation represents any possible data set that fits into a table, e.g., the students enrolled in a class
But a relation instance is one concrete data set, e.g., the students in this class
We note keys by underlining or italicizing the key attributes
Movies(_title_:string, _year_:integer, length:integer, genre:string)
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieStars(_name_:string, address:string, gender:char, birthdate:date)
StarsIn(_movieTitle_:string, _movieYear_:integer, _starName_:string)
MovieExecs(name:string, address:string, _cert#_:integer, netWorth:integer)
Studios(_name_:string, address:string, presC#:integer)
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieStars(_name_:string, address:string, gender:char, birthdate:date)
StarsIn(_movieTitle_:string, _movieYear_:integer, _starName_:string)
MovieExecs(name:string, address:string, _cert#_:integer, netWorth:integer)
Studios(_name_:string, address:string, presC#:integer)
CREATE TABLE
command is used to define stored relations (aka tables)Type | Explanation |
---|---|
CHAR(n) | Fixed-length string of n characters |
VARCHAR(n) | Variable-length string of up to n characters |
BIT(n) | Fixed-length string of n bits |
BIT VARYING(n) | Variable-length string of up to n bits |
BOOLEAN | Can be TRUE, FALSE, or UNKNOWN |
INT or INTEGER | Integer values, may use underlying C int type |
FLOAT or REAL | Floating-point values, may use underlying C float or double |
DOUBLE PRECISION | Floating-point value, may use underlying C double |
DECIMAL(n,d) | Fixed-point value, with n digits, d of which are after the decimal point |
NUMERIC | Could be any of the numeric values above |
DATE | Dates, could be in format '2015-01-26' |
TIME | Times, could be in format '14:25:30.6' |
DATETIME | Date and time, could be in format '2015-01-26 14:25:30.6' |
DURATION | Period of time, could be in format '1:20:30.6' |
CREATE TABLE
commandCREATE TABLE Movies (
title VARCHAR(100),
year INT,
length INT,
genre VARCHAR(10),
studioName VARCHAR(100),
producerC# INT
);
CREATE TABLE MovieStars (
name VARCHAR(100),
address VARCHAR(200),
gender CHAR(1),
birthdate DATE
);
DROP TABLE
commandDROP
to remove items from the database schemaDELETE
to remove items from a relation instance
DROP TABLE Movies;
ALTER TABLE
command
ALTER TABLE MovieStars ADD phone CHAR(16);
ALTER TABLE MovieStars DROP birthdate;
CREATE TABLE MovieStars (
name VARCHAR(100),
address VARCHAR(200),
gender CHAR(1) DEFAULT '?',
birthdate DATE DEFAULT '0000-00-00'
);
ALTER TABLE MovieStars ADD phone CHAR(16) DEFAULT 'unlisted';
CREATE TABLE MovieStars (
name VARCHAR(100) PRIMARY KEY,
address VARCHAR(200),
gender CHAR(1) DEFAULT '?',
birthdate DATE DEFAULT '0000-00-00'
);
CREATE TABLE Movies (
title VARCHAR(100),
year INT,
length INT,
genre VARCHAR(10),
studioName VARCHAR(100),
producerC# INT,
PRIMARY KEY (title, year)
);
UNIQUE
instead of PRIMARY KEY
PRIMARY KEY
adds a constraint that the values for those attributes
cannot be NULL
PRIMARY KEY
for the keyUNIQUE
for other candidate keys (that were not chosen)PRIMARY KEY
for sid and UNIQUE
for ssnname | address | gender | birthdate |
---|---|---|---|
Carrie Fisher | 123 Maple St. | F | 9/9/99 |
Mark Hamill | 456 Oak Rd. | M | 8/8/88 |
name | address | gender | birthdate |
---|---|---|---|
Carrie Fisher | 123 Maple St. | F | 9/9/99 |
Harrison Ford | 789 Palm Dr. | M | 7/7/77 |
name | address | gender | birthdate |
---|---|---|---|
Carrie Fisher | 123 Maple St. | F | 9/9/99 |
Mark Hamill | 456 Oak Rd. | M | 8/8/88 |
Harrison Ford | 789 Palm Dr. | M | 7/7/77 |
name | address | gender | birthdate |
---|---|---|---|
Carrie Fisher | 123 Maple St. | F | 9/9/99 |
name | address | gender | birthdate |
---|---|---|---|
Mark Hamill | 456 Oak Rd. | M | 8/8/88 |
name | address | gender | birthdate |
---|---|---|---|
Harrison Ford | 789 Palm Dr. | M | 7/7/77 |
R.name | R.address | R.gender | R.birthdate | S.name | S.address | S.gender | S.birthdate |
---|---|---|---|---|---|---|---|
Carrie Fisher | 123 Maple St. | F | 9/9/99 | Carrie Fisher | 123 Maple St. | F | 9/9/99 |
Carrie Fisher | 123 Maple St. | F | 9/9/99 | Harrison Ford | 789 Palm Dr. | M | 7/7/77 |
Mark Hamill | 456 Oak Rd. | M | 8/8/88 | Carrie Fisher | 123 Maple St. | F | 9/9/99 |
Mark Hamill | 456 Oak Rd. | M | 8/8/88 | Harrison Ford | 789 Palm Dr. | M | 7/7/77 |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
The Matrix | 1999 | 136 | scifi |
Title | Length | Year |
---|---|---|
Gone With the Wind | 231 | 1939 |
Star Wars | 124 | 1977 |
The Matrix | 136 | 1999 |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
The Matrix | 1999 | 136 | scifi |
Genre |
---|
drama |
scifi |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
The Matrix | 1999 | 136 | scifi |
Title | Year | Length | Genre |
---|---|---|---|
Star Wars | 1977 | 124 | scifi |
The Matrix | 1999 | 136 | scifi |
Title | Year | Length | Genre |
---|---|---|---|
Gone With the Wind | 1939 | 231 | drama |
Star Wars | 1977 | 124 | scifi |
The Matrix | 1999 | 136 | scifi |
Title | Year | Length | Genre |
---|---|---|---|
The Matrix | 1999 | 136 | scifi |
Consider these two tables
Movies(_title_:string, _year_:integer, length:integer, genre:string,
name:string, producerC#:integer)
Studios(_name_:string, address:string, presC#:integer)
Note: We've modified the schema so that Movies
uses name
instead of studioName
We want to find the studio that makes each movie
We can do this with this relational algebra expression: \[\sigma_{\text{Movies.name} = \text{Studios.name}}(Movies \times Studios)\]
Title | Year | Length | Genre | Name | ProducerC# |
---|---|---|---|---|---|
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 |
Name | Address | PresC# |
---|---|---|
MGM | 101 Mogul St. | 5678 |
Lucasfilm | 1 Jedi Way | 6789 |
Warner | 200 Brothers Pl. | 4567 |
Title | Year | Length | Genre | Movies.Name | ProducerC# | Studios.Name | Address | PresC# |
---|---|---|---|---|---|---|---|---|
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 | MGM | 101 Mogul St. | 5678 |
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 | Lucasfilm | 1 Jedi Way | 6789 |
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 | Warner | 200 Brothers Pl. | 4567 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 | MGM | 101 Mogul St. | 5678 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 | Lucasfilm | 1 Jedi Way | 6789 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 | Warner | 200 Brothers Pl. | 4567 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 | MGM | 101 Mogul St. | 5678 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 | Lucasfilm | 1 Jedi Way | 6789 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 | Warner | 200 Brothers Pl. | 4567 |
Title | Year | Length | Genre | Movies.Name | ProducerC# | Studios.Name | Address | PresC# |
---|---|---|---|---|---|---|---|---|
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 | MGM | 101 Mogul St. | 5678 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 | Lucasfilm | 1 Jedi Way | 6789 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 | Warner | 200 Brothers Pl. | 4567 |
Title | Year | Length | Genre | Name | ProducerC# | Address | PresC# |
---|---|---|---|---|---|---|---|
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 | 101 Mogul St. | 5678 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 | 1 Jedi Way | 6789 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 | 200 Brothers Pl. | 4567 |
Movies
with the same name as an attribute in Studios
are
filtered to have equal valuesNow consider the original schema
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
Studios(_name_:string, address:string, presC#:integer)
We can join it as follows: \[\text{Movies} \bowtie_{\text{studioName} = \text{name}} \text{Studios}\]
Title | Year | Length | Genre | StudioName | ProducerC# | Name | Address | PresC# |
---|---|---|---|---|---|---|---|---|
Gone With the Wind | 1939 | 231 | drama | MGM | 1234 | MGM | 101 Mogul St. | 5678 |
Star Wars | 1977 | 124 | scifi | Lucasfilm | 2345 | Lucasfilm | 1 Jedi Way | 6789 |
The Matrix | 1999 | 136 | scifi | Warner | 3456 | Warner | 200 Brothers Pl. | 4567 |
Movies
and their producers
We can do this by joining the tables
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieExecs(name:string, address:string, _cert#_:integer, netWorth:integer)
\[\text{Movies} \bowtie_{\text{producerC#} = \text{cert#}} \text{MovieExecs}\]
MovieExecs
We can do this by joining the tables
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieExecs(name:string, address:string, _cert#_:integer, netWorth:integer)
\[\pi_{\text{name}, \text{address}, \text{cert#}, \text{netWorth}}(\text{Movies} \bowtie_{\text{producerC#} = \text{cert#}} \text{MovieExecs})\]
MovieExecs
We can do this by joining the tables
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieExecs(name:string, address:string, _cert#_:integer, netWorth:integer)
Basic strategy: \[\text{MovieExecs} \bowtie \text{Movies}_1 \bowtie \text{Movies}_2\]
The executive produces movie #1 and movie #2
Movies #1 and #2 are different movies
Movies
and the MovieStars
in them
We can do this by joining the tables
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieStars(_name_:string, address:string, gender:char, birthdate:date)
StarsIn(_movieTitle_:string, _movieYear_:integer, _starName_:string)
Make sure you know how to do this!
Very important: Make sure you know how to do this!
MovieStars
in Movies
that Kevin Bacon stars in
We can do this by joining the tables
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
MovieStars(_name_:string, address:string, gender:char, birthdate:date)
StarsIn(_movieTitle_:string, _movieYear_:integer, _starName_:string)
MovieStars
filters for Kevin BaconStarsIn
and MovieStars
finds Movies
that Kevin Bacon stars inStarsIn
and MovieStars
finds the other MovieStars
in those Movies
If you only want to rename the relation (and leave the attributes the same), you can just leave the new relation name in the subscript
Movies(_title_:string, _year_:integer, length:integer, genre:string,
studioName:string, producerC#:integer)
This is the missing piece to doing a query like
\[\begin{eqnarray} \text{MovieExecs} && \bowtie_{\text{M1.producerC#} = \text{cert#}} \rho_{\text{M1}}(\text{Movies})\\ && \bowtie_{\text{M2.producerC#} = \text{cert#} \text{ AND } (\text{M1.title} \ne \text{M2.title} \text{ OR } \text{M1.year} \ne \text{M2.year})} \rho_{\text{M2}}(\text{Movies}) \\ \end{eqnarray} \]
We introduce assignment statements: \[R(A,B,C) := S \bowtie T \cap U\]
The previous expression is easier to write as follows: \[\begin{eqnarray} MM & := & \rho_\text{M1}(\text{Movies}) \bowtie_{\text{M1.producerC#} = \text{M2.producerC#}} \rho_\text{M2}(\text{Movies}) \\ FMM & := & \sigma_{\text{M1.title} \ne \text{M2.title} \text{ OR } \text{M1.year} \ne \text{M2.year}}(MM) \\ \text{Answer} & := & \text{MovieExec} \bowtie_{\text{M1.producerC#} = \text{cert#}}(FMM) \\ \end{eqnarray} \]
StarsIn.starName
,
then that person must also appear in MovieStars.name
\[\sigma_{\text{M1.title} = \text{M2.title} \text{ AND } \text{M1.year} = \text{M2.year} \text{ AND } \text{M1.length} \ne \text{M2.length} \text{ AND } \text{M1.genre} \ne \text{M2.genre} \text{ AND } \dots}(\rho_{\text{M1}}(\text{Movies}) \times \rho_{\text{M2}}(\text{Movies})) = \emptyset\]
What a mess!
This is far easier to read as follows:
\[\begin{eqnarray} XP & := & \rho_{\text{M1}}(\text{Movies}) \times \rho_{\text{M2}}(\text{Movies}) \\ SK & := & \sigma_{\text{M1.title} = \text{M2.title} \text{ AND } \text{M1.year} = \text{M2.year}}(XP) \\ SNK & := & \sigma_{\text{M1.length} \ne \text{M2.length} \text{ OR } \text{M1.genre} \ne \text{M2.genre} \text{ OR } \dots}(SK) \\ SNK & = & \emptyset \end{eqnarray} \]