The relational model and the ER-to-table recipe

After this lesson you will read a relation as a set of tuples with named attributes, test whether a set of attributes is a key, check a referential constraint, and turn any binary relationship of an ER diagram into tables — knowing from its two (min,max) pairs where the foreign key goes.

Three sales, three customers. Heather bought S1 and S3, Steven bought S2, Dave has bought nothing yet. Three designs store who bought what:

Same facts, three fates: one is not even a relation, one is a legal relation the slides tell you not to build, one is the slides' answer. By the end of the lesson two small pairs on the ER diagram — (1,1) next to Sale, (0,N) next to Customer — will tell you which is which, before you write a single row.

A relation is a set of tuples — with names

Page 85 in four lines: the relational model was "Proposed by E. F. Codd in 1970", "Made available in commercial DBMSs in 1981"; "It is based on (a variant of) the mathematical notion of relation"; "Relations are naturally represented by means of tables". The variant adds names, nulls and constraints.

Start with four football games (p. 88): Juve–Lazio 3–1, Lazio–Milan 2–0, Juve–Roma 1–2, Roma–Milan 0–1. Each is an ordered list of four values: string, string, integer, integer.

Cartesian product of the sets \(D_1, \dots, D_n\) ("n sets, not necessarily distinct") — "the set of all (ordered) n-tuples \((d_1, d_2, \dots, d_n)\) such that \(d_1 \in D_1, \dots, d_n \in D_n\)". A mathematical relation on \(D_1, \dots, D_n\) is "a subset of the cartesian product" (p. 86).

\[ \begin{aligned} &D_1 \times \dots \times D_n \\ &\quad = \{ (d_1, \dots, d_n) \mid d_i \in D_i \} \end{aligned} \] \[ r \subseteq D_1 \times D_2 \times \dots \times D_n \]
\(D_i\)
the domains
\(n\)
the degree
\(|r|\)
the cardinality: the number of n-tuples, "in practice, it is always finite"

So games \(\subseteq\) string × string × integer × integer has degree 4 and cardinality 4. Being a set, it has "no ordering between n-tuples", and "the n-tuples are distinct from one another" (p. 87). Inside a tuple, order rules: "the i-th value come from the i-th domain".

"Cardinality is the (min,max) pair." Not here. The word has two meanings in this course: the number of tuples of a relation (p. 86), and the (min,max) pair of an ER relationship (lesson 6), which rules the second half of this lesson.

The domain string plays two roles here, home team and visitors: "Each of the domains has two roles, distinguished by means of position" — "The structure is positional" (p. 88). Swap the first two values and Juve's home win becomes Lazio's. The relational data model wants "a non-positional structure": it associates "a unique name (attribute) with each domain; it 'describes' the role of the domain" (p. 89).

1 2 3 4 Juve Lazio 3 1 swap 1 and 2 Lazio Juve 3 1 another game!

Before: positional (p. 88)

one order another order HomeTeam: Juve VisitingTeam: Lazio HomeGoals: 3 VisitorGoals: 1 VisitorGoals: 1 HomeGoals: 3 VisitingTeam: Lazio HomeTeam: Juve the same game

After: named attributes (p. 89)

Fig. 1. In the mathematical relation only the position tells the home team from the visitors: swap two values and Juve's 3–1 at home becomes Lazio's. With attribute names the order carries no information: the two cards on the right are one and the same tuple.

With names, a tuple is a set of attribute–value pairs and the column order means nothing. In Python terms, ('Juve', 'Lazio', 3, 1) became {'HomeTeam': 'Juve', …}: a tuple became a dict.

References are values, not arrows

Page 90 draws every row of Exams as two arrows, one into Students and one into Courses, and stops there. The relational model stores no arrows: Exams holds the values that identify the student and the course, and a reference is the same value in two tables.

Students Exams Courses RegNum 6554 8765 9283 3456 Student Grade Course 30 24 28 26 Code 01 02 04 an arrow is not a value

Before: arrows (the slide, p. 90)

Students Exams Courses RegNum 6554 8765 9283 3456 Student Grade Course 3456 3456 9283 6554 30 24 28 26 04 02 01 01 Code 01 02 04 equal values, no arrows

After: values (not on the slide)

Fig. 2. Page 90 draws each exam as two arrows. The relational model keeps, in the Student and Course columns of Exams, the key values themselves (right; this half is not on the slide). Rossi Maria's two exams both carry 3456; student 8765 has no exam, course 01 has two.

Values beat arrows: 3456 means something on its own, survives a copy to another system, and can be checked by a rule — the subject of section 3.

Schema and instance

Page 91 fixes the words. A relation schema is "a name (of the relation) R with a set of attributes", a database schema "a set of relation schemas with different names"; an instance is the "set r of tuples on X" a schema holds now, one relation per schema for a database:

\[ R(A_1, \dots, A_n) \] \[ \mathbf{R} = \{ R_1(X_1), \dots, R_n(X_n) \} \] \[ \mathbf{r} = \{ r_1, \dots, r_n \} \]
\(R(A_1, \dots, A_n)\)
relation schema; its instance \(r\) is a set of tuples
\(\mathbf{R}\)
database schema
\(\mathbf{r}\)
database instance: one relation \(r_i\) per \(R_i\)

The schema is stable; the instance changes with every insert.

Nulls, constraints and keys

The structure is rigid (p. 92): "information is represented by means of tuples" and "tuples have to conform to relation schemas". What goes into a cell when there is no value? A null, of "(at least) 3 types" (p. 93):

The three nulls of p. 93; the examples are not on the slide.
TypeThe slide's definitionExample
unknown value"there is a domain value, but it is not known"a student's phone number that exists but was never recorded
non-existent value"the attribute is not applicable for the tuple"the spouse of someone who is not married
no-information value"we don't know whether a value exists or not; this is the disjunction (logical or) of the other two"a "second phone" field: maybe there is one, maybe not

The line to remember: "DBMSs do not distinguish between the types: they implicitly adopt the no-information value". SQL has one NULL — which is why NULL = NULL is not true there and you write IS NULL.

Constraints are predicates

An integrity constraint is "a property that must be satisfied by all meaningful database instances"; seen "as a predicate", an instance "is legal if it satisfies all integrity constraints" (p. 94). Intrarelational constraints stay in one relation — domain constraints check one value (a grade between 18 and 30), tuple constraints one tuple (honours only with a 30); interrelational ones span several relations. Keys are intrarelational, referential constraints interrelational.

Superkeys and keys

A key is "a set of attributes that uniquely identifies tuples in a relation"; p. 95 makes it precise in two steps.

Superkey — "a set of attributes K is a superkey for a relation r if r does not contain two distinct tuples \(t_1\) and \(t_2\) with \(t_1[K] = t_2[K]\)". Key — "K is a key for r if K is a minimal superkey (that is, there exists no other superkey K' of r that is contained in K as proper subset)" (p. 95).

\[ \forall\, t_1, t_2 \in r: \] \[ t_1[K] = t_2[K] \;\Rightarrow\; t_1 = t_2 \]
\(t[K]\)
the values of \(t\) on the attributes of \(K\)
key
no superkey \(K' \subsetneq K\)

Page 96 tries it on five students:

Students, as printed on p. 96.
RegNumSurnameFirstNameBirthDateDegreeProg
284328SmithLuigi29/04/59Computing
296328SmithJohn29/04/59Computing
587614SmithLucy01/05/61Engineering
934856BlackLucy01/05/61Fine Art
965536BlackLucy05/03/58Fine Art

"RegNum is a key": five different values, and one attribute is minimal by force. The second claim, "Surname, Firstname, BirthDate is another key", takes four checks:

  1. Superkey? The five (Surname, FirstName, BirthDate) triples are all different: no two distinct tuples agree on them.

  2. Drop BirthDate. (Black, Lucy) occurs in 934856 and 965536: {Surname, FirstName} is not a superkey.

  3. Drop FirstName. (Smith, 29/04/59) occurs in 284328 and 296328: not a superkey.

  4. Drop Surname. (Lucy, 01/05/61) occurs in 587614 and 934856: not a superkey.

  5. Minimal. Smaller subsets lie inside these pairs, and tuples that agree on a set agree on its subsets. "no proper subset is also a superkey" (p. 96): a key.

The same test on {FirstName, BirthDate, DegreeProg} finds five different triples and only repeated pairs: on this instance, a key nobody would declare. Hence p. 97: constraints "correspond to properties in the real world", so "they are relevant at the schema level", and "individual instances could satisfy ('by chance') other constraints". An instance can refute a key, never prove one.

"{RegNum, Surname} is a key: its values never repeat." It is a superkey, not a key: drop Surname and RegNum alone still identifies. Every superset of a superkey is a superkey; only the minimal ones are keys. And every relation has a key: having no duplicate tuples, the set of all its attributes is a superkey.

"The presence of nulls in keys has to be limited", so "for each relation we select a primary key on which nulls are not allowed"; it is underlined, and "References between relations are realized through primary keys" (p. 98). A key with a null could neither tell its tuple apart nor be pointed at.

A key is a minimal set of attributes that never takes the same value twice in a legal instance; the primary key is the one chosen, underlined, never null.

Referential constraints: every value must find its row

Values link the tables — "Pieces of data in different relations are correlated by means of values of (primary) keys" — so nothing physical stops a value from pointing nowhere. "Referential integrity constraints are imposed in order to guarantee that the values refer to actual values in the referenced relation" (p. 99).

The slides' example (p. 100) is a database of traffic offences from 1992: Offences(Code, Date, Officer, Dept, Registration), Officers(RegNum, Surname, FirstName) and Cars(Registration, Dept, Owner). Look at the key of Cars: plate 6544 XY appears twice, with Dept 75 (Cordon Edouard's car) and with Dept 47 (Mimault Bernard's). The plate alone does not identify a car; the pair (Registration, Dept) does.

Referential constraint — it "imposes to the values on a set X of attributes of a relation \(R_1\) to appear as values for the primary key of another relation \(R_2\)". In the example: "the attribute Officer of Offences and relation Officers" and "the attributes Registration and Department of Offences and relation Cars" (p. 101).

\[ \forall\, t_1 \in r_1 \;\; \exists\, t_2 \in r_2 :\; t_1[X] = t_2[K_2] \]
\(X\)
the referencing attributes of \(R_1\) (the foreign key)
\(K_2\)
the primary key of \(R_2\); same number of attributes as \(X\)

Two features of the definition are easy to miss. It is directional: every offence must find its officer, but Officers may hold an officer whom no offence names — 638, Larue Jacques, is perfectly legal. And with a composite key it is checked on the pair as a whole: offence 630876 points at (6544 XY, 47), Mimault's car, and (6544 XY, 75) is another car altogether. Note too that the referencing attribute needs neither the key's name (Officer refers to RegNum) nor unique values (456 appears in three offences).

In SQL, which you know, the two constraints of p. 101 are two clauses of one statement; the composite one needs the FOREIGN KEY (…) REFERENCES … form:

-- p. 101 in SQL: Offences must find its officer and its car
CREATE TABLE Offences (
  Code         CHAR(6) PRIMARY KEY,
  Date         DATE,
  Officer      CHAR(3) REFERENCES Officers (RegNum),
  Dept         CHAR(2),
  Registration CHAR(7),
  FOREIGN KEY (Registration, Dept)
    REFERENCES Cars (Registration, Dept)
);

Referential constraint checker

The database of p. 100. Officer in Offences must appear as a RegNum of Officers; the pair (Registration, Dept) in Offences must appear as a row of Cars. Pick an offence and change its officer or its car, or delete one row of Officers or Cars. A red cell holds a value that refers to no row; the outlined rows are where the chosen offence points.

  1. Predict first: which of the two deletes breaks the database — officer 638 or officer 456? Then try both with the last menu.
    What you should see

    Deleting 638 breaks nothing: no offence names him, and the constraint never asks an officer to have offences. Deleting 456 turns three Officer cells red (offences 987554, 987557, 630876). The insight the widget is built for: the check runs one way, from the referencing values (Offences) to the referenced key (Officers).

  2. Give offence 143256 the car (5694 FR, 47). Both "5694 FR" and "47" occur somewhere in Cars. Is the constraint satisfied?
    What you should see

    No: the Registration and Dept cells turn red. The foreign key is the pair, and no row of Cars is (5694 FR, 47) — 5694 FR is registered in 75 only. A composite key is matched as a whole, never attribute by attribute.

  3. Give offence 630876 the car (6544 XY, 75) instead of (6544 XY, 47). Violation or not?
    What you should see

    No violation: (6544 XY, 75) is a row of Cars. But it is Cordon Edouard's car, while the ticket was written for Mimault Bernard's. A referential constraint checks that the referenced row exists, not that it is the right one.

Keep the direction and the "pair as a whole" in mind. Several systems later in this course store such references without checking them, and then your application has to.

From diagram to tables: Step 1 and the two rules

Pages 102–118, "ER to Relational — Quick summary", are a recipe. Step 1 handles the entities (p. 103): "Create a separate table to represent each entity in the conceptual model" — "1A: Each attribute of the entity becomes a column in the relational table", "1B: Each instance of the entity set will become a row in the relational table". The identifier, the filled circle of the diagram, becomes the primary key: Sale(SaleID, Date, Amount).

Entities are the easy part. A relationship can live in two places: in a separate table whose rows are the links, or as a posted foreign key — a column added to one entity's table that holds the key of the other ("post" is the slides' verb; the asterisk marks such a column: Sale(SaleID, Date, Amount, Cust-ID*)). Page 103 names the two criteria that choose:

and where to read them: "Participation Cardinalities communicate some of the information regarding redundancy and load".

\[ \text{load} = \frac{\begin{array}{c}\text{non-null values}\\ \text{in the column}\end{array}}{\text{rows of the table}} \]

Page 104 turns the criteria into two rules, one per number of the (min,max) pair:

Maximum cardinalities — "The general rule is to post into a '1' entity table" (it "avoids 'repeating groups' redundancy"); "You can NEVER post into an 'N' entity".

Minimum cardinalities — "The general rule is to post into a '1' (mandatory) entity table" (it "avoids null values in the foreign key column"); "This rule can be violated in some circumstances".

Why two rules of different strength? Read them as questions about the foreign-key cell of each row. The maximum asks how many partners a row can have. If more than one, one cell cannot hold them: you would need a list in a cell, a repeating group — "multiple facts in one place", the second kind of redundancy of p. 103. A list is not an atomic value, so the table stops being a relation: that rule cannot bend. The minimum asks whether every row has a partner. If it is 0, some cells stay empty: nulls, a lower load. That costs space and care, but the table is still a relation, so this rule may bend.

The maximum decides where a foreign key may live; the minimum decides whether its cells can be empty.

Step 2: many-to-many always gets its own table

Step 2 (p. 105) covers the four patterns (0,N)-(0,N), (0,N)-(1,N), (1,N)-(0,N), (1,N)-(1,N): "You must create a separate table to represent the relationship"; "The primary keys of the related entity tables are posted into the relationship table to form its primary key. This kind of primary key is called a composite or concatenated primary key" — and "There are no exceptions to this rule!!!".

Student Student# Name Course#* 1TonyAcg4401, Acg3101 2EmilyAcg4401, Acg3101 3LeighAcg3101 Course Course# Name Student#* Acg4401AIS1, 2 Acg3101FAR 11, 2, 3 lists in cells

Before: posted either way — forbidden (p. 107)

Student Student#Name 1Tony 2Emily 3Leigh Course Course#Name Acg4401AIS Acg3101FAR 1 TAKES Student#Course# 1Acg4401 1Acg3101 2Acg4401 2Acg3101 3Acg3101 a row per link

After: a separate table (p. 106)

Fig. 3. Student (1,N) — TAKES — (1,N) Course. A foreign key in either entity table needs a list in a cell — a repeating group. The separate table TAKES has one row per enrolment and the composite primary key (Student#, Course#). The cells on the left follow the five enrolments of p. 106; the crossed-out columns of p. 107 simply list both courses for every student.

Both maxima are N, so the maximum rule closes both entity tables; what is left is a table whose rows are the links. Its key is the pair because the pair identifies the link: a student takes a given course once. Note the crossed-out column: an array of course ids inside the student is exactly how a document database stores this relationship (lesson 13). What the relational model forbids, MongoDB allows on purpose.

Step 3: (1,1)-(1,1), one direction only

For the pattern (1,1)-(1,1), Step 3 (p. 108) first asks a design question: "consider whether the two entities are conceptually separate or whether they should be combined". If they stay separate: "3A: Post the primary key from one entity's table into the other entity's table as a foreign key", "3B: It doesn't matter which entity's primary key is posted into the other entity's table, but DO NOT post both", "DO NOT make a separate table". Page 109 shows Sale (1,1) — yield — (1,1) Cash Receipt both ways, CR-ID* in Sale or S-ID* in Cash Receipt: "Choose ONE of these; DO NOT do both!!!".

Why is the direction free? Both maxima are 1 and both minima are 1, so in either table every cell gets exactly one value: load 100 %, no list. Why not both? Then every link is stored twice — one fact in two places, two copies that can disagree. And a separate table would only repeat the two keys row by row.

Steps 4 and 5: the (1,1) side takes the key, otherwise load decides

Step 4 (p. 110): "For remaining relationships that have (1,1) participation by one entity set, post the related entity's primary key into the (1,1) entity's table as a foreign key" — six patterns: (0,N)-(1,1), (1,N)-(1,1), (1,1)-(0,N), (1,1)-(1,N), (0,1)-(1,1), (1,1)-(0,1). "Do NOT make a separate table". "Post a foreign key INTO the (1,1) entity's table from the other entity's table". And the warning that explains the hook: "If you post the opposite direction, either redundancy [for N maximums] OR load [for 0 minimums] will be a problem".

Page 111 is the hook's case: Sale (1,1) — Is-to — (0,N) or (1,N) Customer. Cust-ID* in Sale holds C1, C2, C1, one value per row. The other way both failures arrive at once: Heather's cell needs "S1, S3", Dave's stays empty. Page 112 isolates the second failure: Sale (1,1) — yields — (0,1) Cash Receipt. CR-ID* in Sale is full; S-ID* in Cash Receipt leaves CR4 empty — a receipt of $1,000 that comes from no sale.

"Post the (1,1) entity's key into the other table." Backwards. The foreign-key column lives in the (1,1) entity's table and holds the other entity's key. Read the cardinalities, never the verb on the diamond.

Step 5: when only (0,1) sides are left

Step 5 (p. 113) takes the five remaining patterns: (0,N)-(0,1), (1,N)-(0,1), (0,1)-(0,N), (0,1)-(1,N), (0,1)-(0,1). Now no table satisfies both rules. The maximum rule leaves two options: "posting into a (0,1) or making a separate table; you CANNOT post into the (0,N) or (1,N)". The minimum rule objects to the first, because it "will create null values that waste valuable space in the database" — "However, if a separate table would waste more space, then it is better to follow the maximum rule and break the minimum rule". Load breaks the tie:

The worked example (pp. 114–115) has 18 purchases, 26 cash disbursements and a few purchase returns. "pays for" is Purchase (0,1) — (0,1) Cash Disbursement: "Most purchases (14/18) result in cash disbursements", so Check# posted into Purchase is non-null in 14 rows of 18 — "a high load", "Worth breaking the minimum rule" — and the slide concludes: post Check# into Purchase. "allowance for" is Purchase (0,1) — (1,N) Purchase Return: "Few purchases (3/18) result in purchase returns" — "low load"; the other direction is closed by the maximum rule, "because one purchase return slip # can be associated with multiple purchases". "Conclusion: Make a separate table to represent the 'allowance for' relationship". Its rows are the three links; since a purchase has at most one return, Receiving Report# alone is its key (not on the slides; the widget below underlines it).

Why should 50 % be the borderline between the two options?

The slides give no number; a count of cells gives one (this argument is not on the slides). Say the (0,1) table has n rows, r of them linked, and each key takes one cell. Posting costs one cell per row: n cells, n − r of them null. A separate table costs two cells per link: 2r. Posting is cheaper when n < 2r, that is when the load r/n is above one half — which fits the slide calling 13/26 = 50 % "a medium load" (p. 114). Today a null costs almost no space: the real trade-off is a nullable column against an extra join.

Where does the foreign key go?

A relationship laid out as data. On the left the rows of one entity, on the right the rows of the other, a line for every link; above them the ER diagram with its two (min,max) pairs. Each table carries the column it would get if the foreign key were posted into it (header with *): a blue cell holds one key, a grey cell is NULL, a red cell would need a list — a repeating group. Below, the separate table, one row per line. Start from an example of the slides, then change the pairs, the rows and the links. The slides give no figure for "low" and "high" load; the widget calls a load below 1/3 low and above 2/3 high, which matches their three cases (17 % low, 50 % medium, 78 % high). RR# is the Receiving Report #, PRS# the Purchase Return Slip #.

  1. Start with p. 111. Before reading the colours, predict: in which table does every foreign-key cell get exactly one value? Then look, and read the readouts.
    What you should see

    Cust-ID* in Sale: C1, C2, C1 — load 3/3 = 100 %, Step 4. The S-ID* column in Customer fails twice: Heather's cell needs "S1, S3" (red: Customer's maximum is N) and Dave's is NULL (grey: Customer's minimum is 0). This is the insight the widget is built for: the maximum decides where the key may live, the minimum whether its cells can be empty.

  2. Choose p. 106, then set 3 rows of Student, 2 rows of Course and 3 links. Does the Course#* column in Student still show a red cell? Is posting into Student allowed now?
    What you should see

    No red cell: in these rows every student happens to take one course. The readout still says "forbidden: maximum N". The diagram says (1,N), so a second course can arrive tomorrow — the cardinality decides, not the rows you see, exactly as an instance cannot prove a key (p. 97).

  3. Choose p. 115 and predict the step before reading it. Then raise the links from 3 towards 18: where does the advice change, and what never changes?
    What you should see

    At 3 links the load of PRS#* in Purchase is 3/18 = 17 %: low, Step 5B, a separate table. From 6 to 12 links the load is medium and the widget leaves it to judgement; from 13 links (13/18 = 72 %) it is high: 5A, post into Purchase. The RR#* column of Purchase Return stays forbidden throughout: its maximum is N. Load only breaks the tie the maximum leaves.

  4. Choose p. 114, where both sides are (0,1). Which direction wins? Then lower the links to 9 and predict again.
    What you should see

    With 14 links: Check#* in Purchase 14/18 = 78 % (high) against RR#* in Cash Disbursement 14/26 = 54 % (the slide prints 13/26: see the red pen above) — post Check# into Purchase, the slide's conclusion. With 9 links: 9/18 = 50 % and 9/26 = 35 %. Neither is high, so the note of p. 113 sends you to 5B: a separate table.

right entity left entity (0,1)(1,1)(0,N)(1,N) (0,1)(1,1)(0,N)(1,N) Step 5Step 4Step 5Step 5 Step 4Step 3Step 4Step 4 Step 5Step 4Step 2Step 2 Step 5Step 4Step 2Step 2
Fig. 4. The sixteen participation patterns and the step of pp. 105–113 that settles each. Rows: the (min,max) of the left entity; columns: that of the right one. A solid arrow points to the table that receives the foreign key; a dashed arrow means "into that table if the load is high, otherwise a separate table" (Step 5; for (0,1)-(0,1) the direction of the higher load). The double arrow of Step 3 is "either table, never both"; the small grid is a separate table with a composite key. The highlighted cell is the hook's (1,1)-(0,N).

Relationship attributes travel with the link

Page 116 adds the last piece: "If relationship becomes a separate table, then relationship attributes are placed in that table"; "If relationship can be represented by a posted foreign key, relationship attribute is posted alongside the foreign key". A relationship attribute describes one link, so it lives where the link lives: a grade on TAKES goes into TAKES(Student#, Course#, Grade). In the exam of 12 September 2025, Animal (1,1) — House — (1,N) Farm carries a Housing Date: it goes into Animal next to the posted key, Animal(Tag, Name, Age, AnimalType, Breed, FarmName*, HousingDate). It can never go to the N side: a farm houses many animals, so which animal's housing date would the farm's one cell hold?

One fact in many places: the diagram was wrong

Page 117 ends the section with a diagnosis: an Employee table (EmpID, EmpName, Payrate, Hours Worked, Dept#, DeptName) and five questions: "What facts are in multiple places in this table?", "Reverse engineer to get the ER model that this table must represent", "Is the ER model that results in this table correct?", "What SHOULD the ER model have been instead?", "What is the correct relational model?"

Employee EmpIDEmpNameDept#DeptName 8532AndyD423Audit 7352JenniferD423Audit 215ArlieD777ISAAS 4332CraigD821Tax 74StevenD821Tax one fact, two rows Payrate and Hours Worked omitted

Before: one table (p. 117)

Employee Department (1,1) (1,N) Assigned to Employee Department EmpIDEmpNameDept#* 8532AndyD423 7352JenniferD423 215ArlieD777 4332CraigD821 74StevenD821 Dept#DeptName D423Audit D777ISAAS D821Tax once each

After: two entities (p. 118)

Fig. 5. Left: "D423 is called Audit" is stored twice, and so is "D821 is called Tax". Right: the corrected ER and its tables — Dept# stays in Employee as a foreign key, each department's name is stored once. The slide prints no cardinalities on its ER; (1,1) next to Employee and a maximum N next to Department are what its tables imply.

The answers, in order. The facts in multiple places are "D423 is called Audit" (Andy's and Jennifer's rows) and "D821 is called Tax" (Craig's and Steven's) — the first kind of redundancy of p. 103. Reverse engineering the table gives one entity, Employee, with Dept# and DeptName among its attributes. That model is wrong: a department is a thing of its own, with its own identifier, and its name is a fact about the department. The model should have been Employee — Assigned to — Department (p. 118), and Step 4 then posts Dept# into Employee.

Why it matters: rename Audit and you must edit two rows — miss one and the table contradicts itself; a department with no employee cannot be recorded at all; delete Arlie and the fact that D777 is ISAAS disappears with that row. A correct ER gives tables in which every non-key column describes the thing its row stands for, so one fact in many places is the fingerprint of a wrong ER. Lesson 9 gives the same diagnosis a name: DeptName depends on Dept#, which is not the key — a transitive dependency — and the split of p. 118 is the step to third normal form.

Now the hook. Design B is not a relation: Heather's cell holds a list of sales, a repeating group, forbidden because Customer's maximum is N — and Dave's cell is NULL because Customer's minimum is 0. Design C is a legal relation, but Step 4 says "Do NOT make a separate table" when one side is (1,1). Design A is the slides' answer: Sale is (1,1), so Cust-ID* holds exactly one value in every row, load 100 %. Two pairs on the diagram decided it.

Exam-style questions

Five theory questions in the forms of the written exam (open, multiple choice, true/false; wrong closed answers may carry a penalty, announced just before the exam), then a load computation and a design on a past paper's ER diagram. The model answers use the slides' wording.

True or false: in the relational model a relation may contain two identical tuples, provided that they are stored in different positions of the table.

  • True A relation is a set: "the n-tuples are distinct from one another", and "there is no ordering between n-tuples", so there are no positions to tell two copies apart (p. 87).
  • False A relation is a set of tuples: no duplicates and no order between the tuples (p. 87).
Show model answer

False. A relation is a subset of a cartesian product, i.e. a set of n-tuples: the tuples are distinct from one another and there is no ordering between them. Only inside a tuple are the values ordered (the i-th value comes from the i-th domain), and the relational data model removes even that order by naming the attributes.

The trap is "different positions": tuples have no positions. SQL tables may contain duplicate rows when no key is declared; the relational model, as the slides define it, may not.

Define superkey and key of a relation. Using the relation Students(RegNum, Surname, FirstName, BirthDate, DegreeProg) with the five tuples shown in the lecture, show that {Surname, FirstName, BirthDate} is a key. Why are keys nevertheless defined at the schema level?

Show model answer

A set of attributes K is a superkey for a relation r if r does not contain two distinct tuples t1 and t2 with t1[K] = t2[K]. K is a key if it is a minimal superkey: no proper subset of K is a superkey.

The five tuples have five different (Surname, FirstName, BirthDate) triples, so the triple is a superkey. Each proper subset repeats a value: {Surname, FirstName} has (Black, Lucy) twice, {Surname, BirthDate} has (Smith, 29/04/59) twice, {FirstName, BirthDate} has (Lucy, 01/05/61) twice, and the single attributes repeat as well. Hence the triple is minimal: a key — of this instance.

Constraints correspond to properties of the real world, so they are associated with the schema and must hold in every legal instance. An individual instance can satisfy other uniqueness properties by chance (here {FirstName, BirthDate, DegreeProg} is also unique), and it can refute a key but never prove one.

A complete answer has three things: "distinct tuples" in the superkey definition, the word "minimal" with one counter-pair for each two-attribute subset, and the schema-versus-instance point of p. 97.

Which types of null value does the lecture distinguish, and which one do DBMSs adopt? Why are nulls not allowed in the primary key?

Show model answer

At least three: the unknown value (a domain value exists, but it is not known); the non-existent value (the attribute is not applicable for the tuple); the no-information value (we do not know whether a value exists or not — the logical or of the other two). DBMSs do not distinguish between them and implicitly adopt the no-information value.

The primary key is the key chosen to identify the tuples and to realise the references between relations. A tuple with a null in its key could neither be told apart from the others nor be referenced, so for each relation one key is selected as primary key and nulls are not allowed on it; its attributes are underlined.

A complete answer gives the three names, the "logical or", and the phrase "no-information value" for what DBMSs do. The second half asks for the reason, not just "PK is NOT NULL".

Define a referential constraint. In the database of the lecture — Offences(Code, Date, Officer, Dept, Registration), Officers(RegNum, Surname, FirstName), Cars(Registration, Dept, Owner) with primary key (Registration, Dept) — say which of these operations violates a referential constraint and why: (a) delete officer 638; (b) delete officer 456; (c) change the Dept of offence 630876 from 47 to 75; (d) set the car of offence 143256 to (5694 FR, 47).

Show model answer

A referential constraint imposes that the values on a set X of attributes of a relation R1 appear as values of the primary key of another relation R2. Here Offences.Officer refers to Officers and Offences.(Registration, Dept) refers to Cars.

(a) No violation: no offence references officer 638, and the constraint does not require every officer to be referenced. (b) Violation: offences 987554, 987557 and 630876 reference 456 and would refer to nothing. (c) No violation: (6544 XY, 75) is a row of Cars — although the offence now refers to Cordon's car instead of Mimault's: the constraint checks existence, not correctness. (d) Violation: 5694 FR and 47 both occur in Cars, but not in the same row; the foreign key is the pair, and (5694 FR, 47) is not a primary-key value of Cars.

The four cases test the two properties: direction ((a) against (b)) and the composite key matched as a whole ((d)). Case (c) is the subtle one: a legal instance is not necessarily a true one.

An ER diagram contains Sale (1,1) — yields — (0,1) Cash Receipt. According to the conversion rules of the lecture, how is the relationship represented in the relational schema?

  • The primary key of Sale is posted into the Cash Receipt table Cash Receipt is (0,1): a receipt that comes from no sale (CR4 on p. 112) gets a NULL — "If you post the opposite direction, either redundancy … OR load … will be a problem".
  • The primary key of Cash Receipt is posted into the Sale table Step 4: post into the (1,1) entity's table. Every sale yields exactly one receipt, so the column has no NULL and no list.
  • A separate table yields(SaleID, CR-ID) Step 4 says "Do NOT make a separate table".
  • Both keys are posted, one into each table Each link would be stored twice: one fact in two places.
Show model answer

CR-ID is posted into Sale as a foreign key (Step 4: post the related entity's primary key into the (1,1) entity's table). The column is fully loaded and single-valued. Posting SaleID into Cash Receipt would create nulls for the receipts that come from no sale.

A single choice where each wrong option is a different rule of pp. 104–110: direction, separate table, posting both.

Purchase (0,1) — pays for — (0,1) Cash Disbursement. There are 18 purchases and 26 cash disbursements; 14 purchases are paid, each by a different disbursement. Compute the load, in percent, of the foreign-key column if Check# is posted into the Purchase table.

Show model answer
\[ \text{load} = \frac{14}{18} \approx 77.8\,\% \]

In the other direction, Receiving Report# posted into Cash Disbursement has 14 non-null values out of 26, about 53.8 %. Both maxima are 1, so both directions are allowed; for (0,1)-(0,1) Step 5 posts in the direction of the highest load, provided it is high. 77.8 % is high: Check# goes into Purchase, as a nullable column.

The slide prints 13/26 for the second direction (see the red pen of section 5); the decision is the same. Answering 78 is accepted.

Consider the following part of the ER diagram of the exam of 13 June 2025, which tracks concert attendances and performances (the exercise itself is ours). Entities: Maestro – Personal ID, Name, Surname, Birth Date, Biography, Stage Name; Orchestra – Name, Foundation Date, Biography; Musician – Personal ID, Name, Surname, Birth Date, Biography; Instrument – Name, Type, Description; Concert – ID, Title, Start Time, Duration; Location – Name, Address, Type, N Seats. (In the paper Maestro and Musician inherit the first four attributes from Person; treat them as plain entities.) Relationships: Direct – First Concert (Yes/No): Maestro (1,1) – Orchestra (1,1); Compose: Orchestra (10,N) – Musician (1,2); Play – Since: Musician (1,N) – Instrument (1,N); Located: Concert (1,1) – Location (1,N).

Write the relational schema: one line per table, primary keys underlined, foreign keys marked with *. For each relationship, name the conversion step you apply.

Show model answer

Maestro(PersonalID, Name, Surname, BirthDate, Biography, StageName)
Orchestra(Name, FoundationDate, Biography, MaestroID*, FirstConcert)
Musician(PersonalID, Name, Surname, BirthDate, Biography)
Instrument(Name, Type, Description)
Compose(OrchestraName*, MusicianID*)
Play(MusicianID*, InstrumentName*, Since)
Location(Name, Address, Type, NSeats)
Concert(ID, Title, StartTime, Duration, LocationName*, LocationAddress*)

Direct is (1,1)-(1,1): Step 3. A maestro and an orchestra are conceptually separate, so one key is posted into the other table — here the maestro's into Orchestra; the opposite direction is equally correct, but not both, and no separate table. First Concert is posted alongside the foreign key. Compose: the maximum 2 of Musician is more than 1, so a single cell cannot hold a musician's orchestras; both maxima count as "many" and Step 2 applies: a separate table with the composite primary key. Play is (1,N)-(1,N): Step 2, and Since goes into the Play table. Located is (1,1)-(1,N): Step 4, Location's key is posted into Concert — a composite foreign key (Name, Address), matched as a pair.

Check your answer for the right step for each relationship, the composite keys underlined, the placement of First Concert and Since, and the composite foreign key. The trap is (1,2): for the posting rules 2 counts as many. Not on the slides, but worth one sentence if you have time: the minimum 10 of (10,N) and the maximum 2 of (1,2) are not expressed by these tables, since no key or foreign key can count.

Check yourself

In the named table of p. 89 you swap the columns HomeTeam and VisitingTeam, headers and values together. What happens to the relation?

  • Nothing: it is the same relation Each value travels with its attribute name; a tuple is a set of attribute–value pairs, and the column order carries no information.
  • Every game is reversed: the visitors become the home team That happens in the positional version of p. 88, where only the position tells the roles apart — not when the names move with the values.
  • Its degree changes The degree is the number of attributes: still four.
  • Its cardinality changes The cardinality is the number of tuples: still four games.

Which of these sets are superkeys of the five-student instance of p. 96? Select all that apply.

  • {RegNum, Surname} RegNum alone never repeats, so any set that contains it is a superkey — but not a key, because it is not minimal.
  • {RegNum} Five different values: a superkey, and with one attribute also minimal — a key.
  • {Surname, FirstName} (Black, Lucy) appears in 934856 and in 965536.
  • {FirstName, BirthDate, DegreeProg} Its five triples happen to differ, so on this instance it is a superkey — even a key, "by chance" (p. 97).
  • {DegreeProg} Computing and Fine Art each appear twice.

Superkey: no repetition; key: no repetition and nothing to drop. Both are tested on an instance here, but only the schema declares them.

Officer 638, Larue Jacques, appears in Officers but in no offence. What does that do to the database of p. 100?

  • Nothing: the database is legal The constraint asks every Officer value of Offences to appear in Officers, not every officer to appear in Offences.
  • It violates the referential constraint between Offences and Officers The constraint is directional: only the referencing side (Offences) can dangle.
  • It violates the key of Officers 638 appears once in Officers; the key is fine.

Sale (1,1) — Is-to — (0,N) Customer. You post S-ID into the Customer table instead of Cust-ID into Sale. Which problems appear? Select all that apply.

  • A customer with two sales needs two keys in one cell Customer's maximum is N: a repeating group, which is not even a relation.
  • A customer with no sale gets a NULL Customer's minimum is 0: low load.
  • A sale with no customer gets a NULL Sale is (1,1): every sale has exactly one customer — and in this design Sale has no foreign-key column at all.
  • Nothing: the two directions are equivalent They are equivalent only in (1,1)-(1,1) (Step 3).

p. 110 in one line: the wrong direction fails by redundancy for an N maximum, by load for a 0 minimum.

Employee (0,1) — uses — (0,N) Company Car. The company has 200 employees, and 12 of them use a car. How is the relationship represented?

  • A separate table Only Employee may take the key (max 1), and its load would be 12/200 = 6 %: low, so Step 5B.
  • CarID posted into Employee Legal, but 188 of 200 cells would be NULL: a low load, which Step 5B replaces with a separate table.
  • EmployeeID posted into Company Car Company Car's maximum is N: one car may be used by several employees, a list in a cell.
  • Nothing can be done: the minimum rule is broken either way The minimum rule may bend; the separate table avoids NULLs altogether.

TAKES links Student (1,N) and Course (1,N) and has an attribute Grade. Where is Grade stored?

  • In the TAKES table, next to the composite key A grade describes one enrolment, and TAKES has one row per enrolment (p. 116).
  • In the Student table A student has many courses: which one would the single Grade cell describe?
  • In the Course table Same problem from the other side: many students per course.
  • In both entity tables, for safety One fact in two places — and neither place is right.

The Employee table of p. 117 repeats "Audit" for D423. What went wrong at the level of the ER model?

  • The department was modelled as attributes of Employee instead of an entity related to Employee Its name is a fact about the department; as an entity it gets its own table and one row per department.
  • Employee has no key EmpID is the key and it never repeats.
  • DeptName should be the primary key of Employee It repeats, so it cannot even be a superkey.
  • Nothing: repeated names are only a display issue Rename Audit in one row only and the table contradicts itself — redundancy has a price.

Key take-aways

What to watch and read