<DataInsights />
  • 🏠 Home
  • 📊 SQL
  • 🐍 Python
  • 📈 Power BI
  • 📗 Excel
  • 💼 Career
  • 🎯 Interview Q&A
  • 📁 Case Study
  • 📥 Downloads
  • 🚀 My Portfolio
<DataInsights />

Practical Data Analytics tutorials covering SQL, Python, Power BI, Excel and career guidance for aspiring analysts — 100% free.

Topics

  • SQL Tutorials
  • Python Guide
  • Power BI
  • Excel Tips
  • Career Guide

Quick Links

  • 🛠️ All Tools
  • 🗓️ Archive
  • 📬 Contact
  • 🔍 Search
  • Portfolio
  • Kaggle
  • GitHub

Legal & Info

  • About
  • Contact
  • Privacy Policy
  • Disclaimer
  • Terms & Conditions
  • DMCA
  • Sitemap
Copyright © 2026 Data Insights by Jatin Kumar. All Rights Reserved.Built with ❤️ for Data Analysts
Home/SQL/"Database Design — ER Diagram, Normalization And R...

"Database Design — ER Diagram, Normalization And Real-World Schema"

A
August 3, 2026 Jatin Kumar 30 min read SQL
Data Insights MySQL Masterclass — Part 7 (Final)

Database Design — ER Diagram, Normalization & Real-World Schema

MySQL Masterclass ka final aur sabse important part — Database Design. ER Diagrams se schema plan karo, Normalization se data redundancy hatao, aur ek complete real-world E-commerce database banao. Sab kuch step-by-step Data Insights par.

📑 Is Part 7 Mein Aap Kya Sikhenge:

  • Topic 1: ER Diagram — Entities, Attributes & Relationships
  • Topic 2: Normalization — Kya Hai & Kyun Zaroori Hai
  • Topic 3: 1NF — First Normal Form
  • Topic 4: 2NF — Second Normal Form
  • Topic 5: 3NF — Third Normal Form
  • Topic 6: BCNF — Boyce-Codd Normal Form
  • Topic 7: Denormalization — Kab Torna Hai Rules
  • Topic 8: Real-World Schema — Complete E-commerce Database

1. ER Diagram — Entity Relationship Diagram

text

🔍 Definition: An Entity-Relationship (ER) Diagram is a visual blueprint of a database. It shows Entities (objects/tables), their Attributes (columns), and Relationships (how entities connect). ER diagrams are created BEFORE writing any SQL — they are the planning phase of database design.

🎯 Samjho Simple Bhasha Mein: ER Diagram ek architectural blueprint hai — jaise ghar banane se pehle architect drawing banata hai. Database banane se pehle ER diagram banate hain — kaunsi tables hongi, unmein kya columns honge, aur tables kaise ek dusre se connected honge. Yeh paper ya whiteboard par bana lo PEHLE, phir SQL likho.

💡 ER Diagram ke 3 Main Components:

1. Entity (Rectangle ▭): Real-world object jo table banega
Example: Student, Employee, Product, Order

2. Attribute (Ellipse ○): Entity ka property jo column banega
Example: Student ka naam, roll_number, email
Types: Simple, Composite, Multi-valued, Derived

3. Relationship (Diamond ◇): Entities ke beech connection
Example: Student "enrolls in" Course, Customer "places" Order

📊 Relationship Types — Cardinality:

Type Notation Example Implementation
One-to-One (1:1) 1 — 1 Employee — Passport Foreign key with UNIQUE
One-to-Many (1:N) 1 — ∞ Department — Employees Foreign key in "many" table
Many-to-Many (M:N) ∞ — ∞ Students — Courses Junction/Bridge table

📊 ER Diagram — E-commerce Example (Text Representation):


┌─────────────┐ places ┌─────────────┐
│ CUSTOMER │ ──────────────────────▶ │ ORDER │
│─────────────│ 1 Many │─────────────│
│ customer_id │ │ order_id │
│ name │ │ customer_id │
│ email │ │ order_date │
│ phone │ │ total_amt │
└─────────────┘ └──────┬──────┘
│ contains
│ (1 to Many)
▼
┌─────────────┐ belongs to ┌─────────────┐
│ PRODUCT │ ◀──────────────────── │ ORDER_ITEM │
│─────────────│ 1 Many │─────────────│
│ product_id │ │ order_id │
│ name │ │ product_id │
│ price │ │ quantity │
│ category_id │ │ unit_price │
└──────┬──────┘ └─────────────┘
│ belongs to
│ (Many to 1)
▼
┌─────────────┐
│ CATEGORY │
│─────────────│
│ category_id │
│ name │
│ description │
└─────────────┘

Relationships:
Customer (1) ──places──▶ (Many) Orders
Order (1) ──contains──▶ (Many) Order_Items
Product (1) ──in──▶ (Many) Order_Items
Category (1) ──has──▶ (Many) Products

💻 ER Diagram se SQL Schema:

-- ER Diagram ko SQL mein convert karna
-- Entity: CUSTOMER
CREATE TABLE customers (
customer_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
phone VARCHAR(15)
);

-- Entity: ORDER (1:N with Customer)
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_amount DECIMAL(10,2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

-- Junction Table: ORDER_ITEMS (M:N between Order and Product)
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);

⚠️ Common Mistakes:

  • Mistake: ER Diagram banaye bina seedha SQL likhna → Later schema changes bahut painful hoti hain.
    Fix: Hamesha pehle ER diagram banao — paper par bhi chalega.
  • Mistake: Many-to-Many relationship ko directly implement karna → 2 tables ke beech direct M:N possible nahi — junction table chahiye.
    Fix: M:N ke liye hamesha ek junction/bridge table banao.
  • Mistake: Relationship aur Attribute confuse karna → Relationship do entities ke beech hota hai, attribute ek entity ka property hai.

💬 Interview Questions:

Q1: What is an ER Diagram and what are its components?
Ans: ER (Entity-Relationship) Diagram is a visual representation of database structure. Components: Entity (rectangle) — real-world object that becomes a table. Attribute (ellipse) — property of an entity that becomes a column. Relationship (diamond) — connection between entities. Cardinality notations show 1:1, 1:N, or M:N relationships. ER diagrams are created before coding to plan the database schema.

Q2: How do you implement a Many-to-Many relationship in SQL?
Ans: Many-to-Many cannot be directly implemented between two tables. A junction table (also called bridge table or associative table) is created with foreign keys referencing both parent tables. The junction table's primary key is a composite key of both foreign keys. Example: Students-Courses → student_courses(student_id, course_id) junction table.

Q3: What is a weak entity?
Ans: A weak entity cannot be uniquely identified by its own attributes alone — it depends on another (strong) entity for identification. Example: Order_Item depends on Order — an order item has no meaning without its parent order. Weak entities have a partial key (dashed underline) and use the parent's primary key as part of their composite primary key.

2. Normalization — Kya Hai & Kyun Zaroori Hai

text

🔍 Definition: Normalization is the process of organizing a relational database to reduce data redundancy and improve data integrity. It involves decomposing tables into smaller, well-structured tables and defining relationships between them. Each Normal Form (NF) has specific rules that must be satisfied.

🎯 Samjho Simple Bhasha Mein: Normalization matlab "data ko sahi jagah rakhna." Socho ek table mein student ka naam, college ka naam, aur college ka address — agar student transfer ho toh 100 jagah college address update karna padega. Normalization se college ki info alag table mein jaati hai — ek jagah update karo, sab jagah reflect hota hai. Yeh data duplication hatane ka systematic process hai.

💡 Problems Without Normalization:

Insert Anomaly: Naya record add nahi ho sakta bina unnecessary data ke
Update Anomaly: Ek data ko multiple rows mein update karna padta hai
Delete Anomaly: Ek record delete karne se important data bhi delete ho jaata hai
Data Redundancy: Same data multiple jagah store — storage waste + inconsistency

📊 Un-Normalized Table — Problems Dekho:

-- PROBLEM TABLE: student_courses (Un-normalized)

student_idstudent_namecourse_idcourse_nameteacher_namegrade
101RahulC01MySQLMr. SharmaA
101RahulC02PythonMrs. GuptaB
102PriyaC01MySQLMr. SharmaA+
102PriyaC03Data ScienceMr. SharmaB+
103AmitC02PythonMrs. GuptaC

PROBLEMS: ❌ Update Anomaly: Mr. Sharma ka naam change karo → 3 rows update! ❌ Insert Anomaly: Naya course add karo bina student ke → NULL values! ❌ Delete Anomaly: Amit delete karo → Python course ka record lost! ❌ Redundancy: 'MySQL' aur 'Mr. Sharma' multiple baar store

text

💬 Interview Questions:

Q1: What is Normalization and why is it important?
Ans: Normalization is the process of structuring a database to minimize redundancy and ensure data integrity. It eliminates three types of anomalies: insert anomaly (can't add data without unrelated data), update anomaly (must update same data in multiple places), and delete anomaly (deleting one record accidentally removes other needed data). It's done by decomposing large tables into smaller related tables.

Q2: What is data redundancy and why is it bad?
Ans: Data redundancy means the same data is stored in multiple places. Problems: (1) Storage waste. (2) Update anomaly — update all copies or data becomes inconsistent. (3) Risk of conflicting data — different copies show different values. Normalization eliminates redundancy by storing each piece of data in exactly one place with references (foreign keys) elsewhere.

3. 1NF — First Normal Form

text

🔍 Definition: First Normal Form (1NF) requires that: (1) Each column contains only atomic (indivisible) values — no lists or sets. (2) Each column contains values of the same data type. (3) Each row is uniquely identifiable (has a primary key). (4) No repeating groups of columns.

🎯 Samjho Simple Bhasha Mein: 1NF ka matlab hai "har cell mein sirf ek value." Socho ek cell mein "MySQL, Python, Java" likh diya — yeh 1NF violate karta hai. Har course ko alag row mein hona chahiye. Also, columns repeat nahi hone chahiye jaise course1, course2, course3 — yeh bhi violation hai. Simple rule: har cell = ek value, table mein primary key hona chahiye.

💡 1NF Rules — Checklist:
✅ Har column mein atomic (single) value
✅ Saare values ek column mein same data type ke
✅ Primary Key exist karta hai
✅ Koi repeating column groups nahi (course1, course2, course3)
✅ Row order irrelevant (data order pe depend nahi)

📊 1NF Violation — Before & After:

-- ❌ VIOLATES 1NF (multi-value column + repeating groups)

student_idstudent_namecoursescourse1course2
101RahulMySQL, Python, JavaMySQLPython
102PriyaData Science, MySQLDataSciMySQL
student_idstudent_namecourse101Rahul
MySQL101RahulPython101
RahulJava102PriyaDataSci

Problems: 'courses' column multi-value, repeating course1/course2 columns -- ✅ AFTER 1NF (atomic values, no repeating groups) Primary Key: (student_id, course) — composite key Each cell has ONE value ✅ 102 Priya MySQL

text

💻 1NF Compliant Table Creation:

-- 1NF: Separate rows for each course enrollment
CREATE TABLE student_courses_1nf (
student_id INT,
student_name VARCHAR(50),
course VARCHAR(50),
grade CHAR(2),
PRIMARY KEY (student_id, course) -- Composite PK for uniqueness
);

INSERT INTO student_courses_1nf
VALUES
(101, 'Rahul', 'MySQL', 'A'),
(101, 'Rahul', 'Python', 'B'),
(101, 'Rahul', 'Java', 'A+'),
(102, 'Priya', 'Data Science','B+'),
(102, 'Priya', 'MySQL', 'A+');

⚠️ Common Mistakes:

  • Mistake: JSON ya comma-separated values ek column mein store karna → MySQL JSON type allow karta hai but 1NF violate hoti hai.
    Fix: Har value ki alag row banao — query karna bhi aasaan hoga.
  • Mistake: Repeating column groups banana → phone1, phone2, phone3 — 4th phone add karna ho toh schema change karna padega.
    Fix: Separate phone_numbers table banao with foreign key.

💬 Interview Questions:

Q1: What are the rules of First Normal Form (1NF)?
Ans: 1NF requires: (1) Atomic values — each cell contains a single indivisible value, no lists or sets. (2) Same data type in each column. (3) Unique rows — table must have a primary key. (4) No repeating column groups. A table with a "courses" column storing "MySQL, Python, Java" violates 1NF because the value is not atomic.

Q2: Give an example of 1NF violation and how to fix it.
Ans: Violation: employees table with columns (emp_id, name, skills) where skills = "Java, Python, SQL". Fix: Create a separate employee_skills table with (emp_id, skill) where each skill gets its own row. This eliminates the multi-value column and allows easy querying like "find all Python developers."

4. 2NF — Second Normal Form

text

🔍 Definition: Second Normal Form (2NF) requires the table to be in 1NF AND every non-key attribute must be fully functionally dependent on the ENTIRE primary key — not just part of it. Partial dependency (where a non-key column depends on only part of a composite primary key) must be eliminated.

🎯 Samjho Simple Bhasha Mein: 2NF sirf tab apply hota hai jab composite primary key ho. Rule hai: "har non-key column ko POORI primary key pe depend karna chahiye — sirf ek part pe nahi." Socho student_courses table mein primary key hai (student_id, course_id). student_name sirf student_id pe depend karta hai — course_id se koi lena dena nahi. Yeh partial dependency hai — 2NF violate karta hai.

💡 2NF ka Rule:
Table 1NF mein ho + Koi Partial Dependency na ho

Partial Dependency: Non-key column depends on PART of composite PK
Full Dependency: Non-key column depends on ENTIRE composite PK

Note: Agar single column primary key hai toh 2NF automatically satisfied hai (partial dependency possible hi nahi)

📊 2NF Violation — Before & After:

-- ❌ VIOLATES 2NF (Partial Dependencies!)
-- Primary Key: (student_id, course_id)
student_idcourse_idstudent_namecourse_namegrade
101C01RahulMySQLA
101C02RahulPythonB
102C01PriyaMySQLA+
Partial Dependencies Found:
❌ student_name depends only on student_id (not full PK)
❌ course_name depends only on course_id (not full PK)
✅ grade depends on BOTH student_id AND course_id (full dependency)

-- ✅ AFTER 2NF (Split into 3 tables)
-- Table 1: students (student_id → student_name)
student_idstudent_name
101Rahul
102Priya
-- Table 2: courses (course_id → course_name)
course_idcourse_name
C01MySQL
C02Python
-- Table 3: enrollments (student_id, course_id → grade)
student_idcourse_idgrade
101C01A
101C02B
102C01A+
text

💻 2NF Compliant Tables:

-- 2NF: Separate tables for each entity
CREATE TABLE students (
student_id INT PRIMARY KEY,
student_name VARCHAR(50) NOT NULL
);

CREATE TABLE courses (
course_id VARCHAR(5) PRIMARY KEY,
course_name VARCHAR(50) NOT NULL
);

-- Junction table: Only fully-dependent column (grade) stays here
CREATE TABLE enrollments (
student_id INT,
course_id VARCHAR(5),
grade CHAR(2),
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(student_id),
FOREIGN KEY (course_id) REFERENCES courses(course_id)
);

⚠️ Common Mistakes:

  • Mistake: Single column PK wale table mein 2NF violation dhundhna → Single column PK se partial dependency possible nahi — 2NF auto-satisfied.
    Fix: 2NF sirf composite primary key wale tables mein check karo.
  • Mistake: Har dependency ko partial samajhna → grade DONO columns pe depend karta hai — yeh partial nahi, fully dependent hai.
    Fix: Check karo: kya column sirf ek part se determine ho sakta hai? Haan → Partial. Nahi → Full.

💬 Interview Questions:

Q1: What is Second Normal Form and what is Partial Dependency?
Ans: 2NF requires the table to be in 1NF and every non-key attribute must be fully functionally dependent on the entire primary key. Partial dependency occurs when a non-key attribute depends on only part of a composite primary key. Example: In (student_id, course_id) PK, student_name depending only on student_id is partial. Fix: move student_name to a separate students table.

Q2: Can a table with a single-column primary key violate 2NF?
Ans: No. Partial dependency can only occur with composite primary keys (two or more columns). If a table has a single-column primary key, every non-key attribute is either dependent on that entire key or not dependent at all (which is a different problem). Therefore, any 1NF table with a single-column primary key automatically satisfies 2NF.

5. 3NF — Third Normal Form

text

🔍 Definition: Third Normal Form (3NF) requires the table to be in 2NF AND there must be no Transitive Dependencies — meaning no non-key attribute should depend on another non-key attribute. Every non-key attribute should depend ONLY on the primary key, nothing else.

🎯 Samjho Simple Bhasha Mein: 3NF ka rule: "non-key column kisi dusre non-key column se determine nahi hona chahiye." Example: Employee table mein emp_id → dept_id → dept_name. dept_name, emp_id se directly depend nahi karta — pehle dept_id pe aata hai, phir dept_name. Yeh transitive dependency hai. Fix: dept_name ko alag departments table mein le jao.

💡 Transitive Dependency:
A → B → C (C transitively depends on A via B)

Example: emp_id → dept_id → dept_name
emp_id determines dept_id (direct)
dept_id determines dept_name (direct)
Therefore: emp_id → dept_name (TRANSITIVE — violation!)

Fix: dept_name ko employees table se hataao, departments table mein rakho

📊 3NF Violation — Before & After:

-- ❌ VIOLATES 3NF (Transitive Dependencies!) -- Primary Key: emp_id

emp_idemp_namedept_iddept_namedept_city
101RahulD1ITBangalore
102PriyaD2HRMumbai
103AmitD1ITBangalore
emp_idemp_namedept_id101Rahul
D1102PriyaD2103
AmitD1dept_iddept_namedept_city
D1ITBangaloreD2HR

Transitive Dependencies: emp_id → dept_id ✅ (direct) dept_id → dept_name ❌ (transitive via dept_id) dept_id → dept_city ❌ (transitive via dept_id) Problems: ❌ IT ka dept_city change karo → 2 rows update! ❌ Amit delete karo → D1 dept info lost! -- ✅ AFTER 3NF (Remove transitive dependencies) -- Table 1: employees -- Table 2: departments Mumbai

text

💻 3NF Compliant Tables:

-- 3NF: Transitive dependency removed
-- departments table (dept_name and dept_city stay here)
CREATE TABLE departments_3nf (
dept_id VARCHAR(5) PRIMARY KEY,
dept_name VARCHAR(50) NOT NULL,
dept_city VARCHAR(50)
);

-- employees table (only FK to dept, not dept details)
CREATE TABLE employees_3nf (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(50) NOT NULL,
dept_id VARCHAR(5),
FOREIGN KEY (dept_id) REFERENCES departments_3nf(dept_id)
);

-- Now dept_city update = 1 row only!

UPDATE departments_3nf

SET dept_city = 'Hyderabad'

WHERE dept_id = 'D1';

-- Affects both Rahul and Amit automatically via FK!

⚠️ Common Mistakes:

  • Mistake: 2NF aur 3NF ka fark bhool jaana → 2NF = partial dependency (composite PK). 3NF = transitive dependency (non-key to non-key).
    Fix: Yaad rakho: 2NF partial, 3NF transitive.
  • Mistake: Har dependency ko transitive samajhna → emp_id → emp_name direct dependency hai — not transitive.
    Fix: Sirf non-key se non-key dependency transitive hai.

💬 Interview Questions:

Q1: What is Third Normal Form and what is Transitive Dependency?
Ans: 3NF requires the table to be in 2NF and have no transitive dependencies. Transitive dependency occurs when a non-key attribute determines another non-key attribute: emp_id → dept_id → dept_name. dept_name depends on dept_id (a non-key), not directly on emp_id. Fix: move dept_name and other dept attributes to a separate departments table, keeping only dept_id as foreign key in employees.

Q2: What is the difference between 2NF and 3NF?
Ans: 2NF eliminates Partial Dependency — where a non-key attribute depends on only PART of a composite primary key. 3NF eliminates Transitive Dependency — where a non-key attribute depends on another non-key attribute (not directly on the primary key). 2NF only applies when composite primary key exists. 3NF applies to all tables and is the most commonly required normal form in production databases.

6. BCNF — Boyce-Codd Normal Form

text

🔍 Definition: Boyce-Codd Normal Form (BCNF) is a stronger version of 3NF. A table is in BCNF if for every functional dependency X → Y, X must be a super key (a key that uniquely identifies all rows). Even candidate keys cannot determine non-key attributes if they are not the chosen primary key.

🎯 Samjho Simple Bhasha Mein: BCNF 3NF se thoda strict hai. 3NF mein ek loophole tha — agar ek candidate key doosre candidate key ka column determine kare toh 3NF mein allowed tha. BCNF yeh bhi band karta hai. Real projects mein BCNF rarely needed hoti hai — 3NF mostly sufficient hai. But interview mein zaroor poochha jaata hai!

💡 BCNF Rule:
For every functional dependency X → Y in the table:
X must be a SUPERKEY (must uniquely identify every row)

3NF vs BCNF Difference:
3NF allows: Non-key → Prime attribute (part of candidate key)
BCNF disallows: Even this — every determinant must be superkey

Most 3NF tables are also in BCNF. BCNF violation is rare.

📊 BCNF Violation Example:

-- Scenario: Student, Subject, Teacher assignment -- Rules: Each subject has multiple teachers -- Each teacher teaches only one subject -- Each student can study each subject with only one teacher -- Candidate Keys: (student, subject) OR (student, teacher) -- Chosen PK: (student, subject) -- ❌ VIOLATES BCNF

studentsubjectteacher
RahulMySQLMr. Sharma
PriyaMySQLMr. Sharma
AmitPythonMrs. Gupta
RahulPythonMrs. Gupta
teachersubjectMr. Sharma
MySQLMrs. GuptaPython
studentteacherRahul
Mr. SharmaPriyaMr. Sharma
AmitMrs. GuptaRahul

Dependency: teacher → subject But 'teacher' is NOT a superkey (it's part of candidate key, not full superkey) This violates BCNF! -- ✅ AFTER BCNF Fix (Decompose into 2 tables) -- Table 1: teacher_subjects -- Table 2: student_teachers Mrs. Gupta

text

💬 Interview Questions:

Q1: What is BCNF and how is it different from 3NF?
Ans: BCNF (Boyce-Codd Normal Form) is a stricter version of 3NF. In 3NF, a non-key attribute can depend on a prime attribute (part of a candidate key) — BCNF disallows this. BCNF rule: for every functional dependency X → Y, X must be a superkey. Every BCNF table is in 3NF, but not every 3NF table is in BCNF. BCNF violation is rare in practice.

Q2: In what order are Normal Forms applied?
Ans: Normal Forms are applied sequentially — each higher form builds on the previous: UNF (unnormalized) → 1NF (atomic values, PK) → 2NF (no partial dependency) → 3NF (no transitive dependency) → BCNF (every determinant is superkey) → 4NF → 5NF. Most production databases aim for 3NF as it balances data integrity with query performance.

7. Denormalization — Kab Torna Hai Rules

text

🔍 Definition: Denormalization is the intentional process of adding redundancy back into a normalized database to improve read performance. It trades storage space and write complexity for faster query execution. Used in data warehouses, reporting systems, and high-traffic read-heavy applications.

🎯 Samjho Simple Bhasha Mein: Normalization mein hum data ko tod ke alag tables mein daala. Denormalization mein hum kuch data wapas saath rakhte hain — performance ke liye. Socho ek e-commerce site par har product query mein category table ka JOIN lagana padta hai. Agar traffic 1 lakh users per second hai toh yeh JOIN slow padega. Solution: category_name ko products table mein hi rakh do — ek JOIN bachega, query fast hogi. Yeh denormalization hai.

💡 Denormalization — Kab Use Karein:
✅ Read-heavy applications (100x reads vs writes)
✅ Reporting aur Analytics dashboards
✅ Data Warehouses (OLAP systems)
✅ Frequently joined tables jo slow hain
✅ Aggregate values jo baar baar calculate hoti hain

❌ Write-heavy transactional systems (banking, inventory)
❌ Jab data consistency critical ho
❌ Small datasets (JOIN overhead negligible)

📊 Normalization vs Denormalization:

Feature Normalization Denormalization
Data Redundancy ❌ Minimal ✅ Intentional
Read Performance 🐢 Slower (JOINs needed) ⚡ Faster (no JOINs)
Write Performance ⚡ Faster (one place) 🐢 Slower (multiple updates)
Storage Space Less More
Data Consistency ✅ High ⚠️ Risk of inconsistency
Use Case OLTP (banking, orders) OLAP (reports, analytics)

💻 Denormalization Example:

-- Normalized (3NF): products + categories JOIN needed
SELECT p.name, p.price, c.category_name

FROM products p

JOIN categories c
ON p.category_id = c.category_id;

-- JOIN slow hai on high traffic

-- Denormalized: category_name directly in products
CREATE TABLE products_denorm (
product_id INT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
category_id INT,
category_name VARCHAR(50) -- Redundant but fast!
);

-- No JOIN needed now!
SELECT name, price, category_name

FROM products_denorm;

-- Much faster on millions of rows!

-- But update problem: category name change = update all products!

UPDATE products_denorm

SET category_name = 'Electronics & Gadgets'

WHERE category_id = 5;

-- Might update thousands of rows!

💬 Interview Questions:

Q1: What is Denormalization and when should you use it?
Ans: Denormalization intentionally adds redundancy to a normalized database to improve read performance. Use it when: read operations far outnumber writes, complex JOINs create performance bottlenecks, reporting/analytics queries are slow, or in data warehouse (OLAP) systems. Trade-off: faster reads but slower writes, more storage, and risk of data inconsistency if updates are not carefully managed.

Q2: What is the difference between OLTP and OLAP systems?
Ans: OLTP (Online Transaction Processing) handles day-to-day transactions — highly normalized, optimized for writes, many short transactions. Examples: banking, e-commerce orders. OLAP (Online Analytical Processing) handles business intelligence/reporting — often denormalized, optimized for reads, few complex queries on large datasets. Examples: data warehouses, dashboards. OLTP uses 3NF; OLAP uses star/snowflake schemas with denormalization.

8. Real-World Schema — Complete E-commerce Database

text

🔍 Definition: A real-world E-commerce database schema that applies all the concepts learned — ER modeling, proper normalization (3NF), relationships, constraints, and best practices. This is the type of schema asked in system design interviews and used in actual production applications.

🎯 Samjho Simple Bhasha Mein: Ab sab kuch ek saath use karenge. Amazon ya Flipkart jaisi e-commerce site ka database kaise design hoga? Customers, Products, Orders, Categories, Addresses, Payments — sab kuch proper normalized schema mein. Yeh poori masterclass ka practical culmination hai!

📊 Complete E-commerce Schema — ER Overview:

▼
▼ ▼
PAYMENTS CATEGORIES

💻 Complete E-commerce SQL Schema:

Step 1: Database aur Categories table banao.

-- Complete E-commerce Database
CREATE DATABASE ecommerce_db;

USE ecommerce_db;

-- 1. CATEGORIES (parent table — no foreign keys)
CREATE TABLE categories (
category_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
parent_id INT DEFAULT NULL, -- Self-referencing for sub-categories
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (parent_id) REFERENCES categories(category_id)
);

INSERT INTO categories (name, description, parent_id)
VALUES
('Electronics', 'Electronic devices', NULL),
('Mobiles', 'Mobile phones', 1),
('Laptops', 'Laptop computers', 1),
('Clothing', 'Apparel and fashion', NULL),
('Books', 'Books and literature', NULL);

Step 2: Customers aur Addresses tables.

-- 2. CUSTOMERS
CREATE TABLE customers (
customer_id INT PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
phone VARCHAR(15),
password_hash VARCHAR(255) NOT NULL,
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 3. ADDRESSES (1:N with customers — one customer, many addresses)
CREATE TABLE addresses (
address_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
address_type ENUM('Home','Work','Other') DEFAULT 'Home',
address_line1 VARCHAR(200) NOT NULL,
address_line2 VARCHAR(200),
city VARCHAR(50) NOT NULL,
state VARCHAR(50) NOT NULL,
pincode VARCHAR(10) NOT NULL,
is_default TINYINT(1) DEFAULT 0,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE CASCADE
);

INSERT INTO customers (first_name, last_name, email, phone, password_hash)
VALUES
('Rahul', 'Sharma', 'rahul@email.com', '9876543210', 'hashed_pw_1'),
('Priya', 'Singh', 'priya@email.com', '9876543211', 'hashed_pw_2'),
('Amit', 'Kumar', 'amit@email.com', '9876543212', 'hashed_pw_3');

Step 3: Products table.

-- 4. PRODUCTS
CREATE TABLE products (
product_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
sale_price DECIMAL(10,2),
stock_qty INT DEFAULT 0,
category_id INT,
brand VARCHAR(100),
sku VARCHAR(50) UNIQUE,
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(category_id),
CHECK (price > 0),
CHECK (stock_qty >= 0)
);

INSERT INTO products (name, price, sale_price, stock_qty, category_id, brand, sku)
VALUES
('Samsung Galaxy S24', 79999, 74999, 50, 2, 'Samsung','SKU-MOB-001'),
('iPhone 15 Pro', 134900,NULL, 30, 2, 'Apple', 'SKU-MOB-002'),
('Dell XPS 15 Laptop', 124999,119999,20, 3, 'Dell', 'SKU-LAP-001'),
('Clean Code Book', 599, 499, 100, 5, 'Pearson','SKU-BOK-001');

Step 4: Orders, Order Items aur Payments.

-- 5. ORDERS
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
address_id INT,
status ENUM('Pending','Confirmed','Shipped','Delivered','Cancelled')
DEFAULT 'Pending',
total_amount DECIMAL(12,2) NOT NULL,
discount_amount DECIMAL(10,2) DEFAULT 0,
final_amount DECIMAL(12,2) NOT NULL,
notes TEXT,
ordered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
FOREIGN KEY (address_id) REFERENCES addresses(address_id)
);

-- 6. ORDER_ITEMS (Junction table — M:N between orders and products)
CREATE TABLE order_items (
order_item_id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL, -- Price at time of order (not current price)
total_price DECIMAL(12,2) NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(product_id),
CHECK (quantity > 0)
);

-- 7. PAYMENTS
CREATE TABLE payments (
payment_id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT UNIQUE NOT NULL, -- 1:1 with order
payment_method ENUM('UPI','Card','NetBanking','COD','Wallet'),
amount DECIMAL(12,2) NOT NULL,
status ENUM('Pending','Success','Failed','Refunded') DEFAULT 'Pending',
transaction_id VARCHAR(100) UNIQUE,
paid_at TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);

Step 5: Sample data insert aur analytics queries.

-- Sample orders

INSERT INTO orders (customer_id, status, total_amount, final_amount)
VALUES
(1, 'Delivered', 79999, 74999),
(2, 'Shipped', 134900,134900),
(1, 'Pending', 599, 499);

INSERT INTO order_items (order_id, product_id, quantity, unit_price, total_price)
VALUES
(1, 1, 1, 74999, 74999),
(2, 2, 1, 134900, 134900),
(3, 4, 1, 499, 499);

-- ===== ANALYTICS QUERIES ON E-COMMERCE SCHEMA =====

-- 1. Customer order history with totals
SELECT
CONCAT(c.first_name, ' ', c.last_name) AS customer,
COUNT(o.order_id) AS total_orders,
SUM(o.final_amount) AS lifetime_value,
MAX(o.ordered_at) AS last_order

FROM customers c
LEFT
JOIN orders o
ON c.customer_id = o.customer_id

GROUP BY c.customer_id

ORDER BY lifetime_value DESC;

-- 2. Top selling products
SELECT
p.name,
SUM(oi.quantity) AS units_sold,
SUM(oi.total_price) AS revenue

FROM products p
INNER
JOIN order_items oi
ON p.product_id = oi.product_id

GROUP BY p.product_id

ORDER BY revenue DESC;

-- 3. Category wise revenue
SELECT
cat.name AS category,
COUNT(DISTINCT p.product_id) AS products,
COALESCE(SUM(oi.total_price), 0) AS total_revenue

FROM categories cat
LEFT
JOIN products p
ON cat.category_id = p.category_id
LEFT
JOIN order_items oi
ON p.product_id = oi.product_id

GROUP BY cat.category_id

ORDER BY total_revenue DESC;

-- 4. Low stock alert
SELECT
name,
stock_qty,
brand,
CASE

WHEN stock_qty = 0
THEN 'OUT OF STOCK'

WHEN stock_qty 10
THEN 'LOW STOCK'

ELSE 'IN STOCK'

END AS stock_status

FROM products

WHERE is_active = 1

ORDER BY stock_qty ASC;

📊 Expected Output (Query 1 — Customer LTV):

customertotal_orderslifetime_valuelast_order
Rahul Sharma275498.002024-01-15 10:00:00
Priya Singh1134900.002024-01-14 15:30:00
Amit Kumar0NULLNULL
text

📊 Schema Design Best Practices Used:

Practice Where Used Why
AUTO_INCREMENT PK All tables Unique identifier, no manual management
ON DELETE CASCADE addresses, order_items Customer delete → addresses auto-delete
ENUM for status orders, payments Constrained values, storage efficient
unit_price in order_items order_items Price at order time — product price may change!
Self-referencing FK categories.parent_id Sub-categories without extra table
UNIQUE on payment order_id payments Enforces 1:1 between order and payment
CHECK constraints products, order_items Business rule enforcement at DB level
updated_at TIMESTAMP customers Auto-track last modification time

💬 Interview Questions:

Q1: Design a database schema for an e-commerce application. (System Design Question!)
Ans: Core tables: customers (customer_id, name, email, phone), addresses (address_id, customer_id FK, city, pincode), products (product_id, name, price, stock_qty, category_id FK), categories (category_id, name, parent_id), orders (order_id, customer_id FK, status, total), order_items (order_id FK, product_id FK, quantity, unit_price), payments (payment_id, order_id FK UNIQUE, method, status). Key design decisions: store unit_price in order_items (not product price which can change), UNIQUE on payments.order_id for 1:1, ON DELETE CASCADE for dependent records.

Q2: Why do we store unit_price in order_items instead of referencing product price?
Ans: Product prices change over time — if a product's price is updated, past orders should still show the price at which the customer actually purchased. By storing unit_price directly in order_items at the time of purchase, we preserve historical accuracy. This is called "snapshot" or "point-in-time" data — critical for financial/audit purposes.

Q3: How would you handle the normalization of this schema?
Ans: 1NF: All columns atomic, each table has PK. 2NF: No partial dependencies (all PKs are single column, so auto-satisfied). 3NF: No transitive dependencies — customer address details in separate addresses table, category details in separate categories table, payment details in separate payments table. Each entity is in its own table, referenced via foreign keys.

Summary — Complete Normalization Reference

Normal Form Rule Eliminates Requires
1NF Atomic values, PK exists Multi-value columns, repeating groups Nothing before it
2NF Full functional dependency on PK Partial dependencies Must be in 1NF
3NF No non-key → non-key dependencies Transitive dependencies Must be in 2NF
BCNF Every determinant is superkey Remaining anomalies from 3NF Must be in 3NF

🎯 Top Database Design Interview Questions — Rapid Fire

Q1: 1NF kya violate karta hai? → Multi-value cells ya repeating column groups

Q2: 2NF kab apply hota hai? → Sirf composite primary key hone par — partial dependency eliminate karo

Q3: 3NF mein kya hatate hain? → Transitive dependency — non-key se non-key dependency

Q4: M:N relationship implement kaise karein? → Junction/Bridge table with both FKs as composite PK

Q5: Denormalization kab use karein? → Read-heavy OLAP systems, reporting dashboards, high-traffic applications

Q6: E-commerce mein unit_price order_items mein kyun? → Product price change ho sakti hai — historical accuracy maintain karne ke liye

🎉 MySQL Masterclass — Complete!

Tumne poori MySQL Masterclass complete kar li! Yeh sab cover hua:

✅ Part 1 — Fundamentals (Database, DDL, DML, DCL, TCL)

✅ Part 2 — SELECT Deep Dive (WHERE, Operators, Sorting)

✅ Part 3 — Aggregate Functions & GROUP BY

✅ Part 4 — JOINS (INNER, LEFT, RIGHT, SELF, CROSS)

✅ Part 5 — Subqueries & EXISTS

✅ Part 6 — Advanced (Views, Indexes, Procedures, Triggers, Window Functions)

✅ Part 7 — Database Design (ER, Normalization, Real Schema)

Happy Coding & Keep Building! 🚀

👤
Jatin Kumar
Data Analyst & Educator

Python, SQL, Power BI aur Excel mein practical tutorials likhta hoon — taaki data analytics seekhna aasan ho. Portfolio: jatinanalytics.co.in

Portfolio LinkedIn GitHub Kaggle All Articles
Share:

💬 Comments (0)

Spam/links allowed nahi hain — respectful comments welcome!

Loading comments...

Was this article helpful?
Previous ArticleAdvanced MySQL — Views, Indexes, Stored Procedures, FunctionNext Article SQL Data Cleaning Techniques — 2026 Guide (MySQL)

📚 More Articles Like This

"Subqueries — Queries ke Andar Queries"

Read Article

SQL JOINS — Multiple Tables Ko Connect Karna

Read Article

Aggregate Functions, GROUP BY And HAVING — Data Analytics with SQL

Read Article