Ketika database menjadi bottleneck karena traffic tinggi atau data terlalu besar, kamu perlu strategi scaling database.
1. Read Replicas (Replication) Satu database primary untuk write, beberapa replicas untuk read:
App → Write → Primary DB
→ Read → Replica 1
→ Read → Replica 2
→ Read → Replica 3
Cocok ketika read >> write (kebanyakan aplikasi web). Data dari primary di-replicate ke replicas secara asinkron.
// Pseudo-code: routing read/write
const db = {
write: connectTo("primary.db.com"),
read: connectTo("replica.db.com")
};
// Write → primary
await db.write.query("INSERT INTO articles ...");
// Read → replica (lebih cepat, tidak membebani primary)
const articles = await db.read.query("SELECT * FROM articles");
Replication lag: Ada delay kecil antara primary dan replica. Baca dari replica mungkin mendapat data sedikit lama. Untuk data yang harus fresh (saldo, profil baru diubah), baca dari primary.
2. Vertical Partitioning Pisahkan tabel ke database berbeda berdasarkan fungsionalitas:
Database Users → tabel users, profiles, settings
Database Articles → tabel articles, comments, tags
Database Analytics → tabel page_views, events
3. Horizontal Partitioning (Sharding) Pecah satu tabel besar ke beberapa database berdasarkan key:
User ID 1-1M → Shard 1
User ID 1M-2M → Shard 2
User ID 2M-3M → Shard 3
Sharding strategies:
- Range-based — berdasarkan range ID (mudah tapi bisa tidak seimbang)
- Hash-based —
hash(userId) % numShards(distribusi merata) - Geography-based — user Asia di shard Asia, Eropa di shard Eropa
Tantangan sharding:
- Query cross-shard sulit (JOIN antar shard)
- Rebalancing saat menambah shard
- Single point of failure jika satu shard mati
- ID harus globally unique
4. Indexing — optimasi tanpa scaling
-- Tanpa index: scan seluruh tabel (O(n))
SELECT * FROM articles WHERE author_id = 42;
-- 10 juta row → lambat!
-- Dengan index: lookup langsung (O(log n))
CREATE INDEX idx_author ON articles(author_id);
-- Sekarang cepat!
Jangan over-index — setiap index memperlambat write operation.
5. SQL vs NoSQL
| Aspek | SQL (MySQL, PostgreSQL) | NoSQL (MongoDB, DynamoDB) |
|---|---|---|
| Schema | Fixed, strict | Flexible, schema-less |
| Scaling | Vertical (sulit horizontal) | Horizontal (mudah shard) |
| Joins | Kuat | Terbatas |
| ACID | Ya | Eventual consistency* |
| Cocok untuk | Relasi kompleks, transaksi | Data besar, cepat, flexible |
Urutan optimasi database:
- Optimize queries — tambahkan index, perbaiki query lambat
- Add caching — Redis untuk data yang sering dibaca
- Read replicas — scale read operation
- Vertical partitioning — pisah tabel ke DB berbeda
- Sharding — opsi terakhir, paling kompleks
Mulai dari yang sederhana. Jangan shard sebelum benar-benar dibutuhkan.
🎭 Analogi sehari-hari: Database scaling = perpustakaan kelebihan koleksi.
- Read replicas: kopi buku populer disimpan di banyak rak (bisa banyak orang baca bersamaan)
- Vertical partitioning: rak fiksi terpisah dari rak ilmiah
- Sharding: koleksi A-M di gedung 1, N-Z di gedung 2 (terpisah fisik)
- Indexing: kartu katalog supaya gak harus susuri semua rak
💡 Aturan emas database scaling: Optimize sebelum scale. 90% bottleneck database = query buruk + missing index, bukan butuh shard. Profile dulu. EXPLAIN query lambat. Tambah index. Baru kalau sudah optimal masih lambat → caching. Baru replica. Baru sharding sebagai last resort (sangat kompleks).
⚠️ Jebakan klasik:
- Sharding terlalu cepat — hampir semua aplikasi 1jt user bisa pakai 1 DB + read replicas. Sharding = kompleks operations
- Replication lag ignored — read di replica setelah write di primary = data lama. Untuk read-after-write critical, baca dari primary
- Bad shard key — country/timezone → hot shard. Pilih high-cardinality + access merata
- Cross-shard JOIN = mimpi buruk. Disain schema supaya gak butuh
- Over-indexing — tiap index = write lebih lambat. Cuma index yang dipakai query
🎯 Urutan optimasi (dari mudah ke susah):
- EXPLAIN + index (cek query plan, fix slow query)
- Connection pooling (hindari connect overhead)
- Caching layer (Redis untuk hot data)
- Read replicas (scale baca)
- Vertical partition (pisah by domain)
- Sharding (last resort, kompleks ops)
- Pertimbangkan NoSQL (kalau pattern akses gak fit relational)
TL;DR: Database scaling = optimize → cache → replicate → partition → shard. Mulai dari yang sederhana. Sharding = last resort. SQL vs NoSQL: pilih yang fit pattern data, bukan trend.