Skip to content

Expert: design, speed and engines · Schema design and normalisation · topic 42 of 62 · 35 min

Modelling data: entities and relationships

Explanation

Before you write CREATE TABLE, you turn the requirements into a model: entities (the things), attributes (their details) and relationships (how they connect), with a cardinality such as one-to-many. An ER diagram draws this model, often with crow's foot lines. Many-to-many relationships become junction tables, and every table gets a key chosen on purpose.

Why model before you build?

In module 1 you met keys and the three kinds of relationship. Now you use them to design a database from scratch. Changing a design on paper costs nothing. Changing it after a year, when the tables hold lakhs of rows and ten programs read them, takes migrations, testing and late nights. A few hours of modelling saves weeks later.

A data model is a description of the things your app must remember and how they connect. It has three parts:

  • Entity: a kind of thing you store many of, such as Student, Course or Doctor. Each entity usually becomes a table.
  • Attribute: one detail of an entity, such as a student's name or a course's fee. Attributes become columns.
  • Relationship: how entities connect, such as "a student enrols in a course". Relationships become foreign keys or junction tables.

From requirements to a model

Start from plain sentences written with the people who will use the app. A simple trick is to underline the nouns and the verbs. Nouns that have their own details are entities; small nouns that only describe something are attributes; verbs are relationships.

Requirement sentenceWhat it gives you
"A coaching institute has students. We record each student's name, phone and city."Entity Student with attributes name, phone, city
"Each course has a code, a title and a fee."Entity Course with code, title, fee
"A student can join many courses, and a course has many students."A many-to-many relationship: enrols
"For each enrolment we keep the batch and the date of joining."Attributes of the relationship itself, so they live in the junction table
"Each course has exactly one teacher; a teacher can teach several courses."Entity Teacher, one-to-many to Course

Cardinality and optionality

Cardinality is the "how many" of a relationship: one or many on each side. Optionality says whether a link must exist at all: a course may have zero students in its first week, but an enrolment must always point to one student. Ask two questions for each side: "at least how many?" (zero or one) and "at most how many?" (one or many).

Crow's foot notation, in words

The most common way to draw an ER (entity-relationship) diagram is crow's foot notation. Tables are boxes and relationships are lines. The end of each line shows cardinality: a three-pronged fork that looks like a crow's foot means "many", a short bar means "one", and a small circle means "zero", so the link is optional.

Line endRead it as
Bar and bar ( || )Exactly one
Circle and bar ( o| )Zero or one
Bar and crow's foot ( |< )One or many
Circle and crow's foot ( o< )Zero or many
output
teachers ||------o< courses       one teacher teaches zero or many courses
students ||------o< enrolments    one student has zero or many enrolments
courses  ||------o< enrolments    one course has zero or many enrolments
enrolments: student_id FK, course_id FK, batch, joined_on; PK (student_id, course_id)
The coaching institute in crow's foot words. Students and courses are many-to-many through enrolments.

Many-to-many becomes a junction table

A relational table cannot hold "many" on both sides, so every many-to-many relationship becomes a junction table with two foreign keys. Notice that the relationship often has its own attributes: the batch and the joining date belong to neither the student nor the course, but to the enrolment. When a relationship gathers many attributes, it is really an entity of its own, and that is fine.

sql
SELECT c.code, c.title
FROM enrolments e
JOIN courses c ON c.id = e.course_id
WHERE e.student_id = 3;
-- CS102 | Databases
-- MA101 | Statistics
Reading a junction table: the courses of student 3 (Priya Nair). A second join to students would show her name.

Choosing keys on purpose

A candidate key is any column, or set of columns, that could identify a row: for a course both id and code are unique. You pick one as the primary key and protect the others with UNIQUE. Most teams use a surrogate id as the primary key and keep natural values such as a course code, a PAN or an email under a UNIQUE rule.

  • A junction table can use the pair as its primary key, PRIMARY KEY (student_id, course_id), which also blocks the same student joining the same course twice.
  • If the same pair may appear more than once (a patient sees the same doctor many times), the pair is not unique. Give the table its own id, and add the date to make each row distinct.
  • A one-to-one relationship is a foreign key with UNIQUE on it; an optional one-to-many relationship is a foreign key that allows NULL.

Common mistakes

  • Jumping straight to CREATE TABLE. Fix: write the requirement sentences and a rough ER diagram first, and show them to a real user.
  • Putting relationship details on the wrong table, such as a grade column in students. Fix: ask "whose detail is this?"; a grade belongs to one student in one course, so it goes in the junction table.
  • Making a junction table's pair the primary key when repeats are real (repeat appointments). Fix: use an id plus the date.
  • Modelling a list as columns: course1, course2, course3. Fix: one row per pair in a junction table. Topic 2 explains why.
  • Forgetting optionality. Fix: decide NOT NULL or nullable for every foreign key, from the "at least how many?" question.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Modelling data: entities and relationships · 1/7

Modelling data

In this module we design databases ourselves. First step: turn plain requirements into a model before writing any SQL.

Prefer a video by a teacher? Find free videos on “er diagram crow's foot notation tutorial entity relationship modelling” on YouTube ↗

In real life: A clinic appointment system

A small clinic chain wants online booking. The requirements give entities Patient, Doctor, Clinic and Appointment. A doctor works at one clinic; a patient can book many appointments with many doctors over the years, and the same patient may see the same doctor again next month. So Appointment is its own table with an id, patient_id, doctor_id, a start time and a status, rather than a pair-keyed junction table. Hospital and clinic software across India is built on models like this.

sql
CREATE TABLE appointments (
  id         INTEGER PRIMARY KEY,
  patient_id INTEGER NOT NULL REFERENCES patients(id),
  doctor_id  INTEGER NOT NULL REFERENCES doctors(id),
  starts_at  TEXT NOT NULL,              -- UTC, 'YYYY-MM-DD HH:MM:SS'
  status     TEXT NOT NULL DEFAULT 'Booked',
  UNIQUE (doctor_id, starts_at)          -- a doctor cannot be double-booked
);
The UNIQUE pair turns a business rule ("no double booking") into a constraint.

Practice (0/3 done)

Task 1 · Code · SQL

The college database has students, courses and the junction table enrolments (student_id, course_id, semester). Return the name of every student enrolled in the course titled 'Databases', sorted by name (one column: name).

Task 2 · Code · SQL

The tables students and courses exist, but there is no junction table yet. 1) Create enrolments with student_id (INTEGER NOT NULL, references students(id)), course_id (INTEGER NOT NULL, references courses(id)) and PRIMARY KEY (student_id, course_id). 2) Insert these pairs (student_id, course_id): (1, 2), (2, 2), (2, 3), (4, 1), (5, 2). 3) Return every course with how many students joined it, including courses with none: columns title and students, sorted by title.

Task 3 · Practice

Model a small public library (or, if you prefer, a clinic). Requirements: members borrow books; a book title can have several physical copies; a member can borrow many copies over time and the same copy many times; each loan has a borrow date, a due date and a return date (empty until returned); books have one or more authors. Write the entities, their attributes, the relationships with cardinality in crow's foot words, and the primary key of every table.

Quick quiz

Question 1

1.In "a patient books an appointment with a doctor", what is most likely an attribute rather than an entity?

Question 2

2.In crow's foot notation, what does a line end drawn as a circle with a crow's foot (o<) mean?

Question 3

3.Students and courses are many-to-many, and each enrolment has a grade. Where does the grade column go?

Question 4

4.A patient may see the same doctor many times. Why is PRIMARY KEY (patient_id, doctor_id) a bad key for appointments?

Question 5

5.courses has both id and a unique code like CS101. What is the usual design?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

In "a patient books an appointment with a doctor", what is most likely an attribute rather than an entity?

Answer: The appointment start time

The start time only describes an appointment, so it is a column. Patient, Doctor and Appointment each have their own details.

In crow's foot notation, what does a line end drawn as a circle with a crow's foot (o<) mean?

Answer: Zero or many

The circle means zero is allowed, and the fork means many.

Students and courses are many-to-many, and each enrolment has a grade. Where does the grade column go?

Answer: In the enrolments junction table

A grade belongs to one student in one course, which is exactly one row of the junction table.

A patient may see the same doctor many times. Why is PRIMARY KEY (patient_id, doctor_id) a bad key for appointments?

Answer: The pair repeats, so a second visit would be rejected

A pair key allows each pair only once. Use an id, and add the start time to tell visits apart.

courses has both id and a unique code like CS101. What is the usual design?

Answer: Use id as the primary key and put a UNIQUE rule on code

Both are candidate keys. A surrogate id is the stable key; UNIQUE still protects the natural value.

In the Notes app, why is user_id stored in the notes table?Related

Answer: It is a foreign key that says which user owns the note

One user has many notes, so each note row records its owner with a foreign key pointing to users.id.

From Designing the data model

One student takes many courses, and one course has many students. How do you model this?Related

Answer: Add a junction table with student_id and course_id

Many-to-many needs a junction table with one row per pair.

From Keys and relationships

When is a schema design really finished?Related

Answer: When the important business questions can be answered with clear queries on sample data

Testing with real reports finds missing columns and awkward relationships early.

From Design project: an online store

Students take many courses and courses have many students. How do you model this?Related

Answer: Add a junction table enrollments(student_id, course_id)

Many-to-many needs a junction table with a foreign key to each side.

From Normalisation and table design

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 4 more topics in “Schema design and normalisation” before its exam: Normalisation: 1NF, 2NF, 3NF and BCNF, Denormalisation, OLTP and OLAP, Data types, naming and good habits, Design project: an online store.
  2. Module 9 exam: Schema design and normalisation · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Indexes, query plans and views. 62 topics left in the course before the final exam.

← Previous: ACID, isolation and locking