The Relational Model
by K. Yue
1. Introduction
1.1 Data Model
1.2 The Relational Model: an introduction
More theoretically:
Example:
Toyu: A drastically simplified university: toyu
Relationship Diagram (in MS Access):
A version of an ER Diagram (created by using MySQL Workbench).
MS Access: toyu.accdb
Toyu in MySQL: createtoyu.sql.txt
CREATE TABLE IF NOT EXISTS Class (
classId INT NOT NULL,
courseId INT NOT NULL,
semester VARCHAR(10) NOT NULL,
year DECIMAL(4,0) NOT NULL,
facId INT NOT NULL,
room VARCHAR(6) NULL,
CONSTRAINT Class_classId_pk PRIMARY KEY (classId),
CONSTRAINT Class_courseId_fk FOREIGN KEY (courseId)
REFERENCES Course(courseId) ON DELETE CASCADE,
CONSTRAINT Class_facId_fk FOREIGN KEY (facId)
REFERENCES Faculty (facId) ON DELETE CASCADE
);
INSERT INTO Class(classId, courseId, semester, year, facId, room) VALUES
(10000,2000,'Fall',2019,1011,'D241'),
(10001,2001,'Fall',2019,1011,'D242'),
(10002,2002,'Fall',2019,1012,'D136'),
(10003,2020,'Fall',2019,1014,'D241'),
(10004,2021,'Fall',2019,1014,'D241'),
(10005,2040,'Fall',2019,1015,'D237'),
(10006,2041,'Fall',2019,1019,'D217'),
(10007,2060,'Fall',2019,1020,'B101'),
(10008,2080,'Fall',2019,1018,'D241'),
(11000,2000,'Spring',2020,1011,'D241'),
(11001,2001,'Spring',2020,1012,'D242'),
(11002,2002,'Spring',2020,1013,'D136'),
(11003,2020,'Spring',2020,1016,'D217'),
(11004,2061,'Spring',2020,1018,'B101');
MariaDB [toyu]> SELECT * FROM class;
+---------+----------+----------+------+-------+------+
| classId | courseId | semester | year | facId | room |
+---------+----------+----------+------+-------+------+
| 10000 | 2000 | Fall | 2019 | 1011 | D241 |
| 10001 | 2001 | Fall | 2019 | 1011 | D242 |
| 10002 | 2002 | Fall | 2019 | 1012 | D136 |
| 10003 | 2020 | Fall | 2019 | 1014 | D241 |
| 10004 | 2021 | Fall | 2019 | 1014 | D241 |
| 10005 | 2040 | Fall | 2019 | 1015 | D237 |
| 10006 | 2041 | Fall | 2019 | 1019 | D217 |
| 10007 | 2060 | Fall | 2019 | 1020 | B101 |
| 10008 | 2080 | Fall | 2019 | 1018 | D241 |
| 11000 | 2000 | Spring | 2020 | 1011 | D241 |
| 11001 | 2001 | Spring | 2020 | 1012 | D242 |
| 11002 | 2002 | Spring | 2020 | 1013 | D136 |
| 11003 | 2020 | Spring | 2020 | 1016 | D217 |
| 11004 | 2061 | Spring | 2020 | 1018 | B101 |
+---------+----------+----------+------+-------+------+
14 rows in set (0.005 sec)
A tuple/row: {classId: 10004, courseId: 2021, semester: 'Fall', year: 2019, facId: 1014, room: 'D241'}. Note that it is a set of mappings from attribute names to attribute values.
It can also be represented as:
{classId: 10004, facId: 1014, room: 'D241', semester: 'Fall', year: 2019, courseId: 2021}
or
{10004, 2021, 'Fall', 2019, 1014, 'D241'} if the attribute names are assumed.
or using a more computer science-style notation.
(10004, 2021, 'Fall', 2019, 1014, 'D241')
Identify some examples of the database terms in the class table above as much as possible.
Example:
+---------+----------+----------+------+-------+------+
| classId | courseId | semester | year | facId | room |
+---------+----------+----------+------+-------+------+
| 10000 | 2000 | Fall | 2019 | 1011 | D241 |
| 10001 | 2001 | Fall | 2019 | 1011 | D242 |
| 10002 | 2002 | Fall | 2019 | 1012 | D136 |
| 10003 | 2020 | Fall | 2019 | 1014 | D241 |
| 10004 | 2021 | Fall | 2019 | 1014 | D241 |
| 10005 | 2040 | Fall | 2019 | 1015 | D237 |
| 10006 | 2041 | Fall | 2019 | 1019 | D217 |
| 10007 | 2060 | Fall | 2019 | 1020 | B101 |
| 10008 | 2080 | Fall | 2019 | 1018 | D241 |
| 11000 | 2000 | Spring | 2020 | 1011 | D241 |
| 11001 | 2001 | Spring | 2020 | 1013 | D242 |
| 11002 | 2002 | Spring | 2020 | 1013 | D136 |
| 11003 | 2020 | Spring | 2020 | 1016 | D217 |
| 11004 | 2061 | Spring | 2020 | 1018 | B101 |
+---------+----------+----------+------+-------+------+
and
+---------+------+----------+----------+------+-------+
| classId | year | semester | courseId | room | facId |
+---------+------+----------+----------+------+-------+
| 11004 | 2020 | Spring | 2061 | B101 | 1018 |
| 10007 | 2019 | Fall | 2060 | B101 | 1020 |
| 10002 | 2019 | Fall | 2002 | D136 | 1012 |
| 11002 | 2020 | Spring | 2002 | D136 | 1013 |
| 11003 | 2020 | Spring | 2020 | D217 | 1016 |
| 10006 | 2019 | Fall | 2041 | D217 | 1019 |
| 10005 | 2019 | Fall | 2040 | D237 | 1015 |
| 10000 | 2019 | Fall | 2000 | D241 | 1011 |
| 11000 | 2020 | Spring | 2000 | D241 | 1011 |
| 10003 | 2019 | Fall | 2020 | D241 | 1014 |
| 10004 | 2019 | Fall | 2021 | D241 | 1014 |
| 10008 | 2019 | Fall | 2080 | D241 | 1018 |
| 10001 | 2019 | Fall | 2001 | D242 | 1011 |
| 11001 | 2020 | Spring | 2001 | D242 | 1013 |
+---------+------+----------+----------+------+-------+
store the same information.
The second table can be obtained in SQL by:
SELECT classId, year, semester, courseId, room, facId
FROM class
ORDER BY room, facId;
2. Null values
Example:
-- students with no advisor
SELECT s.*
FROM student AS s
WHERE s.advisor IS NULL;
-- Show all students with a declared minor.
SELECT DISTINCT s.*
FROM student AS s
WHERE s.minor IS NOT NULL;
-- Show enrollment without a n_alerts value.
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts IS NULL;
Result:
MariaDB [toyu]> -- students with no advisor
MariaDB [toyu]> SELECT s.*
-> FROM student AS s
-> WHERE s.advisor IS NULL;
+--------+-----------+-------+-------+-------+------+---------+
| stuId | fname | lname | major | minor | ach | advisor |
+--------+-----------+-------+-------+-------+------+---------+
| 100003 | Catherine | Lim | ITEC | CINF | 20 | NULL |
| 100007 | Ben | Zico | NULL | NULL | 16 | NULL |
| 100008 | Bill | Ching | ARTS | NULL | 90 | NULL |
+--------+-----------+-------+-------+-------+------+---------+
3 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- Show all students with a declared minor.
MariaDB [toyu]> SELECT DISTINCT s.*
-> FROM student AS s
-> WHERE s.minor IS NOT NULL;
+--------+-----------+---------+-------+-------+------+---------+
| stuId | fname | lname | major | minor | ach | advisor |
+--------+-----------+---------+-------+-------+------+---------+
| 100000 | Tony | Hawk | CSCI | CINF | 40 | 1011 |
| 100001 | Mary | Hawk | CSCI | CINF | 35 | 1011 |
| 100002 | David | Hawk | CSCI | ITEC | 66 | 1012 |
| 100003 | Catherine | Lim | ITEC | CINF | 20 | NULL |
| 100005 | Linda | Johnson | CINF | ENGL | 13 | 1015 |
| 100006 | Lillian | Johnson | CINF | ITEC | 18 | 1016 |
| 100009 | Linda | King | ARTS | CSCI | 125 | 1018 |
+--------+-----------+---------+-------+-------+------+---------+
7 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- Show enrollment without a n_alerts value.
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts IS NULL;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100001 | 10000 | NULL | NULL |
| 100005 | 10003 | NULL | NULL |
| 100004 | 10004 | B+ | NULL |
| 100006 | 10004 | C+ | NULL |
| 100006 | 10005 | A | NULL |
| 100005 | 10006 | B+ | NULL |
+--------+---------+-------+----------+
6 rows in set (0.000 sec)
Null and Boolean Expressions
Example:
-- 1. Boolean values are TINYINT. FALSE is 0.
SELECT FALSE,
TRUE;
SELECT *
FROM student
WHERE 0;
SELECT *
FROM student
WHERE 1;
SELECT *
FROM student
WHERE 2697;
SELECT *
FROM student
WHERE '0';
SELECT *
FROM student
WHERE '145';
-- warning: '' cannot be converted to a number.
-- "Warning 1292 Truncated incorrect DOUBLE value: ''"
SELECT *
FROM student
WHERE '';
-- warning: '' cannot be converted to a number.
-- "Warning 1292 Truncated incorrect DOUBLE value: ''"
SELECT *
FROM student
WHERE 'Hello world';
SELECT *
FROM student
WHERE 1.49;
Result:
MariaDB [toyu]> SELECT FALSE,
-> TRUE;
+-------+------+
| FALSE | TRUE |
+-------+------+
| 0 | 1 |
+-------+------+
1 row in set (0.001 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE 0;
Empty set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE 1;
+--------+-----------+----------+-------+-------+------+---------+
| stuId | fname | lname | major | minor | ach | advisor |
+--------+-----------+----------+-------+-------+------+---------+
| 100000 | Tony | Hawk | CSCI | CINF | 40 | 1011 |
| 100001 | Mary | Hawk | CSCI | CINF | 35 | 1011 |
| 100002 | David | Hawk | CSCI | ITEC | 66 | 1012 |
| 100003 | Catherine | Lim | ITEC | CINF | 20 | NULL |
| 100004 | Larry | Johnson | ITEC | NULL | 66 | 1017 |
| 100005 | Linda | Johnson | CINF | ENGL | 13 | 1015 |
| 100006 | Lillian | Johnson | CINF | ITEC | 18 | 1016 |
| 100007 | Ben | Zico | NULL | NULL | 16 | NULL |
| 100008 | Bill | Ching | ARTS | NULL | 90 | NULL |
| 100009 | Linda | King | ARTS | CSCI | 125 | 1018 |
| 100111 | Cathy | Johanson | NULL | NULL | 0 | 1018 |
+--------+-----------+----------+-------+-------+------+---------+
11 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE 2697;
+--------+-----------+----------+-------+-------+------+---------+
| stuId | fname | lname | major | minor | ach | advisor |
+--------+-----------+----------+-------+-------+------+---------+
| 100000 | Tony | Hawk | CSCI | CINF | 40 | 1011 |
| 100001 | Mary | Hawk | CSCI | CINF | 35 | 1011 |
| 100002 | David | Hawk | CSCI | ITEC | 66 | 1012 |
| 100003 | Catherine | Lim | ITEC | CINF | 20 | NULL |
| 100004 | Larry | Johnson | ITEC | NULL | 66 | 1017 |
| 100005 | Linda | Johnson | CINF | ENGL | 13 | 1015 |
| 100006 | Lillian | Johnson | CINF | ITEC | 18 | 1016 |
| 100007 | Ben | Zico | NULL | NULL | 16 | NULL |
| 100008 | Bill | Ching | ARTS | NULL | 90 | NULL |
| 100009 | Linda | King | ARTS | CSCI | 125 | 1018 |
| 100111 | Cathy | Johanson | NULL | NULL | 0 | 1018 |
+--------+-----------+----------+-------+-------+------+---------+
11 rows in set (0.001 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE '0';
Empty set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE '145';
+--------+-----------+----------+-------+-------+------+---------+
| stuId | fname | lname | major | minor | ach | advisor |
+--------+-----------+----------+-------+-------+------+---------+
| 100000 | Tony | Hawk | CSCI | CINF | 40 | 1011 |
| 100001 | Mary | Hawk | CSCI | CINF | 35 | 1011 |
| 100002 | David | Hawk | CSCI | ITEC | 66 | 1012 |
| 100003 | Catherine | Lim | ITEC | CINF | 20 | NULL |
| 100004 | Larry | Johnson | ITEC | NULL | 66 | 1017 |
| 100005 | Linda | Johnson | CINF | ENGL | 13 | 1015 |
| 100006 | Lillian | Johnson | CINF | ITEC | 18 | 1016 |
| 100007 | Ben | Zico | NULL | NULL | 16 | NULL |
| 100008 | Bill | Ching | ARTS | NULL | 90 | NULL |
| 100009 | Linda | King | ARTS | CSCI | 125 | 1018 |
| 100111 | Cathy | Johanson | NULL | NULL | 0 | 1018 |
+--------+-----------+----------+-------+-------+------+---------+
11 rows in set (0.001 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- warning: '' cannot be converted to a number.
MariaDB [toyu]> -- "Warning 1292 Truncated incorrect DOUBLE value: ''"
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE '';
Empty set, 1 warning (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- warning: '' cannot be converted to a number.
MariaDB [toyu]> -- "Warning 1292 Truncated incorrect DOUBLE value: ''"
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE 'Hello world';
Empty set, 1 warning (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE 1.49;
+--------+-----------+----------+-------+-------+------+---------+
| stuId | fname | lname | major | minor | ach | advisor |
+--------+-----------+----------+-------+-------+------+---------+
| 100000 | Tony | Hawk | CSCI | CINF | 40 | 1011 |
| 100001 | Mary | Hawk | CSCI | CINF | 35 | 1011 |
| 100002 | David | Hawk | CSCI | ITEC | 66 | 1012 |
| 100003 | Catherine | Lim | ITEC | CINF | 20 | NULL |
| 100004 | Larry | Johnson | ITEC | NULL | 66 | 1017 |
| 100005 | Linda | Johnson | CINF | ENGL | 13 | 1015 |
| 100006 | Lillian | Johnson | CINF | ITEC | 18 | 1016 |
| 100007 | Ben | Zico | NULL | NULL | 16 | NULL |
| 100008 | Bill | Ching | ARTS | NULL | 90 | NULL |
| 100009 | Linda | King | ARTS | CSCI | 125 | 1018 |
| 100111 | Cathy | Johanson | NULL | NULL | 0 | 1018 |
+--------+-----------+----------+-------+-------+------+---------+
11 rows in set (0.000 sec)
Example:
-- 2. If a Boolean value is expected, null is implicitly type-converted to FALSE.
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts;
Result:
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100002 | 10000 | B- | 3 |
| 100000 | 10001 | A | 2 |
| 100000 | 10002 | B+ | 1 |
| 100002 | 10002 | B+ | 2 |
| 100002 | 10003 | D | 4 |
| 100000 | 10004 | A- | 1 |
| 100007 | 10007 | F | 4 |
| 100000 | 11001 | D | 4 |
+--------+---------+-------+----------+
8 rows in set (0.000 sec)
Example:
-- 3. null is a special value different with 0 or empty string.
SELECT FALSE IS NULL,
TRUE IS NULL,
0 IS NULL,
1 IS NULL,
"" IS NULL,
"Hey" IS NULL,
NULL IS NULL,
NULL IS NOT NULL;
Result:
MariaDB [toyu]> SELECT FALSE IS NULL,
-> TRUE IS NULL,
-> 0 IS NULL,
-> 1 IS NULL,
-> "" IS NULL,
-> "Hey" IS NULL,
-> NULL IS NULL,
-> NULL IS NOT NULL;
+---------------+--------------+-----------+-----------+------------+---------------+--------------+------------------+
| FALSE IS NULL | TRUE IS NULL | 0 IS NULL | 1 IS NULL | "" IS NULL | "Hey" IS NULL | NULL IS NULL | NULL IS NOT NULL |
+---------------+--------------+-----------+-----------+------------+---------------+--------------+------------------+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+---------------+--------------+-----------+-----------+------------+---------------+--------------+------------------+
1 row in set (0.000 sec)
Example:
-- 4. Comparing null to other values return null, which is converted to false.
SELECT NULL > 3,
NULL <= 3,
5 >= NULL,
5 < NULL,
NULL > NULL,
NULL <= NULL;
SELECT *
FROM student
WHERE NULL > 3;
-- Comparisons must be mindful of null.
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts >= 2;
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts < 2;
SELECT e.*
FROM enroll AS e;
-- Q. List all enrollment records without 2 or more n_alerts.
-- Naive solution
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts < 2;
-- Q. List all enrollment records without 2 or more n_alerts.
-- More likely solution
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts IS NULL
OR e.n_alerts < 2;
-- Q. List all enrollment records without a value in n_alerts.
-- incorrect answer.
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts <> NULL;
-- Q. List all enrollment records without a value in n_alerts.
-- correct answer.
SELECT e.*
FROM enroll AS e
WHERE e.n_alerts IS NOT NULL;
Result:
MariaDB [toyu]> -- 4. Comparing null to other values return null, which is converted to false.
MariaDB [toyu]> SELECT NULL > 3,
-> NULL <= 3,
-> 5 >= NULL,
-> 5 < NULL,
-> NULL > NULL,
-> NULL <= NULL;
+----------+-----------+-----------+----------+-------------+--------------+
| NULL > 3 | NULL <= 3 | 5 >= NULL | 5 < NULL | NULL > NULL | NULL <= NULL |
+----------+-----------+-----------+----------+-------------+--------------+
| NULL | NULL | NULL | NULL | NULL | NULL |
+----------+-----------+-----------+----------+-------------+--------------+
1 row in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT *
-> FROM student
-> WHERE NULL > 3;
Empty set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- Comparisons must be mindful of null.
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts >= 2;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100002 | 10000 | B- | 3 |
| 100000 | 10001 | A | 2 |
| 100002 | 10002 | B+ | 2 |
| 100002 | 10003 | D | 4 |
| 100007 | 10007 | F | 4 |
| 100000 | 11001 | D | 4 |
+--------+---------+-------+----------+
6 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts < 2;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100000 | 10000 | A | 0 |
| 100001 | 10001 | A- | 0 |
| 100000 | 10002 | B+ | 1 |
| 100000 | 10003 | C | 0 |
| 100004 | 10003 | A | 0 |
| 100000 | 10004 | A- | 1 |
| 100005 | 10004 | A- | 0 |
| 100005 | 10005 | A- | 0 |
| 100008 | 10007 | C- | 0 |
| 100007 | 10008 | A- | 0 |
+--------+---------+-------+----------+
10 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100000 | 10000 | A | 0 |
| 100001 | 10000 | NULL | NULL |
| 100002 | 10000 | B- | 3 |
| 100000 | 10001 | A | 2 |
| 100001 | 10001 | A- | 0 |
| 100000 | 10002 | B+ | 1 |
| 100002 | 10002 | B+ | 2 |
| 100000 | 10003 | C | 0 |
| 100002 | 10003 | D | 4 |
| 100004 | 10003 | A | 0 |
| 100005 | 10003 | NULL | NULL |
| 100000 | 10004 | A- | 1 |
| 100004 | 10004 | B+ | NULL |
| 100005 | 10004 | A- | 0 |
| 100006 | 10004 | C+ | NULL |
| 100005 | 10005 | A- | 0 |
| 100006 | 10005 | A | NULL |
| 100005 | 10006 | B+ | NULL |
| 100007 | 10007 | F | 4 |
| 100008 | 10007 | C- | 0 |
| 100007 | 10008 | A- | 0 |
| 100000 | 11001 | D | 4 |
+--------+---------+-------+----------+
22 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- Q. List all enrollment records without 2 or more n_alerts.
MariaDB [toyu]> -- Naive solution
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts < 2;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100000 | 10000 | A | 0 |
| 100001 | 10001 | A- | 0 |
| 100000 | 10002 | B+ | 1 |
| 100000 | 10003 | C | 0 |
| 100004 | 10003 | A | 0 |
| 100000 | 10004 | A- | 1 |
| 100005 | 10004 | A- | 0 |
| 100005 | 10005 | A- | 0 |
| 100008 | 10007 | C- | 0 |
| 100007 | 10008 | A- | 0 |
+--------+---------+-------+----------+
10 rows in set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- Q. List all enrollment records without 2 or more n_alerts.
MariaDB [toyu]> -- More likely solution
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts IS NULL
-> OR e.n_alerts < 2;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100000 | 10000 | A | 0 |
| 100001 | 10000 | NULL | NULL |
| 100001 | 10001 | A- | 0 |
| 100000 | 10002 | B+ | 1 |
| 100000 | 10003 | C | 0 |
| 100004 | 10003 | A | 0 |
| 100005 | 10003 | NULL | NULL |
| 100000 | 10004 | A- | 1 |
| 100004 | 10004 | B+ | NULL |
| 100005 | 10004 | A- | 0 |
| 100006 | 10004 | C+ | NULL |
| 100005 | 10005 | A- | 0 |
| 100006 | 10005 | A | NULL |
| 100005 | 10006 | B+ | NULL |
| 100008 | 10007 | C- | 0 |
| 100007 | 10008 | A- | 0 |
+--------+---------+-------+----------+
16 rows in set (0.000 sec)
MariaDB [toyu]> -- Q. List all enrollment records without a value in n_alerts.
MariaDB [toyu]> -- incorrect answer.
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts <> NULL;
Empty set (0.000 sec)
MariaDB [toyu]>
MariaDB [toyu]> -- Q. List all enrollment records without a value in n_alerts.
MariaDB [toyu]> -- correct answer.
MariaDB [toyu]> SELECT e.*
-> FROM enroll AS e
-> WHERE e.n_alerts IS NOT NULL;
+--------+---------+-------+----------+
| stuId | classId | grade | n_alerts |
+--------+---------+-------+----------+
| 100000 | 10000 | A | 0 |
| 100002 | 10000 | B- | 3 |
| 100000 | 10001 | A | 2 |
| 100001 | 10001 | A- | 0 |
| 100000 | 10002 | B+ | 1 |
| 100002 | 10002 | B+ | 2 |
| 100000 | 10003 | C | 0 |
| 100002 | 10003 | D | 4 |
| 100004 | 10003 | A | 0 |
| 100000 | 10004 | A- | 1 |
| 100005 | 10004 | A- | 0 |
| 100005 | 10005 | A- | 0 |
| 100007 | 10007 | F | 4 |
| 100008 | 10007 | C- | 0 |
| 100007 | 10008 | A- | 0 |
| 100000 | 11001 | D | 4 |
+--------+---------+-------+----------+
16 rows in set (0.000 sec)
Interpretation of null values
Example:
Consider the attribute SpouseName. A Null value may mean:
How do we distinguish between the three meanings of the null value in this case?
By using an extra attribute, such as MaritalStatus.
... | SpouseName | MaritalStatus | ... |
Null | Married | ||
Null | Not married | ||
Null | Null |
3. Keys
Example:
Consider:
MariaDB [toyu]> SELECT * FROM faculty;
+-------+----------+----------+----------+---------------------+
| facId | fname | lname | deptCode | rank |
+-------+----------+----------+----------+---------------------+
| 1011 | Paul | Smith | CSCI | Professor |
| 1012 | Mary | Tran | CSCI | Associate Professor |
| 1013 | David | Love | CSCI | NULL |
| 1014 | Sharon | Mannes | CSCI | Assistant Professor |
| 1015 | Daniel | Kim | CINF | Professor |
| 1016 | Andrew | Byre | CINF | Associate Professor |
| 1017 | Deborah | Gump | ITEC | Professor |
| 1018 | Art | Allister | ARTS | Assistant Professor |
| 1019 | Benjamin | Yu | ITEC | Lecturer |
| 1020 | Katrina | Bajaj | ENGL | Lecturer |
| 1021 | Jorginlo | Neymar | ACCT | Assistant Professor |
+-------+----------+----------+----------+---------------------+
11 rows in set (0.001 sec)
MariaDB [toyu]> SELECT * FROM department;
+----------+------------------------------+------------+----------+
| deptCode | deptName | schoolCode | numStaff |
+----------+------------------------------+------------+----------+
| ACCT | Accounting | BUS | 10 |
| ARTS | Arts | HSH | 5 |
| CINF | Computer Information Systems | CSE | 5 |
| CSCI | Computer Science | CSE | 12 |
| ENGL | English | HSH | 12 |
| ITEC | Information Technology | CSE | 4 |
| MATH | Mathematics | CSE | 7 |
+----------+------------------------------+------------+----------+
7 rows in set (0.001 sec)
Consider the tables student and enroll:
Classroom Exercise:
(1) Give a realistic example of a relation with two candidate keys. State the assumptions you have made.
(2) A relation R has an arity of 4. What are the possible minimum and maximum number of superkeys of R? What are the possible minimum and maximum number of candidate keys of R?
What about the general case?
More about keys:
Consider the example above. The attribute deptCode is a foreign key in the relation faculty, referencing department(deptCode)
Likewise, stuid is a foreign key in the relation Enroll: stuid references student(stuid)
Note that the student table has three foreign keys.
Example:
The list of all foreign keys in toyu:
1. Student(advisor) references Faculty(facId)
2. Student(major) references Department(deptCode)
3. Student(minor) references Department(deptCode)
4. Faculty(deptCode) references Department(deptCode)
5. Department(schoolCode) references School(schoolCode)
6. Enroll(stuId) references Student(stuId)
7. Enroll(classId) references Class(classId)
8. Enroll(grade) references Grade(grade)
9. Class(courseId) references Course(courseId)
10. Class(facId) references Faculty(facId)
Example:
-- INNER JOINMariaDB [toyu]> SELECT * FROM faculty;
+-------+----------+----------+----------+---------------------+
| facId | fname | lname | deptCode | rank |
+-------+----------+----------+----------+---------------------+
| 1011 | Paul | Smith | CSCI | Professor |
| 1012 | Mary | Tran | CSCI | Associate Professor |
| 1013 | David | Love | CSCI | NULL |
| 1014 | Sharon | Mannes | CSCI | Assistant Professor |
| 1015 | Daniel | Kim | CINF | Professor |
| 1016 | Andrew | Byre | CINF | Associate Professor |
| 1017 | Deborah | Gump | ITEC | Professor |
| 1018 | Art | Allister | ARTS | Assistant Professor |
| 1019 | Benjamin | Yu | ITEC | Lecturer |
| 1020 | Katrina | Bajaj | ENGL | Lecturer |
| 1021 | Jorginlo | Neymar | ACCT | Assistant Professor |
+-------+----------+----------+----------+---------------------+
11 rows in set (0.000 sec)
MariaDB [toyu]> SELECT * FROM department;
+----------+------------------------------+------------+----------+
| deptCode | deptName | schoolCode | numStaff |
+----------+------------------------------+------------+----------+
| ACCT | Accounting | BUS | 10 |
| ARTS | Arts | HSH | 5 |
| CINF | Computer Information Systems | CSE | 5 |
| CSCI | Computer Science | CSE | 12 |
| ENGL | English | HSH | 12 |
| ITEC | Information Technology | CSE | 4 |
| MATH | Mathematics | CSE | 7 |
+----------+------------------------------+------------+----------+
7 rows in set (0.000 sec)
MariaDB [toyu]> SELECT s.fname, s.lname, s.advisor, f.`rank`
-> FROM student AS s INNER JOIN faculty AS f
-> ON (s.advisor = f.facId);
+---------+----------+---------+---------------------+
| fname | lname | advisor | rank |
+---------+----------+---------+---------------------+
| Tony | Hawk | 1011 | Professor |
| Mary | Hawk | 1011 | Professor |
| David | Hawk | 1012 | Associate Professor |
| Larry | Johnson | 1017 | Professor |
| Linda | Johnson | 1015 | Professor |
| Lillian | Johnson | 1016 | Associate Professor |
| Linda | King | 1018 | Assistant Professor |
| Cathy | Johanson | 1018 | Assistant Professor |
+---------+----------+---------+---------------------+
8 rows in set (0.000 sec)