SEN2104 · Week 3 · Introduction to Relational Data Model

The relational model, keys and ER-to-table mapping

Relation, schema, instance, domain; super/candidate/primary/foreign key; referential integrity and the rules for turning an ER diagram into tables. Both the algebra and the SQL questions rely on these tables.

relationtupleattributedomainatomicrelation schemarelation instancedegreecardinalitysuperkeycandidate keyprimary keyforeign keyreferential integrityschema diagramNULL

The ER diagram was the design on paper. The relational model is its counterpart in the computer: everything is a table. This week you learn two things. The first is terminology and keys; relational algebra, SQL and normalization are built on these concepts, and you cannot get through week 9 without knowing what a candidate key is. The second is the rules for converting ER to tables; almost every year the midterm has a “convert this diagram into relation schemas” question.

Golden rules:

  1. The schema is fixed, the instance varies. Constraints belong to the schema.
  2. A key must be minimal. If it has an extra attribute, it is a superkey, not a candidate.
  3. An FK requires that the row it references exists. The value either equals a real PK or is NULL.
  4. M:N is always a separate table. 1:N becomes a column on the N side.

Terminology

In the relational model, data lives in tables. By its mathematical name a table is a relation, a row is a tuple and a column is an attribute. The student relation we use in the course:

stu_idnamedept_nametot_cred
S1AdaCS60
S2BoraCS30
S3CemEE45
S4DefneMATH90
S5EceCS15
S6FiratEE0
S7GizemNULL10
  • Domain: the set of values an attribute may take. For tot_cred, non-negative integers.
  • Atomicity: a single, indivisible value in each cell. Writing “555-0101, 555-0102” in one cell breaks the relational model; this is the basis of 1NF (week 9).
  • NULL: the value is unknown or does not exist. S7’s department is not known yet.
  • Degree: the number of attributes, here 4. Cardinality: the number of tuples, here 7.

A relation is a set: rows have no order and there cannot be two identical rows. The order of columns is also unimportant in theory, because attributes are referred to by name.

Schema and instance

A relation schema is the structure of the relation: student(stu_id, name, dept_name, tot_cred). A relation instance is the rows at a given moment. The programming counterpart: the schema is the variable type, the instance is the current value of the variable. When Ada graduates, the instance changes and the schema stays the same.

The schemas we use throughout the course:

department (dept_name, building, budget)
instructor (inst_id, name, dept_name -> department, salary)
student    (stu_id, name, dept_name -> department, tot_cred)
course     (course_id, title, dept_name -> department, credits)
teaches    (inst_id -> instructor, course_id -> course)
takes      (stu_id -> student, course_id -> course, grade)

Since we cannot underline here, the primary key is the first column(s); for teaches and takes the first two columns together. The arrow -> shows what a foreign key points to. In a schema diagram, each table is a box, the PK is underlined, and FKs are connected by arrows to the PK of the table they reference.

Keys

Superkey: a set of attributes whose values identify every row uniquely. For student, {stu_id}, {stu_id, name} and {stu_id, name, dept_name, tot_cred} are all superkeys.

Candidate key: a minimal superkey, that is, one from which no attribute can be removed. {stu_id} is a candidate; {stu_id, name} is not, because it is still a key after dropping name.

Primary key: the one the designer chooses among the candidate keys. A relation may have more than one candidate key (a student number and a national ID number); you pick one as the PK and put UNIQUE on the other.

Foreign key: one or more attributes in a relation that reference the PK of another (or the same) relation. takes.stu_id → student.stu_id. The referencing side is the referencing relation, the other is the referenced relation.

Reading keys from an instance

You can check with SQL whether a set has repeats in the instance:

SELECT stu_id, course_id FROM takes
GROUP BY stu_id, course_id HAVING COUNT(*) > 1;   -- empty: no repeats
SELECT stu_id, grade FROM takes
GROUP BY stu_id, grade HAVING COUNT(*) > 1;       -- 3 groups repeat
(first query: no rows)
S1 | A
S1 | B
S4 | A

PITFALL · instance data does not prove a key. name has no repeats among the current 7 students, but it is not a key: a second “Ada” may register. An instance gives only negative proof: dept_name has repeats (CS three times), so it is definitely not a key. In the exam, watch the difference between “this instance” and “the schema”.

Counting superkeys

A set of attributes is a superkey if it contains at least one candidate key. For R(A, B, C, D), if the only candidate key is {A}, the other three attributes can be added freely: 23=82^3 = 8 superkeys. If there are two candidate keys {A} and {B, C}, apply inclusion-exclusion:

∣SA∪SBC∣=23+22−21=8+4−2=10|S_A \cup S_{BC}| = 2^3 + 2^2 - 2^1 = 8 + 4 - 2 = 10

The last term is the sets that contain both A and B,C: {A,B,C} and {A,B,C,D}.

Integrity constraints and referential integrity

  • Entity integrity: the PK value cannot repeat and cannot be NULL.
  • Referential integrity: an FK value is either NULL or a PK value that actually exists in the referenced table.

What we tried on the sample database with PRAGMA foreign_keys = ON:

OperationResultWhy
INSERT INTO takes VALUES ('S9','CS101','A')rejectedthere is no student S9
INSERT INTO instructor VALUES ('I7','Ozturk','PHYS',65000)rejectedthere is no PHYS department
INSERT INTO student VALUES ('S8','Hakan',NULL,0)acceptedan FK may be NULL
INSERT INTO student VALUES ('S1','Zeynep','CS',0)rejectedduplicate PK
DELETE FROM department WHERE dept_name='CS'rejectedinstructors, students and courses reference CS
Deleting S5’s takes rows, then deleting S5acceptednothing references it any more

What happens when a referenced row is deleted is chosen in the FK definition: the default NO ACTION/RESTRICT rejects it, ON DELETE CASCADE deletes the referencing rows too, and ON DELETE SET NULL sets the FK to NULL.

PITFALL · SQLite and NULL primary keys. In standard SQL a PK can never be NULL. Because of a historical bug, SQLite accepts NULL in a TEXT PRIMARY KEY column (tried in the verification run); if you add NOT NULL, it rejects it. Also, in SQLite FK checking is off by default and PRAGMA foreign_keys = ON is needed. PostgreSQL and MySQL (InnoDB) enforce these on their own.

Rules for converting ER to a relational schema

ER constructHow it becomes tables
Strong entityIts own table; simple attributes become columns, the key becomes the PK
Composite attributeOnly the leaf parts become columns: name → first_name, last_name
Multivalued attributeSeparate table: inst_phone(inst_id, phone), PK is both, inst_id is an FK
Derived attributeNo column (computed with a view if needed)
Weak entityTable; the owner’s PK is added as an FK, PK = owner PK + discriminator
Identifying relationshipNo table, it is already in the weak entity’s table
1:N relationshipThe PK of the “1” side as an FK column on the N side; the relationship attributes go to the N side too
Total participation (N side)That FK column is NOT NULL
1:1 relationshipFK + UNIQUE on one side (preferably the side with total participation), or a separate table
M:N relationshipSeparate table: both PKs + relationship attributes, PK = combination of both PKs
n-ary (ternary) relationshipSeparate table: the PKs of all participants

Worked example

Scenario: department; instructor (composite name, multivalued phone, N:1 total to department); student (one advisor instructor, 1:N); course; section (weak entity of course); takes (M:N between student and section, grade); dean (1:1 between department and instructor, to be kept in a separate table).

department (dept_name, building)
instructor (inst_id, first_name, last_name, dept_name -> department NOT NULL)
inst_phone (inst_id -> instructor, phone)                         PK: both
student    (stu_id, name, advisor_id -> instructor)
course     (course_id, title)
section    (course_id -> course, sec_id, semester, year)          PK: all four
takes      (stu_id -> student, course_id, sec_id, semester, year, grade)
           PK: the first five ; FK (course_id, sec_id, semester, year) -> section
dean       (dept_name -> department, inst_id -> instructor UNIQUE) PK: dept_name

That makes 8 tables. We built the schema in SQLite and tried it: a registration for a non-existent section was rejected because of the composite FK, making the same instructor dean of two departments was rejected because of UNIQUE, an instructor without a department was rejected because of NOT NULL, and when a course was deleted its sections went away through CASCADE.

Note: since takes is tied to a section, its FK is a composite key with four columns. An FK must contain all columns of the PK it references; you cannot link only course_id to section.

Three ways for specialization

person(pid, name) → student(tot_cred), employee(salary):

MethodTablesWhen
1. Super + sub tablesperson(pid, name), student(pid, tot_cred), employee(pid, salary)Works in every case; the pid of the sub-tables is an FK to person
2. Only sub tablesstudent(pid, name, tot_cred), employee(pid, name, salary)Only if total and disjoint
3. Single tableperson(pid, name, ptype, tot_cred, salary)If there are few subsets; unrelated columns are NULL

Method 2 stores the same person’s name twice when overlapping, and cannot store a person who is in no subset when partial.

Common mistakes

Wrong ideaThe truth
Degree = number of rowsDegree is columns, cardinality is the number of rows
{stu_id, name} is a candidate keyIt is a superkey; not minimal
No repeats in the instance, so it is a keyThe constraint belongs to the schema; an instance can only refute
An FK cannot be NULLIt can; a PK cannot
The FK must have the same nameThe name is free (advisor_id → inst_id); type and value must match
Put the M:N relationship as a column on one sideA separate table is required
In 1:N, put the FK on the “1” sideOn the N side; otherwise one cell would need many values
Write the multivalued phone in one column with commasAtomicity breaks; use a separate table
The PK of a weak entity is just the discriminatorOwner PK + discriminator
In 1:1 an FK is enoughFK + UNIQUE; otherwise it becomes 1:N

Test yourself

Exam-style questions. Solve them on paper first, then reveal the answer.

Question 1easy

What are the degree and the cardinality of the student relation in the sample database?

Show answer
degree 4, cardinality 7

Degree = number of attributes: stu_id, name, dept_name, tot_cred → 4. Cardinality = number of rows (tuples): S1 to S7 → 7. Do not mix them up: the degree depends on the schema, the cardinality on the instance.

Question 2easy

In student(stu_id, name, dept_name, tot_cred), stu_id is the primary key. Is {stu_id, name} a superkey? Is it a candidate key?

Show answer
superkey: yes; candidate key: no

stu_id already identifies every row uniquely; whatever you add next to it is still unique: a superkey. A candidate key must be minimal. When you remove name, the remaining {stu_id} is still a key, so {stu_id, name} is not minimal.

Question 3medium

In the current student instance no two students have the same name. Can we declare name a candidate key?

Show answer
no

A key is a constraint of the schema and must hold for all future valid instances. A second "Ada" may register tomorrow. In the verification run name was unique in this instance, but that is a coincidence. Instance data can only show that something is not a key (dept_name has repeats, so it cannot be a key).

Question 4easy

What is the primary key of takes(stu_id, course_id, grade)? Explain why neither attribute alone works.

Show answer
{stu_id, course_id}

stu_id repeats (S1 is in four rows) and course_id repeats (CS101 is in four rows). The pair (stu_id, course_id) is unique in the instance, and the business rule is "a student takes a course once". Adding grade is unnecessary, and (stu_id, grade) repeats (S1 has two A grades).

Question 5medium

A relation R(A, B, C, D) has exactly two candidate keys: {A} and {B, C}. How many superkeys does R have?

Show answer
10

Subsets that contain A: the remaining B, C, D are free → 2^3 = 8. Those that contain {B,C}: A and D are free → 2^2 = 4. Those that contain both ({A,B,C} and {A,B,C,D}) were counted twice → 2. Inclusion-exclusion: 8 + 4 − 2 = 10.

Question 6medium

With foreign keys enforced, which statement is rejected?

  1. INSERT INTO student VALUES ('S8','Hakan',NULL,0)
  2. INSERT INTO takes VALUES ('S9','CS101','A')
  3. INSERT INTO takes VALUES ('S6','BI100',NULL)
  4. UPDATE student SET tot_cred = 20 WHERE stu_id = 'S7'
Show answer
INSERT INTO takes VALUES ('S9','CS101','A')

takes.stu_id references student.stu_id (foreign key). There is no student named S9: referential integrity violation. Inserting a student whose dept_name is NULL is allowed, because an FK value may be NULL. S6 and BI100 both exist. tot_cred is not a key.

Question 7medium

What happens to DELETE FROM department WHERE dept_name = 'CS'; if foreign keys are enforced with the default action?

Show answer
rejected, because instructor, student and course rows reference CS

The default behavior (NO ACTION / RESTRICT) does not allow deleting a referenced row. CS is referenced by I1, I2 (instructor), S1, S2, S5 (student) and CS101, CS201, CS305 (course). If you want to delete it, you must first delete those, or define the FK with ON DELETE CASCADE / SET NULL.

Question 8medium

Map the M:N relationship takes between student(stu_id, ...) and course(course_id, ...) with relationship attribute grade to a relation schema. Give the primary key and the foreign keys.

Show answer
takes(stu_id, course_id, grade), PK (stu_id, course_id), FK stu_id → student, FK course_id → course

An M:N relationship always becomes a separate table. The columns are the primary keys of both sides + the attributes of the relationship. The primary key is the combination of the keys of both sides; each one is an FK to its own table.

Question 9medium

Map the weak entity set section (discriminator: sec_id, semester, year; attribute room) owned by course(course_id, ...).

Show answer
section(course_id, sec_id, semester, year, room), PK (course_id, sec_id, semester, year), FK course_id → course

The table of a weak entity takes the PK of the owner as an FK. PK = owner PK + discriminator. The identifying relationship (sec_course) does not become a separate table; its information is already in the course_id of section. Since a section is meaningless once its owner is deleted, the FK is usually defined with ON DELETE CASCADE.

Question 10hard

An ER design has the strong entities department, instructor (composite name, multivalued phone), student and course; the weak entity section (owner course); the relationships inst_dept (N:1, instructor total), advisor (1:N, instructor to student), takes (M:N between student and section) and dean (1:1 between department and instructor). Fold every 1:N / N:1 relationship into the N side, but keep dean as its own table. How many tables do you get?

Show answer
8

Entities: department, instructor, student, course, section → 5. The multivalued phone → inst_phone → 6. The M:N takes → 7. dean as its own table → 8. inst_dept goes into instructor as a dept_name NOT NULL column (total participation means NOT NULL). advisor becomes an advisor_id column in student. sec_course is represented by the course_id in section. The composite name is split into columns (first_name, last_name) and adds no table. The schema was built in SQLite and 8 tables were counted.

Question 11hard

In the design above, dean is a 1:1 relationship between department and instructor stored as dean(dept_name, inst_id). Which constraints make it truly 1:1?

Show answer
dept_name PRIMARY KEY and inst_id UNIQUE (both foreign keys)

dept_name PK: a department has at most one dean. inst_id UNIQUE: an instructor is the dean of at most one department. If you add only one of them, the relationship becomes 1:N. In the verification run, making the same instructor dean of a second department was rejected because of UNIQUE.

Question 12hard

person(pid, name) is specialized into student(tot_cred) and employee(salary), and the specialization is total and disjoint. Which mapping uses the fewest tables without NULL columns, and why is it unsafe if the specialization were overlapping?

Show answer
two tables student(pid, name, tot_cred) and employee(pid, name, salary); overlapping would store name twice

Method 1: person + one table per subset (3 tables, the sub-tables have pid as an FK to the superset). Method 2: only the subsets, each copying the superset attributes (2 tables). Method 3: a single table + a type column (1 table, but unrelated columns are NULL). If the specialization is total and disjoint, method 2 keeps each person in exactly one table, with no NULLs. If it were overlapping, the name of a person who is both student and employee would repeat in two tables and could become inconsistent; if it were partial, a person in no subset could not be stored anywhere.

Verification: The sample university database was built with node:sqlite. Key claims were checked with GROUP BY ... HAVING COUNT(*) > 1, FK violations with real INSERT/DELETE under PRAGMA foreign_keys=ON, superkey counts with JS subset counting, and the ER mappings by building the schema in SQLite and counting the tables (verify/SEN2104/03.mjs, 32 checks).

Review card

Relation = table, tuple = row, attribute = column, domain = allowed values (atomic). Schema = structure (does not change), instance = the rows right now (changes). Degree = number of columns, cardinality = number of rows. Superkey: identifies the row uniquely. Candidate key: minimal superkey. Primary key: the chosen candidate. A key is a constraint of the schema: instance data cannot prove that something is a key, it can show that it is not. Counting superkeys: if {A} is the key, 2^3 = 8 in R(ABCD); with two keys use inclusion-exclusion. FK: references the PK of another table, can be NULL, INSERT is rejected if the referenced row does not exist. Deleting a referenced row: RESTRICT by default; define either CASCADE or SET NULL. ER -> table: strong entity = table; composite = leaf columns; multivalued = separate table (id, value). Weak: owner PK + discriminator = PK, owner PK is the FK (CASCADE). 1:N -> FK column on the N side. Total participation -> NOT NULL. M:N -> separate table, PK = combination of both PKs. 1:1 -> FK + UNIQUE. Specialization: super+sub (3) / only subs (total+disjoint) / single table + type.