Database Fundamentals
Database কেন এত গুরুত্বপূর্ণ?
একটা system এর performance এর ৮০% নির্ভর করে database design এর উপর। ভুল database choose করলেন, index না দিলে, বা wrong schema করলেন — ১০০ জন user এলেই সব crash করে।
Interview এ "Design Instagram" বললে — কোন database? SQL নাকি NoSQL? Photos কোথায়? Follow relationship কীভাবে? Feed কীভাবে fast? — সব database question। Database choice ই system এর সবচেয়ে critical decision।
DEFINITION
Database হলো organized data storage system। শুধু store নয় — efficiently retrieve, update, delete এবং manage করাই database এর কাজ। একই query milliseconds এ return করবেন নাকি seconds এ — সেটা নির্ভর করে database design এর উপর।
SQL vs NoSQL — সবচেয়ে বড় decision
প্রতিটি project এর শুরুতে এই decision নিতে হয়। কোনো একটা "সবসময় better" না — use case বুঝে decide করতে হয়।
📊 SQL — Relational
Structured data, ACID transactions, complex JOINs। Fixed schema। Banking, e-commerce orders, user accounts এর জন্য best।
🌊 NoSQL — Non-Relational
Flexible schema, horizontal scaling, high throughput। Social feed, caching, IoT, product catalog এর জন্য best।
| বিষয় | SQL | NoSQL |
|---|---|---|
| Schema | Fixed (ALTER TABLE লাগে) | Flexible |
| Scaling | Vertical (harder horizontal) | Horizontal (সহজ) |
| ACID | Full ACID support | Eventual consistency |
| JOIN | Complex JOINs সহজ | JOIN কঠিন বা অসম্ভব |
| Query Language | Standard SQL (সব DB তে একই) | Database-specific API |
| Best For | Banking, Orders, Auth, Reporting | Feed, Cache, IoT, Search |
NoSQL এর ৪টি Type — কোনটা কী কাজে
| Type | Database | Best For |
|---|---|---|
| Key-Value | Redis, DynamoDB | Caching, Sessions, Shopping cart, Rate limiting |
| Document | MongoDB, Firestore | User profiles, Product catalog, Blog posts |
| Column-family | Cassandra, HBase | Time-series, IoT sensor data, Analytics |
| Graph | Neo4j, Amazon Neptune | Social network, Fraud detection, Recommendation |
🎯 Interview এ এটা বলুন
"আমি SQL দিয়ে শুরু করবো কারণ ACID guarantee এবং mature tooling। Data model unclear বা massive write scale দরকার হলে NoSQL consider করবো। Real production systems এ সাধারণত দুটোই use হয় — Polyglot Persistence।" এটাই industry standard answer।
ACID — Transaction এর ৪টি Guarantee
ACID মানে Atomicity, Consistency, Isolation, Durability। Bank transfer ভাবুন — টাকা একটা account থেকে কাটলে অবশ্যই অন্যটায় যোগ হতে হবে। এই guarantee দেয় ACID।
-- Bank Transfer — ACID transaction এর classic example
BEGIN TRANSACTION;
-- Step 1: Sender থেকে টাকা কাটো
UPDATE accounts SET balance = balance - 5000
WHERE account_id = 101;
-- Step 2: Balance negative হলে সব undo — Atomicity!
IF (SELECT balance FROM accounts WHERE account_id = 101) < 0 THEN
ROLLBACK; -- দুটো UPDATE এর কোনোটাই হবে না
RAISE EXCEPTION 'Insufficient balance';
END IF;
-- Step 3: Receiver এ টাকা যোগ করুন
UPDATE accounts SET balance = balance + 5000
WHERE account_id = 202;
-- Step 4: Audit log রাখুন
INSERT INTO transfer_log (from_id, to_id, amount, created_at)
VALUES (101, 202, 5000, NOW());
COMMIT; -- সব ঠিক থাকলে permanent save — Durability!Indexing — Database এর Superpower
Index হলো book এর index page এর মতো। পুরো book না পড়ে সরাসরি page এ যানয়া যায়। Database এ index না থাকলে প্রতিটি query তে পুরো table scan করতে হয় — ১০ লক্ষ row এ এটা অনেক slow।
✅ Index দিন যখন
WHERE clause এ frequently query হয়। High cardinality column (email, phone)। Foreign key columns। Read-heavy workload।
❌ Index এড়াও যখন
Write-heavy table (INSERT/UPDATE slow হয়)। ১০০০ row এর কম small table। Low cardinality (true/false, status)। Rarely queried columns।
-- 1. Basic index — single column
CREATE INDEX idx_users_email ON users(email);
-- 2. Composite index — দুটো column একসাথে filter করলেন
-- WHERE email = ? AND created_at > ?
CREATE INDEX idx_users_email_date ON users(email, created_at);
-- 3. Partial index — শুধু active users (ছোট এবং fast)
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';
-- 4. Query plan দেখুন — index use হচ্ছে কি?
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'test@example.com';
-- "Index Scan" → ভালো ✅ | "Seq Scan" → index নেই ⚠️Sharding এবং Replication
Read Replica — Read Load কমাও
সব database operation এর ৮০-৯০% হলো READ। Primary database এর copy (Replica) রাখুন — Read requests Replica তে পাঠাও। Primary শুধু Write handle করবেন। এভাবে Primary এর load অনেক কমে।
Sharding — Write Load ভাগ করুন
একটা বড় table কে multiple databases এ ভাগ করা। User ID 1-1M → DB1, 1M-2M → DB2। প্রতিটি shard আলাদাভাবে serve করতে পারে।
| Approach | কীভাবে কাজ করে | কখন ব্যবহার করুন |
|---|---|---|
| Read Replica | Primary → Replica async sync। Read → Replica | Read-heavy app (80%+ read) |
| Vertical Sharding | আলাদা table → আলাদা DB (users DB, orders DB) | Microservices separation |
| Horizontal Sharding | একই table rows ভাগ করে multiple DB তে | Billions of rows, write scale |
⚠️ Sharding এর সমস্যা
Cross-shard JOIN কঠিন — User A Shard 1 এ, User B Shard 3 এ, এদের data JOIN করতে application layer এ করতে হয়। Resharding complex। Hotspot shard হতে পারে। তাই Sharding সবচেয়ে শেষে করুন — আগে Read Replica, Caching, Query optimization দিয়ে দেখুন।
DB Pool & Caching Pattern
Backend এ database handle করার সময় connection pool এবং caching strategy (Cache-aside) ব্যবহার করা industry standard। Connection বারবার create করা অনেক expensive, তাই pool ব্যবহার করা হয়।
const { Pool } = require('pg');
const redis = require('redis');
// Connection Pool — connection বারবার create করা expensive!
const primaryDB = new Pool({ host: 'primary-db', max: 20 });
const replicaDB = new Pool({ host: 'replica-db', max: 40 });
const cache = redis.createClient();
// Cache-aside Pattern — সবচেয়ে common caching strategy
async function getUser(userId) {
const cacheKey = `user:${userId}`;
// 1. Cache check করুন
const cached = await cache.get(cacheKey);
if (cached) return JSON.parse(cached); // Cache HIT ✅
// 2. Cache miss — Replica থেকে read (Primary এ load দিও না)
const result = await replicaDB.query(
'SELECT * FROM users WHERE id = $1', [userId]
);
const user = result.rows[0];
// 3. Cache এ store করুন (TTL: 1 hour)
await cache.setEx(cacheKey, 3600, JSON.stringify(user));
return user;
}
// Write — Primary তে
async function updateUser(userId, data) {
await primaryDB.query('UPDATE users SET name=$1 WHERE id=$2', [data.name, userId]);
await cache.del(`user:${userId}`); // Cache invalidate করুন!
}Database Tools — কোনটা কখন ব্যবহার করবেন
| Database | Type | ACID | Scale | Best For |
|---|---|---|---|---|
| PostgreSQL | SQL | ✅ Full | Vertical + Read Replica | Complex queries, JSON, GIS |
| MySQL | SQL | ✅ Full | Master-slave replication | Web apps, E-commerce |
| MongoDB | Document NoSQL | ⚠️ Partial | Horizontal sharding | Flexible schema, JSON docs |
| Redis | Key-Value NoSQL | ❌ No | Cluster mode | Caching, Sessions, Pub/Sub |
| Cassandra | Column NoSQL | ⚠️ Eventual | Linear horizontal | Time-series, IoT, High write |
বড় কোম্পানিগুলো কীভাবে করেছেনে
📱 Instagram এর Database Journey
Instagram শুরু করেছেনিল PostgreSQL দিয়ে। User base ১০M থেকে ১B+ হওয়ার সময় PostgreSQL sharding করে। User ID based consistent hashing দিয়ে ১০০০+ shards। Photos (media files) আলাদাভাবে S3 (object storage) তে রাখে — database তে শুধু metadata। Django ORM এর উপরে custom sharding layer।
🏦 bKash / Banking — ACID Critical
Financial systems এ SQL database অপরিহার্য। Transaction isolation level "SERIALIZABLE" রাখতে হয়। Double-spending prevent করতে database-level locks। Audit log সব transactions এর। Strong consistency mandatory — কোনো eventual consistency চলবে না।
Polyglot Persistence
SUMMARY — আজকে যা শিখলাম
| Concept | এক লাইনে |
|---|---|
| SQL vs NoSQL | SQL = ACID, structured। NoSQL = flexible, scale। Use case দেখে choose করুন |
| ACID | Atomicity (all/nothing), Consistency, Isolation, Durability |
| Index | B-Tree দিয়ে O(n) → O(log n)। Read fast, Write slow হয় |
| Read Replica | Read → Replica, Write → Primary। Read load কমে |
| Sharding | Table rows ভাগ করুন। Write scale করুন। Cross-shard JOIN কঠিন |
| N+1 Problem | Loop এ query করুন না। JOIN বা eager loading ব্যবহার করুন |