Day 6 is what separates people who can write queries from those who can design real systems.
Today you learn how databases are designed, optimized, and enforced.
Normalization is the process of:
Structuring a database to reduce redundancy and improve data integrity.
Goals:
- Eliminate duplicate data
- Prevent update anomalies
- Maintain consistency
Bad table:
| user_id | user_name | order_id | product |
|---|
Issues:
- User name repeated many times
- Updating name requires multiple updates
- Risk of inconsistency
Rule:
- No repeating groups
- Atomic values only (no lists inside cells)
❌ Bad:
| id | products |
|---|---|
| 1 | Laptop, Phone |
✅ Good:
| id | product |
|---|---|
| 1 | Laptop |
| 1 | Phone |
Rule:
- Must be in 1NF
- No partial dependency on composite key
Example problem:
| order_id | product_id | product_name |
If primary key = (order_id, product_id)
product_name depends only on product_id → violation
✅ Fix: Split into:
products order_items
Rule:
- Must be in 2NF
- No transitive dependency
❌ Bad:
| user_id | country | country_code |
country_code depends on country, not user_id
✅ Fix:
users countries
Normalization improves:
- Data integrity
- Storage efficiency
- Logical clarity
Trade-off:
- More joins required
An index is a data structure that improves query speed.
Think: Book index → jump to page instead of reading entire book.
SELECT * FROM users WHERE age = 30;Database scans ALL rows → slow.
CREATE INDEX idx_age ON users(age);Now database uses B-tree:
- Logarithmic lookup
- Much faster
- Balanced tree
- Sorted values
- Fast lookup: O(log n)
- Primary Index (auto-created)
- Unique Index
- Composite Index
Example:
CREATE INDEX idx_user_country_age
ON users(country, age);Indexes improve: ✔ SELECT speed
But slow down: ❌ INSERT ❌ UPDATE ❌ DELETE
Because index must be updated.
Use when:
- Frequent filtering (
WHERE) - Joins (
JOIN) - Sorting (
ORDER BY)
Avoid:
- Small tables
- Columns rarely queried
name VARCHAR(100) NOT NULLPrevents missing data.
email VARCHAR(100) UNIQUENo duplicates allowed.
id INT PRIMARY KEY- Unique
- Not null
- Indexed
FOREIGN KEY (user_id) REFERENCES users(id)Ensures relational integrity.
CHECK (age >= 0)Enforces rules.
They push validation into the database.
Even if backend fails → database stays correct.
We design properly normalized schema.
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL
);CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
price INT CHECK (price > 0)
);CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
created_at DATE,
FOREIGN KEY (user_id) REFERENCES users(id)
);CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT CHECK (quantity > 0),
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);✔ No redundancy
✔ Scalable
✔ Maintains integrity
✔ Supports complex queries
CREATE INDEX idx_orders_user ON orders(user_id);
CREATE INDEX idx_order_items_product ON order_items(product_id);What is normalization and why is it important?
Give an example of a 1NF violation.
Why does 2NF require removal of partial dependencies?
Explain transitive dependency with an example.
Why can over-normalization hurt performance?
Explain how indexes improve JOIN performance.
Design a database schema for a school system with:
- students
- teachers
- courses
- enrollments
- https://pgexercises.com/
- https://leetcode.com/problemset/database/
- https://sqlzoo.net/
- https://www.hackerrank.com/domains/sql
Focus today:
- Schema design
- Index usage
- Data integrity
You should now:
✔ Understand normalization (1NF–3NF)
✔ Know how indexes work internally
✔ Use constraints properly
✔ Design a real database schema
✔ Think like a database engineer
Tomorrow (Day 7):
You will:
- Build a full mini-project
- Write 25+ real queries
- Simulate job-level SQL tasks