Core CS · DBMS
Five entity types, four relationships, seven tables
Turning an ER diagram into a relational schema is seven rules applied in a fixed order. You will run six of them on one small college diagram, see why the seventh never fires, and watch where each primary key comes from.
Convert one diagram, one rule at a time →01 The idea
What actually becomes a table
An ER diagram holds four kinds of thing: entity types, relationships, attributes, and the cardinality and participation markings on the lines. The conversion is a sorting exercise. Some of those become tables, some become columns, and one of them becomes nothing at all.
Entity types always become tables, strong or weak. Relationships are the interesting case, and the deciding fact is the cardinality. A foreign-key column holds exactly one value, so a column can only ever record “at most one on that side”. That is enough for a 1:1 and enough for a 1:N, which is why neither of them needs a table. It is not enough for M:N, so M:N gets a table whose rows are the pairs. Attributes mostly become columns, except that a multivalued attribute cannot fit in one, so it gets a table too.
The part interviewers actually press on is not which tables you built. It is the primary key of each one, because that is where the diagram’s meaning ends up. Every rule below names a key, and every key in this lesson is checked against the rows you can see.
02 Worked example
One college diagram, written out
Here is the diagram this whole lesson uses, written in text so nothing is hidden in a drawing. Five entity types, four relationships, and one attribute of each awkward kind: a composite one, a derived one and a multivalued one. Read the last line first; it is the notation key.
-- entity typesSTUDENT sid*, name(first, last), dob, /age, {phone}COURSE cid*, title, creditsINSTRUCTOR empid*, inameLIBRARY_CARD card_no*, issued_onINSTALMENT inst_no~, amount, paid_on -- weak, owner STUDENT -- relationships sides participationTAKES STUDENT --- LIBRARY_CARD 1:1 card total, student partialPAYS STUDENT --- INSTALMENT 1:N identifying; instalment totalTEACHES INSTRUCTOR --- COURSE 1:N every course has one instructorENROLS STUDENT --- COURSE M:N attribute: marks -- * key attribute ~ partial key / derived {} multivalued () composite
Three lines carry most of the difficulty. Line 2 has all three awkward attributes on one entity type: name is composite and arrives as two columns, /age is derived and arrives as no column at all, and {phone} is multivalued and ends up needing a table. Line 6 is the weak entity type, marked by ~ on its partial key. Line 9 is where participation does real work: cardinality decides which table receives a column everywhere else in this diagram, and TAKES is the one line where the participation marking decides it instead.
Node 4 is where the conversion is won or lost, which is why it is marked. Nothing about TAKES, TEACHES and ENROLS looks different on the page: three lines joining two boxes each. What separates them is the cardinality written on the line, and that single marking decides whether you write a column or build a table. Get it wrong in one direction and you have a table nobody needed; get it wrong in the other and your schema cannot record what the diagram said.
Count the result before you build it. Five entity types give five tables. One M:N relationship gives one more. One multivalued attribute gives one more. 7 tables, and three of the four relationships produced a foreign-key column instead of a table: the 1:1, and both of the 1:N lines. The rest of the lesson is the rule behind each of those seven, and the key each one ends up with.
03 Mechanics
The seven rules, in the order you apply them
The order matters, because rules 2 to 7 all borrow primary keys that rule 1 has to have created first. Work down the list and every foreign key you need already exists.
Before the table, the three words the fourth column is written in, because interviewers use them precisely and marks are lost here. A superkey is any set of columns whose values are unique in every state the table is allowed to reach. A candidate key is a superkey with nothing removable: take any one column out and uniqueness breaks. The primary key is whichever candidate key you picked. So “a candidate key is a key that could be the primary key” is not the definition; minimality is the whole content of the word.
| Rule | In the diagram | What you create | Primary key becomes | On our diagram |
|---|---|---|---|---|
| 1 | Strong entity type E | One table with every simple attribute of E. A composite attribute contributes its components and then disappears; a derived attribute contributes nothing; a multivalued attribute waits for rule 6. | The key attribute E already has | student(sid), course(cid), instructor(empid), library_card(card_no) |
| 2 | Weak entity type W with owner E | One table with W’s own attributes plus the primary key of E as a foreign key, normally ON DELETE CASCADE because W has no meaning without its owner. | The owner’s primary key together with W’s partial key | instalment(sid, inst_no) |
| 3 | Binary 1:1 between S and T | No new table. The primary key of one side becomes a UNIQUE column in the other, with the relationship’s own attributes beside it. Put it on the side whose participation is total, so it can be NOT NULL. If both sides are total you may instead merge the two into one table. | Unchanged on both sides. The new column is a second candidate key of the table that received it. | library_card.sid UNIQUE NOT NULL; card_no stays the key |
| 4 | Binary 1:N, with S on the 1 side | No new table. The primary key of S becomes a plain foreign-key column in T’s table, with the relationship’s own attributes beside it. No UNIQUE here: that column is meant to repeat. | Unchanged. T keeps the key it already had. | course.empid; cid stays the key |
| 5 | Binary M:N | A new table holding both primary keys as foreign keys, plus the relationship’s own attributes. | The two foreign keys together, and nothing else | enrols(sid, cid), with marks outside the key |
| 6 | Multivalued attribute A of E | A new table holding the primary key of E and one column for A, one row per value. | E’s key together with A | student_phone(sid, phone) |
| 7 | n-ary relationship over n entity types | A new table holding all n primary keys as foreign keys, plus its own attributes. Same shape as rule 5 with more columns. | All n foreign keys together, unless one participating side has cardinality 1, in which case that side’s key is left out of the key | none in this diagram |
Rule 5 is the one to be able to argue, because it is the one people try to shortcut. Suppose you tried to record ENROLS with a column instead of a table. Put cid inside student and you have said each student takes at most one course. Put sid inside course and you have said each course has at most one student. Neither is what the diagram says, and there is no third column to try. The only shape that records many on both sides is one row per pair, and once the rows are pairs, the pair is what identifies a row. That is why the primary key is composite, and why marks sits in the table but outside the key: marks belongs to the pair, it does not help identify it.
Here is the whole diagram as DDL. Read it against the rule numbers in the comments rather than top to bottom.
CREATE TABLE student ( -- rule 1 · strong entity sid TEXT PRIMARY KEY, dob DATE NOT NULL, -- age is derived: not stored first_name TEXT NOT NULL, last_name TEXT NOT NULL); -- composite name, flattenedCREATE TABLE instructor (empid TEXT PRIMARY KEY, iname TEXT NOT NULL);CREATE TABLE library_card ( -- rule 1, then rule 3 card_no TEXT PRIMARY KEY, issued_on DATE, sid TEXT UNIQUE NOT NULL REFERENCES student(sid)); -- 1:1 · the total sideCREATE TABLE instalment ( -- rule 2 · weak entity sid TEXT REFERENCES student(sid) ON DELETE CASCADE, inst_no INT, amount NUMERIC NOT NULL, paid_on DATE, PRIMARY KEY (sid, inst_no)); -- owner key + partial keyCREATE TABLE course ( -- rule 1, then rule 4 cid TEXT PRIMARY KEY, title TEXT NOT NULL, credits INT NOT NULL, empid TEXT NOT NULL REFERENCES instructor(empid)); -- 1:N · the N sideCREATE TABLE enrols ( -- rule 5 · M:N gets a table sid TEXT REFERENCES student(sid), cid TEXT REFERENCES course(cid), marks INT, PRIMARY KEY (sid, cid)); -- both foreign keys togetherCREATE TABLE student_phone ( -- rule 6 · multivalued sid TEXT REFERENCES student(sid), phone TEXT, PRIMARY KEY (sid, phone));-- rule 7 · an n-ary relationship would add one more table here, holding-- all n foreign keys; the key is all n, minus any side limited to one.
Line 7 is rule 3 and the only place participation shows up as syntax. UNIQUE is what makes it 1:1 rather than 1:N, and NOT NULL is legal only because every card belongs to a student. It also gives library_card a second candidate key: card_no and sid are each unique on their own, and either could have been the primary key. Line 14 is rule 4 and deliberately has no UNIQUE, because one instructor here teaches two of the three courses and that column is supposed to repeat. Line 18 is rule 5, and line 21 is rule 6; in both, a foreign key is part of the primary key, which is normal and not a mistake.
One vendor difference worth naming, because it bites exactly here. A UNIQUE column accepts many NULLs in the SQL standard, PostgreSQL, MySQL and Oracle. SQL Server treats NULLs as equal in a unique constraint and accepts only one NULL row, so a nullable UNIQUE foreign key fails on the second row that has no partner. That is a second reason to put the 1:1 foreign key on the side that is never empty.
05 Cheat sheet
The seven rules on one card
Learn it as construct, table, key. The third column is the one that gets asked about, and the one people leave out.
| ER construct | What you build | Primary key |
|---|---|---|
| Strong entity type | a table of its simple attributes | its own key attribute |
| Weak entity type | a table, plus the owner’s key as a foreign key | owner's key + partial key |
| Binary 1:1 | no table; a UNIQUE foreign-key column on the total side | both keys unchanged |
| Binary 1:N | no table; a foreign-key column on the N side | the N side keeps its own key |
| Binary M:N | a table of both keys plus the relationship’s attributes | the two foreign keys together |
| Multivalued attribute | a table of the owner’s key plus one value per row | owner's key + the value |
| n-ary relationship | a table of all n keys plus its own attributes | all n keys, minus any side with cardinality 1 |
06 Where & why
Where these rules are the DDL you type
The seven rules are not a diagram exercise. Each one lands as a clause you can type into a database that is running right now, and each of these systems takes one of them slightly differently. Interviewers ask about exactly those differences.
PRIMARY KEY (sid, cid) is rule 5 and creates a single unique index on the pair, not one per column, so the column order in that key decides which lookups it can serve. ON DELETE CASCADE is rule 2 written down: delete a student and the instalments go with her, which is what “weak” means. A foreign key here may point at any column carrying a unique constraint, not only at a primary key, which is why the second candidate key rule 3 creates is a legitimate target.
InnoDB stores the table clustered on its primary key and every secondary index carries that primary key as its row pointer. So the composite key from rule 5 is not just a constraint: enrols is physically ordered by sid then cid, which makes “all courses for one student” a range scan and “all students on one course” an index lookup you have to add. InnoDB also creates an index on a foreign-key column if you have not, so rule 4 quietly costs you one index per relationship.
Putting the 1:1 foreign key on the partial side means a nullable UNIQUE column. SQL Server treats two NULLs as equal for a unique constraint and allows only one NULL row, so the second student with no library card fails to insert. The fix is a filtered unique index, WHERE sid IS NOT NULL. It is a syntax difference, but it turns rule 3’s participation guidance from a preference into a portability problem.
Foreign keys are ignored until the connection runs PRAGMA foreign_keys = ON, so all six references in this schema are documentation by default. SQLite also allows NULLs in most PRIMARY KEY columns, a long-standing documented deviation, with INTEGER PRIMARY KEY the exception. So declare the parts of a composite key NOT NULL yourself, or rule 2 and rule 5 give you keys that do not actually identify anything.
07 Interview questions
What they actually ask
This usually arrives as a whiteboard task rather than a question: here is a diagram, give me the tables. The follow-ups are always about keys, so answer each table with its key attached before anyone has to ask.
Walk me through converting an ER diagram into tables.
Which relationships get their own table and which do not?
What is the primary key of the table an M:N relationship produces?
A weak entity type: what table do you build, and what is its key?
Which side of a 1:1 relationship should hold the foreign key?
Why can a multivalued attribute not just be a column?
What happens to composite and derived attributes?
Where do the attributes of a relationship go?
Superkey, candidate key, primary key: what is the difference?
Can this conversion ever leave you with a table that has no primary key?
Do teams ship exactly this schema in practice?
08 Practice problems
Six to work through
All six extend the same college diagram. For each one, write the tables before you write the keys, then check every key against rows you actually wrote down.