Memahami perbandingan SQL vs NoSQL (relational, document, key-value, wide-column), replikasi leader-follower synchronous vs asynchronous, dan partitioning/sharding hash-based vs range-based untuk database berskala besar

Setelah di episode 3 kita memahami caching strategies, pada episode ini kita masuk ke komponen paling kritis dalam hampir semua sistem: database. Database menentukan bagaimana data disimpan, diakses, dan di-scale. Keputusan database yang salah bisa membuat sistem tidak bisa scale; keputusan yang tepat bisa menghemat bulan-bulan perbaikan.
Pertanyaan paling umum dalam system design: "SQL atau NoSQL?" Jawabannya bukan "selalu SQL" atau "selalu NoSQL" — tapi "tergantung requirement." Di episode ini kita bedah keduanya secara mendalam, termasuk replikasi dan sharding yang membuat database bisa menangani traffic masif.
PostgreSQL, MySQL, MariaDB — database berbasis tabel dengan schema yang didefinisikan sebelumnya.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
total DECIMAL(10,2),
status VARCHAR(20) DEFAULT 'pending'
);Kelebihan:
Kekurangan:
MongoDB, DynamoDB, CouchDB — data disimpan sebagai dokumen (JSON/BSON).
{
"_id": "user1234",
"name": "Budi",
"email": "budi@example.com",
"orders": [
{"id": "order1", "total": 150000, "status": "delivered"},
{"id": "order2", "total": 75000, "status": "pending"}
]
}Kelebihan:
Kekurangan:
Redis, DynamoDB, etcd — interface paling sederhana: GET(key), SET(key, value).
Kapan pakai: session store, caching, rate limiting, feature flags. Simple dan sangat cepat (sub-millisecond latency).
Cassandra, ScyllaDB, HBase — seperti relational tapi column bisa dinamis per row.
Kapan pakai: time-series data, logging, write-heavy workload yang butuh horizontal scale. Cassandra dipakai oleh Instagram, Apple, Netflix.
InfluxDB, TimescaleDB, Prometheus — dioptimasi untuk data timestamped.
Kapan pakai: metrics, IoT sensor data, monitoring, logging.
| Skenario | Rekomendasi |
|---|---|
| E-commerce (order, user, product) | PostgreSQL (relational, ACID, JOIN) |
| Chat messages (write-heavy, simple query) | Cassandra (wide-column, horizontal scale) |
| Session store (simple key-value, fast) | Redis (in-memory, sub-ms latency) |
| Product catalog (flexible schema) | MongoDB (document, schema-flexible) |
| Metrics/monitoring (time-series) | Prometheus + TimescaleDB |
Replikasi artinya menyimpan copy data di beberapa server untuk redundancy dan read scaling.
| Metode | Konsistensi | Performa | Kapan Pakai |
|---|---|---|---|
| Sync | Kuat (data konsisten segera) | Lambat (tunggu semua replica) | Financial systems, strong consistency |
| Async | Eventual (delay propagasi) | Cepat (tulis ke leader lalu return) | High-throughput systems, read scaling |
| Semi-sync | Balance (tunggu minimal satu replica) | Menengah | Default untuk production (PostgreSQL) |
Pada asynchronous replication, ada delay antara write ke leader dan propagasi ke follower. Dampaknya:
1. User A write "name = Budi" ke leader
2. Leader propagate ke follower (delay 100ms)
3. Dalam 100ms itu, User B read dari follower → dapat "name = Ani" (lama)
4. User B bingung: baru update tapi masih dapat data lamaSolusi: read-after-write consistency — setelah write, baca dari leader untuk N detik berikutnya.
Sharding artinya memecah database menjadi beberapa partisi (shard) yang masing-masing menyimpan sebagian data.
Hash dari shard key menentukan shard tujuan.
Shard key: user_id
shard = hash(user_id) % number_of_shards
user_id=1 → hash(1) % 4 = 1 → Shard 1
user_id=2 → hash(2) % 4 = 3 → Shard 3
user_id=3 → hash(3) % 4 = 2 → Shard 2
user_id=4 → hash(4) % 4 = 0 → Shard 0Kelebihan: distribution merata. Kekurangan: range query sulit (data tersebar di semua shard).
Berdasarkan range dari shard key.
Shard key: user_id
Shard 0: user_id 1-1000
Shard 1: user_id 1001-2000
Shard 2: user_id 2001-3000Kelebihan: range query efisien. Kekurangan: hotspot (semua write baru ke shard terakhir).
Pemilihan shard key adalah keputusan kritis — ia menentukan distribusi data dan query pattern.
| Shard Key | Distribusi | Query Pattern Cocok |
|---|---|---|
user_id (hash) | Merata | Query per user |
user_id (range) | Tidak merata (hotspot di ujung) | Range query user |
timestamp (range) | Tidak merata (hotspot terbaru) | Time-series query |
geographic_region | Merata (jika user tersebar) | Query per region |
Warning
Pemilihan shard key yang buruk bisa membuat satu shard menerima 90% traffic (hotspot). Selalu analisis query pattern sebelum memilih shard key. Jika ragu, gunakan hash-based sharding untuk distribusi merata.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
category_id INTEGER REFERENCES categories(id),
price DECIMAL(10,2),
stock INTEGER DEFAULT 0
);
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
-- Query dengan JOIN
SELECT p.name, c.name as category, p.price
FROM products p
JOIN categories c ON p.category_id = c.id;{
"_id": "product1234",
"name": "Laptop ASUS",
"category": {"id": "cat1", "name": "Electronics"},
"price": 12000000,
"stock": 50
}Di episode 13 kita bedah sharding lebih dalam: resharding, cross-shard query, dan distributed transactions.
Inti yang harus dibawa pulang:
Di episode 5 selanjutnya kita akan membahas database deep dive: indexing & optimization — B-Tree, LSM-Tree, EXPLAIN ANALYZE, dan cara optimasi query lambat di PostgreSQL. Database yang sudah di-shard pun tetap butuh indexing yang tepat untuk performa optimal!