Mid-level 6 min · March 05, 2026

ER Diagrams Explained: Entities, Relationships and Keys for Beginners

ER diagrams made simple — learn entities, attributes, relationships and cardinality from scratch with real-world examples and visual walkthroughs.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • ER diagram is a blueprint for your database — it maps entities, attributes and relationships before you write SQL.
  • The three building blocks are Entity (thing), Attribute (fact), and Relationship (connection).
  • Primary Key uniquely identifies a row; Foreign Key links tables.
  • Cardinality tells you how many of one thing relates to another — get this wrong and your schema breaks.
  • Biggest mistake: using commas in a column to store many-to-many relationships — always use a junction table.
Plain-English First

Think of an ER diagram like an architect's blueprint before a house is built — nobody picks up a hammer until the plan is drawn. An ER diagram is that blueprint for a database: it maps out what things you need to store (like Students and Courses) and how those things connect to each other, before you write a single line of SQL. Just like a blueprint uses standard symbols so any builder can read it, an ER diagram uses standard shapes so any developer or database admin can understand the plan instantly.

Every app you've ever used — Instagram, Spotify, your school's grading portal — stores data in a database. But before that database was built, someone had to answer a deceptively hard question: what exactly are we storing, and how does it all fit together? Get that wrong at the start and you end up with a tangled mess of tables that are nearly impossible to untangle later. ER diagrams exist precisely to force that thinking before any real work begins.

The problem ER diagrams solve is miscommunication. A business analyst says 'a customer can have multiple orders.' A developer hears something slightly different and builds the database wrong. An ER diagram turns that fuzzy conversation into a precise, visual contract that every stakeholder — technical or not — can read and agree on. It's a universal language for data structure.

By the end of this article you'll be able to read any ER diagram you come across, draw one from a plain-English description of a system, spot common design mistakes before they become expensive bugs, and walk into a database interview with genuine confidence. We'll build everything from scratch using a relatable example — a simple online bookstore — and layer on complexity one piece at a time.

What an ER Diagram Actually Is (and Why It Exists)

ER stands for Entity-Relationship. The diagram was invented by computer scientist Peter Chen in 1976, and the core idea hasn't changed since: draw pictures of your data before you build anything.

There are three foundational building blocks you need to know right now, and everything else is just detail on top of them.

An Entity is a real-world thing you want to store information about. In a bookstore, that's things like Book, Customer, and Order. Think of each entity as a category — not a specific book, but the concept of a book.

An Attribute is a piece of information that describes an entity. A Book entity has attributes like Title, ISBN, and Price. A Customer has a Name, Email, and Address. Attributes are the columns your future database table will have.

A Relationship is the connection between two entities. A Customer places an Order. An Order contains Books. These verbs connecting your nouns are the relationships.

That's the whole model. Everything else — notation styles, cardinality symbols, keys — is just a way to be more precise about these three ideas. Start with entities, hang attributes on them, then draw lines between the entities to show how they relate.

bookstore_er_sketch.txtPLAINTEXT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
=== BOOKSTORE ER DIAGRAM (Text Representation) ===

[ CUSTOMER ]                    [ ORDER ]                    [ BOOK ]
-----------                    ---------                    --------
* CustomerID (PK)              * OrderID (PK)               * ISBN (PK)
  FirstName                    * OrderDate                    Title
  LastName                     * TotalAmount                  Author
  Email                        * CustomerID (FK)              Price
  Phone                                                        StockCount

  CUSTOMER ----places----> ORDER ----contains----> BOOK
  (one customer places      (one order contains
   many orders)              many books; one book
                             can appear in many orders)

LEGEND:
  [ ]  = Entity (becomes a table)
  *    = Part of Primary Key
  (PK) = Primary Key — uniquely identifies each row
  (FK) = Foreign Key — links to another table
  ---- = Relationship line
Output
This is a design artifact, not executable code.
When implemented in SQL, this diagram produces three tables:
- customer (5 columns)
- order (4 columns)
- book (5 columns)
Plus one junction table: order_book (to handle the many-to-many relationship between orders and books)
Why Draw First, Code Second:
Studies of failed software projects consistently show that fixing a database design mistake after data is live costs 10-100x more than catching it on a whiteboard diagram. An ER diagram is cheap. Migrating a production database with millions of rows is not.
Production Insight
Teams that skip ER diagrams often end up with schema drift — tables get added in a hurry, foreign keys get misaligned, and nobody remembers which column stores what.
A common production scenario: you need to add a new relationship between Customer and Discount, but without the ER diagram you don't know if it's one-to-many or many-to-many. You guess, data gets duplicated, and rollbacks become painful.
Rule: keep the ER diagram version-controlled alongside your DDL — it prevents schema drift and saves your on-call team hours of detective work.
Key Takeaway
ER diagrams are not optional — they are the single cheapest tool for preventing expensive schema mistakes.
Every time you skip the diagram, you're betting you'll remember the cardinality correctly. You won't.
Draw it first. Code second. Always.

Entities, Attributes and Keys — The Building Blocks in Detail

Let's go deeper on each building block using our bookstore example so every concept has a concrete home to live in.

Entities become tables in your database. Strong entities can exist on their own — a Book exists whether or not it's been ordered. Weak entities depend on another entity to exist — an OrderItem only makes sense if there's an Order it belongs to. In diagrams, strong entities are drawn as rectangles; weak entities use a double rectangle.

Attributes come in flavors. A simple attribute holds one value (a customer's LastName). A multi-valued attribute can hold several (a customer might have two Phone numbers). A derived attribute is calculated from others (Age can be derived from DateOfBirth — you don't store it, you compute it on the fly). Composite attributes are made of smaller parts (FullName is made of FirstName + LastName).

Keys are the most important concept to nail down. A Primary Key (PK) is the attribute — or combination of attributes — that uniquely identifies one row in a table. No two rows can share the same Primary Key value, ever. CustomerID is a perfect primary key because no two customers share one. Email could work too, but people change emails, so auto-generated numeric IDs are safer. A Foreign Key (FK) is how you create the link between two tables — it's a column in one table that stores the Primary Key of a related row in another table.

bookstore_create_tables.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- ============================================================
-- BOOKSTORE DATABASE — translating our ER diagram into SQL
-- These CREATE TABLE statements are the direct output of
-- the design decisions made in the ER diagram above.
-- ============================================================

-- ENTITY: Customer
-- CustomerID is an auto-incrementing integer — the database
-- assigns it automatically so we never get duplicates.
CREATE TABLE customer (
    customer_id   INT          PRIMARY KEY AUTO_INCREMENT,  -- surrogate PK
    first_name    VARCHAR(50)  NOT NULL,
    last_name     VARCHAR(50)  NOT NULL,
    email         VARCHAR(100) NOT NULL UNIQUE,             -- natural candidate key
    phone         VARCHAR(20)                               -- nullable: optional field
);

-- ENTITY: Book
-- ISBN is a real-world unique code for every book — a natural PK.
CREATE TABLE book (
    isbn          CHAR(13)     PRIMARY KEY,   -- ISBNs are always exactly 13 digits
    title         VARCHAR(200) NOT NULL,
    author        VARCHAR(100) NOT NULL,
    price         DECIMAL(6,2) NOT NULL,      -- 6 digits total, 2 after decimal point
    stock_count   INT          NOT NULL DEFAULT 0
);

-- ENTITY: Order
-- customer_id here is a FOREIGN KEY — it references customer(customer_id)
-- This is how the ER relationship "Customer places Order" becomes real in SQL.
CREATE TABLE `order` (
    order_id      INT          PRIMARY KEY AUTO_INCREMENT,
    order_date    DATE         NOT NULL,
    total_amount  DECIMAL(8,2) NOT NULL,
    customer_id   INT          NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES customer(customer_id)
    -- If you try to insert an order with a customer_id that doesn't exist
    -- in the customer table, the database will REJECT it. This enforces
    -- referential integrity — no orphan orders allowed.
);

-- JUNCTION TABLE: order_book
-- This resolves the many-to-many relationship between Order and Book.
-- One order can contain many books. One book can appear in many orders.
-- A junction table is the ONLY correct way to model many-to-many in SQL.
CREATE TABLE order_book (
    order_id      INT          NOT NULL,
    isbn          CHAR(13)     NOT NULL,
    quantity      INT          NOT NULL DEFAULT 1,
    unit_price    DECIMAL(6,2) NOT NULL,   -- price at time of purchase (may change later)
    PRIMARY KEY (order_id, isbn),          -- composite PK: combination must be unique
    FOREIGN KEY (order_id) REFERENCES `order`(order_id),
    FOREIGN KEY (isbn)     REFERENCES book(isbn)
);
Output
Query OK, 0 rows affected (table: customer)
Query OK, 0 rows affected (table: book)
Query OK, 0 rows affected (table: order)
Query OK, 0 rows affected (table: order_book)
Database now contains 4 tables that perfectly reflect the ER diagram.
Inserting an order for a non-existent customer will produce:
ERROR 1452: Cannot add or update a child row: a foreign key constraint fails
Watch Out: Don't Use Email as a Primary Key
It seems logical — emails are unique. But people change their email addresses. If email is your PK, changing one customer's email means updating it in every related table (orders, reviews, sessions). Use a surrogate auto-increment ID as your PK and store email as a UNIQUE column. The ER diagram is the right place to catch this mistake before it's baked into your schema.
Production Insight
In production, using a natural key like email as PK caused a cascade update failure for a SaaS company — when a user changed their email, the update timed out because it had to update millions of rows in child tables.
The fix was to add a surrogate PK and keep email as UNIQUE. The rule: primary keys must never change. Foreign keys reference the PK, not the email.
If you're designing an ER diagram and see a candidate key that could change over a person's lifetime, make it a UNIQUE constraint, not the PK.
Key Takeaway
Entity becomes table, attribute becomes column, key becomes constraint.
A good PK is stable, simple, and never changes — reach for an auto-increment integer first.
The ER diagram is where you decide whether an attribute is simple, composite, or derived — get it right on paper, not in a migration.

Relationships and Cardinality — How Entities Talk to Each Other

Drawing a line between two entities is only half the job. You also need to say how many of one thing relates to how many of the other. That's cardinality, and it's the most important and most misunderstood part of ER diagrams.

There are three cardinality types you'll encounter in every system you ever design.

One-to-One (1:1): One row in Table A links to exactly one row in Table B, and vice versa. Example: one Customer has one ShippingProfile. These are rare and often a sign you should just merge the tables. Use it when you want to separate sensitive data (like storing payment details in a separate, more secured table).

One-to-Many (1:N): One row in Table A links to many rows in Table B, but each row in B links to only one row in A. This is the most common relationship in any database. One Customer places many Orders. One Author writes many Books. In SQL, you implement this by putting the FK on the 'many' side.

Many-to-Many (M:N): One row in Table A can link to many rows in Table B, and one row in Table B can link to many rows in Table A. Students enrol in many Courses; each Course has many Students. You cannot implement this directly in SQL — you always need a junction table in between. Your ER diagram must show this before you try to build it.

The notation you'll see most in job descriptions is Crow's Foot notation — a 'crow's foot' symbol (a trident shape) on the 'many' end of a relationship line, and a single vertical bar on the 'one' end.

cardinality_reference.txtPLAINTEXT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
=== CARDINALITY CHEAT SHEET (Crow's Foot Notation) ===

── ONE-TO-ONE ─────────────────────────────────────────

  CUSTOMER ──|────|── SHIPPING_PROFILE
             one  one

  "Each customer has exactly one shipping profile."
  "Each shipping profile belongs to exactly one customer."
  SQL: Put the FK in either table (usually the 'weaker' one).

── ONE-TO-MANY ────────────────────────────────────────

  CUSTOMER ──|────<── ORDER
             one    many

  "One customer places many orders."
  "Each order belongs to exactly one customer."
  SQL: FK (customer_id) goes in the ORDER table — the 'many' side.
       Never put it in the CUSTOMER table.

── MANY-TO-MANY ───────────────────────────────────────

  ORDER ──>────<── BOOK
        many  many

  "One order contains many books."
  "One book appears in many orders."
  SQL: You CANNOT model this directly.
       Create a junction table: ORDER_BOOK(order_id FK, isbn FK)
       This splits the M:N into two 1:N relationships:
         ORDER ──|────<── ORDER_BOOK ──>────|── BOOK

── CROW'S FOOT SYMBOLS ────────────────────────────────

  |    = exactly one      (mandatory one)
  O    = zero or one      (optional one)
  <    = many             (mandatory many)
  O<   = zero or many     (optional many)

  Combined examples:
  |──|   = exactly one on both sides
  |──<   = one on left, many on right
  O──O<  = optional one to optional many
Output
This is a reference diagram — no executable output.
Use this as a quick lookup when you're reading or drawing ER diagrams.
The most common pattern you'll see in real databases is: |──< (one-to-many)
Pro Tip: Read Relationships in Both Directions
Every relationship line tells two stories. 'Customer places Orders' reads left to right. 'Each Order belongs to one Customer' reads right to left. Always read both directions aloud when reviewing a diagram — hidden design errors become obvious when you verbalize both sides. If either direction sounds wrong, your cardinality is wrong.
Production Insight
A startup once modeled Customers and PaymentMethods as one-to-one, assuming each customer used exactly one card. When the product added support for multiple cards, they had to do a painful migration: alter the FK to allow multiple, then create a new PaymentMethod table, then write a migration script — during a holiday season.
The ER diagram would have caught this during the design meeting: read the relationship backwards — 'one payment method belongs to exactly one customer' sounds correct, but 'one customer has many payment methods' is the real business rule.
Rule: always capture future cardinality possibilities. If 'one customer can have many X' is likely, start with one-to-many even if the current version is one-to-one.
Key Takeaway
Cardinality is not just a diagram detail — it drives the entire physical schema.
One-to-Many: FK on the many side. Many-to-Many: junction table. There are no exceptions.
Read every relationship in both directions before you finalise the diagram — it reveals hidden assumptions.

Drawing Your First Complete ER Diagram — A Step-by-Step Walkthrough

Knowing the pieces is one thing. Knowing how to go from a plain-English description to a finished diagram is the skill that actually matters. Here's the repeatable process senior developers use.

Step 1 — Identify your entities. Read the requirements and underline every noun. 'Students enrol in Courses taught by Instructors.' The nouns — Student, Course, Instructor — are your candidate entities.

Step 2 — Identify attributes for each entity. Ask: what do I need to know about a Student? Name, StudentID, Email, DateOfBirth. Repeat for every entity. Circle anything that could uniquely identify one row — that's your Primary Key candidate.

Step 3 — Identify relationships. Read the verbs. 'Students enrol in Courses.' 'Instructors teach Courses.' Each verb is a relationship. Write them down as triples: (Student, enrols in, Course).

Step 4 — Determine cardinality. For each relationship, ask both directions: 'Can one Student enrol in many Courses?' Yes. 'Can one Course have many Students?' Yes. That's Many-to-Many — you need a junction table called Enrolment.

Step 5 — Add foreign keys. Now that you know the cardinality, add FKs on the 'many' sides. For M:N, add both FKs into the junction table.

Step 6 — Review. Read every relationship both directions aloud. Check every entity has a PK. Confirm no M:N relationship is missing a junction table. Done.

university_schema_from_er.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
-- ============================================================
-- UNIVERSITY ENROLLMENT SYSTEM
-- Built by following the 6-step ER diagram process above.
-- Requirements: Students enrol in Courses taught by Instructors.
-- ============================================================

-- Step 1-2: Entity INSTRUCTOR with attributes
CREATE TABLE instructor (
    instructor_id   INT          PRIMARY KEY AUTO_INCREMENT,
    full_name       VARCHAR(100) NOT NULL,
    email           VARCHAR(100) NOT NULL UNIQUE,
    department      VARCHAR(50)  NOT NULL
);

-- Step 1-2: Entity COURSE with attributes
-- Step 5: instructor_id FK links to the instructor who teaches this course
-- Cardinality: One instructor teaches many courses (1:N)
--              FK goes on the 'many' side — in the COURSE table
CREATE TABLE course (
    course_id       CHAR(8)      PRIMARY KEY,   -- e.g. 'CS-10234'
    course_name     VARCHAR(150) NOT NULL,
    credits         TINYINT      NOT NULL CHECK (credits BETWEEN 1 AND 6),
    instructor_id   INT          NOT NULL,
    FOREIGN KEY (instructor_id) REFERENCES instructor(instructor_id)
);

-- Step 1-2: Entity STUDENT with attributes
CREATE TABLE student (
    student_id      INT          PRIMARY KEY AUTO_INCREMENT,
    first_name      VARCHAR(50)  NOT NULL,
    last_name       VARCHAR(50)  NOT NULL,
    email           VARCHAR(100) NOT NULL UNIQUE,
    enrollment_year YEAR         NOT NULL
);

-- Step 4-5: JUNCTION TABLE for the M:N relationship between Student and Course
-- 'Students enrol in Courses' — one student takes many courses,
-- one course has many students. We CANNOT link these directly.
-- The ENROLMENT table breaks it into two 1:N relationships.
CREATE TABLE enrolment (
    student_id      INT          NOT NULL,
    course_id       CHAR(8)      NOT NULL,
    enrolment_date  DATE         NOT NULL,
    grade           CHAR(2),                   -- NULL until grade is submitted
    PRIMARY KEY (student_id, course_id),       -- composite PK prevents duplicate enrolment
    FOREIGN KEY (student_id) REFERENCES student(student_id),
    FOREIGN KEY (course_id)  REFERENCES course(course_id)
);

-- ── SAMPLE DATA to verify the design works ──────────────────

INSERT INTO instructor VALUES (1, 'Dr. Priya Mehta', 'priya@uni.edu', 'Computer Science');

INSERT INTO course VALUES ('CS-10234', 'Database Systems', 3, 1);
INSERT INTO course VALUES ('CS-10301', 'Algorithms',       3, 1);

INSERT INTO student VALUES (1, 'James', 'Okafor', 'james@uni.edu', 2023);
INSERT INTO student VALUES (2, 'Sofia', 'Reyes',  'sofia@uni.edu', 2023);

-- James enrols in both courses; Sofia enrols in one
INSERT INTO enrolment VALUES (1, 'CS-10234', '2024-09-01', NULL);
INSERT INTO enrolment VALUES (1, 'CS-10301', '2024-09-01', NULL);
INSERT INTO enrolment VALUES (2, 'CS-10234', '2024-09-01', NULL);

-- Query that PROVES the ER design is correct:
-- Show every student and every course they are enrolled in
SELECT
    CONCAT(s.first_name, ' ', s.last_name) AS student_name,
    c.course_name,
    i.full_name                            AS taught_by
FROM enrolment e
JOIN student    s ON e.student_id = s.student_id
JOIN course     c ON e.course_id  = c.course_id
JOIN instructor i ON c.instructor_id = i.instructor_id
ORDER BY student_name, c.course_name;
Output
student_name | course_name | taught_by
----------------|-------------------|------------------
James Okafor | Algorithms | Dr. Priya Mehta
James Okafor | Database Systems | Dr. Priya Mehta
Sofia Reyes | Database Systems | Dr. Priya Mehta
3 rows returned.
The design works: James appears twice (enrolled in 2 courses),
Sofia appears once. No duplicate data in any table.
Interview Gold: The Junction Table Question
Interviewers love to ask 'how do you implement a many-to-many relationship in a relational database?' The answer is always a junction table (also called a bridge table, associative table, or linking table). Bonus points if you mention that the junction table often grows its own attributes — like the 'grade' column in our enrolment table — making it a full entity in its own right.
Production Insight
The 6-step process looks easy on paper, but in real projects the hardest step is #1: identifying the correct entities. Engineers often confuse attributes with entities (making 'Color' a table) and entities with relationships (making 'Enrolment' a simple attribute of Student).
A production trick: ask 'does this thing have its own lifecycle?' If yes, it's probably an entity. 'Color' doesn't change independently — it's an attribute of Product. 'Enrolment' has a date, a grade, and is created and deleted — it's an entity (a junction entity).
Another production insight: when adding a junction table, remember it almost always accumulates its own attributes — enrolment_date, grade, discount_code. Design the junction table with those from the start.
Key Takeaway
Follow the 6-step process: Entities → Attributes → Relationships → Cardinality → Foreign Keys → Review.
Never skip the polar reading of relationships — it catches the cardinality mistakes that cost weeks later.
Junction tables are not an afterthought — they are entities in their own right and often carry their own attributes.

Common Pitfalls in ER Diagrams and How to Avoid Them

Even experienced developers make the same handful of mistakes when drawing ER diagrams. Knowing these patterns helps you spot them in your own designs and in code reviews.

Pitfall 1: Treating every noun as an entity. Not every noun is a data object. 'Color', 'Status', 'Category' are often attributes, not entities. Ask: does this thing have attributes of its own? Can it exist independently? If no, it's probably an attribute.

Pitfall 2: Confusing mandatory and optional cardinality. In Crow's Foot notation, a vertical bar means 'exactly one', a circle means 'zero or one'. A common mistake: using 'zero or one' on a FK that should always have a value. This allows NULLs where they shouldn't exist, leading to orphaned rows.

Pitfall 3: Missing the junction table for M:N relationships. You spot this when you find yourself trying to add multiple foreign keys in a single table or using comma-separated lists. Always draw the junction table on the ER diagram — it's a design decision, not an implementation detail.

Pitfall 4: Overlooking weak entities. OrderItem is a weak entity because it depends on Order. Without identifying it as weak, you might try to give it its own artificial PK and miss the composite FK constraint that ensures every item belongs to a real order.

Remember: the ER diagram is a communication tool. If a non-technical stakeholder can read it and confirm 'yes, that's how our business works', you've succeeded. If they get confused, the diagram is too complex or the symbols are wrong.

pitfalls_checklist.txtPLAINTEXT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
=== ER DIAGRAM PITFALLS CHECKLIST ===

Before finalising your ER diagram, verify each of the following:

[ ] Every entity has a primary key (surrogate or natural).
[ ] No entity represents something that should be an attribute.
[ ] Every relationship line has the correct cardinality symbol.
[ ] Read each relationship in both directions — do both read correctly?
[ ] Every many-to-many relationship has a corresponding junction table.
[ ] Weak entities are clearly marked (double rectangle).
[ ] Foreign keys are placed on the 'many' side of one-to-many relationships.
[ ] Multi-valued attributes (e.g., multiple phone numbers) are modeled as separate entities.
[ ] Derived attributes (e.g., Age from DateOfBirth) are marked and not stored.
[ ] Composite attributes (e.g., Address made of Street, City, Zip) are broken into simple attributes.

If any box is unchecked, go back and fix the diagram before moving to SQL.
This checklist saves hours of migration work post-launch.
Output
This checklist is a reference — no SQL output.
Print it out or keep it in your notes for every database design session.
The 'Noun Test' for Entities vs Attributes
  • Entity: has its own attributes and relationships (e.g., Supplier has Name, Address, Phone).
  • Attribute: describes a single entity and has no sub-structure (e.g., Color is just a string on Product).
  • If you're tempted to create a table with only one column (e.g., ColorID + Name), it's an attribute. Merge it back.
  • Exception: if an attribute frequently changes independently, it might be an entity (e.g., 'Category' with its own description, parent category).
Production Insight
The most common production failure from pitfall #2 (mandatory vs optional) is a customer profile page that breaks because a required FK is NULL. Example: an 'Order' record has a NULL 'assigned_sales_rep_id' because the cardinality was drawn as zero-or-one, but the business rule says every order MUST be assigned.
The fix: enforce mandatory cardinality on the ER diagram with a vertical bar, and in SQL with NOT NULL. Don't leave it to chance.
Pitfall #3 (missing junction table) hits hardest when you need to query the relationship. Without a junction table, you resort to string parsing — and string parsing in SQL is a clear sign you skipped the ER diagram.
Key Takeaway
Four pitfalls kill ER diagrams: entity/attribute confusion, cardinality symbol misuse, missing junction tables, and ignoring weak entities.
The 'noun test' and the checklist are your shields against these mistakes.
If a non-technical stakeholder can read your diagram and agree it matches the business rules, you've won.
Is This Noun an Entity or an Attribute?
IfDoes the noun have its own attributes (e.g., Supplier has Phone, Address)?
UseYes → It's an entity. Create a table.
IfIs the noun a single value that only describes one entity (e.g., Color for Product)?
UseYes → It's an attribute. Add it as a column.
IfCan the noun exist without being linked to something else?
UseYes → Strong entity. No → Weak entity (depends on parent).
IfDoes the noun have its own identity separate from the entity it belongs to?
UseYes → Entity. For example, 'Invoice' has its own number and date — entity. 'InvoiceLine' depends on Invoice — weak entity.
● Production incidentPOST-MORTEMseverity: high

The Hospital Database That Spilled Patient Data

Symptom
Patients were showing up under multiple IDs, lab results were attached to the wrong person, and the billing system sent invoices to random accounts.
Assumption
The team assumed a simple Patients table with an auto-increment ID and an Encounters table linked by patient_id would be enough. No diagram was drawn.
Root cause
Without an ER diagram, the relationship between Patient and Address was modeled as one-to-one — but a patient can have multiple addresses (home, work, billing). The team later tried to store multiple addresses as comma-separated strings in the Patient table, breaking referential integrity.
Fix
Redraw the ER diagram: Patient to Address became one-to-many, requiring a separate Address table with a foreign key to Patient. Also discovered that encounter to lab result was many-to-many — missing junction table caused duplicate results.
Key lesson
  • An ER diagram must be drawn before any DDL is written — the diagram reveals relationship cardinality that’s easy to miss in conversation.
  • Never store multiple values in a single column — it violates 1NF and destroys queryability.
  • Every foreign key relationship must be reviewed in both directions: 'can a patient have many addresses?' is one question; 'can an address belong to many patients?' is another and usually false for billing addresses.
Production debug guideSpot cardinality mistakes, missing junction tables, and wrong key placements before they hit production.4 entries
Symptom · 01
You need to store multiple values for one attribute (e.g., multiple phone numbers for one customer).
Fix
Draw the ER diagram — if the attribute is multi-valued, create a new entity (Phone) with a foreign key to Customer. Do not use a comma-separated column.
Symptom · 02
Every time you add a relationship, you need to create an extra table you didn't expect.
Fix
Check if the relationship is many-to-many. If yes, a junction table is required. If the relationship is one-to-many, verify the foreign key is on the 'many' side.
Symptom · 03
You have an entity with no attributes of its own — it only links two other entities.
Fix
That entity is likely a junction table (weak entity) for a many-to-many relationship. Confirm cardinality — if both sides can have many, you need this bridge.
Symptom · 04
You're reading an ER diagram and a relationship line has a crow's foot on both ends — what does that mean?
Fix
That's many-to-many (M:N). You must create a junction table in the physical schema. The ER diagram shows the conceptual relationship; the junction table is how you implement it.
★ ER Design Quick Cheat SheetThe three most common ER diagram mistakes and how to fix them on the spot.
One-to-many relationship modeled with FK on the 'one' side
Immediate action
Move the FK column to the 'many' table immediately.
Commands
ALTER TABLE order ADD customer_id INT;
ALTER TABLE customer DROP COLUMN order_ids;
Fix now
Never store array-like data in a single column — always create a proper FK on the many side.
Many-to-many relationship with no junction table+
Immediate action
Create a junction table with both foreign keys.
Commands
CREATE TABLE enrolment (student_id INT, course_id INT, PRIMARY KEY (student_id, course_id));
ALTER TABLE enrolment ADD FOREIGN KEY student_id REFERENCES student(id);
Fix now
A junction table (bridge table) is the only correct way to implement M:N relationships in SQL.
Entity uses email as primary key+
Immediate action
Add a surrogate auto-increment primary key. Keep email as UNIQUE NOT NULL.
Commands
ALTER TABLE customer ADD COLUMN customer_id INT AUTO_INCREMENT PRIMARY KEY;
ALTER TABLE customer ADD UNIQUE INDEX idx_email (email);
Fix now
Emails change; primary keys must never change. Use auto-increment IDs for stability.
ER Diagram Cardinality Comparison
AspectOne-to-Many (1:N)Many-to-Many (M:N)
Real-world exampleOne Customer → Many OrdersStudents ↔ Courses
Where does the FK go?In the 'many' side table (Order table)In a separate junction table — never in the main entities
Number of tables needed2 tables3 tables minimum (both entities + junction)
Composite Primary Key needed?No — each table has its own single PKYes — junction table PK combines both FKs
Most common mistakePutting FK on the wrong side (in the 'one' table)Trying to store the relationship in a comma-separated column
How to spot it in requirementsVerb is singular on one side: 'a customer places orders'Both sides are plural: 'students enrol in courses, courses have students'
ER diagram symbol (Crow's Foot)Single bar ── Crow's foot: |──<Crow's foot on both ends: >──<

Key takeaways

1
An ER diagram is a blueprint, not code
draw it before you write a single line of SQL, because fixing a design on paper costs nothing and fixing it in production costs everything.
2
The three core building blocks are Entity (thing), Attribute (fact about a thing), and Relationship (connection between things)
every ER concept is just a refinement of these three.
3
Cardinality is the critical detail
One-to-Many is implemented with a FK on the 'many' table; Many-to-Many always requires a junction table — there are no exceptions to this rule in relational databases.
4
A Foreign Key is the physical implementation of a relationship line in your ER diagram
when you draw that line, you're deciding where the FK column will live.
5
Weak entities need composite primary keys combining a partial key with the parent's PK
never give them their own synthetic ID alone.
6
Always read relationships in both directions aloud during diagram review
it's the single most effective way to catch cardinality errors.

Common mistakes to avoid

3 patterns
×

Using comma-separated IDs in a column to represent many-to-many relationships

Symptom
Queries become slow and complex, can't enforce referential integrity, and adding a new relationship requires string manipulation. For example, storing '101,205,310' in a course_ids column of the student table.
Fix
Create a junction table (e.g., enrolment) with two foreign keys and a composite primary key. Store one relationship per row — this is first normal form.
×

Putting the foreign key on the wrong side of a one-to-many relationship

Symptom
You end up with array-like columns or you can't add a second related record without modifying the parent row. For example, adding an order_ids column to the customer table instead of a customer_id column in the order table.
Fix
Always place the foreign key in the table on the 'many' side. Ask 'which entity can have multiple of the other?' — that entity gets the FK.
×

Creating entities for everything, including things that should be attributes

Symptom
The ER diagram has dozens of entities for a simple app, joins are everywhere, and performance suffers. For example, making 'Color' an entity with its own table and an ID.
Fix
If a concept has no attributes of its own and is only ever a single value for one entity, it's an attribute. Color = attribute of Product. Supplier = entity (has many attributes).
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is the difference between a Primary Key and a Foreign Key, and how ...
Q02SENIOR
How do you represent a many-to-many relationship in a relational databas...
Q03SENIOR
Can a weak entity have its own Primary Key? Why or why not — and how do ...
Q04SENIOR
What is a composite primary key? Give an example in the context of ER di...
Q01 of 04JUNIOR

What is the difference between a Primary Key and a Foreign Key, and how does that difference show up in an ER diagram?

ANSWER
A Primary Key uniquely identifies each row in a table — it's shown underlined or marked with (PK) in the ER diagram. A Foreign Key references the Primary Key of another table, creating a relationship line between entities. In the diagram, the FK appears as an attribute in the dependent entity but is not the primary key of that entity. The relationship line between entities is the visual representation of the FK constraint.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
What is the difference between an ER diagram and a database schema?
02
Do I need special software to draw an ER diagram?
03
What's the difference between a strong entity and a weak entity?
04
What is the difference between a surrogate key and a natural key in ER diagrams?
🔥

That's Database Design. Mark it forged?

6 min read · try the examples if you haven't

Previous
1NF 2NF 3NF Explained
3 / 16 · Database Design
Next
Primary Key and Foreign Key