Database Scaling — System Design

Ketika database menjadi bottleneck karena traffic tinggi atau data terlalu besar, kamu perlu strategi scaling database. 1. Read Replicas (Replication) Satu data

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:

Tantangan sharding:

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:

  1. Optimize queries — tambahkan index, perbaiki query lambat
  2. Add caching — Redis untuk data yang sering dibaca
  3. Read replicas — scale read operation
  4. Vertical partitioning — pisah tabel ke DB berbeda
  5. Sharding — opsi terakhir, paling kompleks

Mulai dari yang sederhana. Jangan shard sebelum benar-benar dibutuhkan.

<title>Sharding Key Selection</title> Good: hash(user_id) — merata Shard 1 25% Shard 2 25% Shard 3 26% Shard 4 24% Bad: shard by country — hot skew US Shard 78% HOT EU 12% ASIA 10% Key yang terdistribusi merata (hash) → beban seimbang antar shard. Key yang timpang (country, timezone, signup_date) → satu shard jadi bottleneck saat traffic spike. Pilih shard key yang high-cardinality dan akses-nya tersebar merata.
Distribusi shard yang baik saat memakai hash key; hot shard terjadi saat memilih key yang secara natural timpang seperti country.

🎭 Analogi sehari-hari: Database scaling = perpustakaan kelebihan koleksi.

💡 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:

🎯 Urutan optimasi (dari mudah ke susah):

  1. EXPLAIN + index (cek query plan, fix slow query)
  2. Connection pooling (hindari connect overhead)
  3. Caching layer (Redis untuk hot data)
  4. Read replicas (scale baca)
  5. Vertical partition (pisah by domain)
  6. Sharding (last resort, kompleks ops)
  7. 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.

Yang akan kamu pelajari