Pilih keluarga penyimpanan data
Bandingkan relasional, dokumen, key-value, wide-column, kolumnar, dan graf dari beban kerja, bukan dari merek atau tren.
Pertanyaan
Keluarga penyimpanan data mana yang cocok untuk beban kerja ini, dan apa yang kita korbankan?
Setelah baca ini, kamu bisa memetakan pola akses ke satu atau dua keluarga penyimpanan, menyebut apa yang didapat dan hilang, dan menolak pilihan yang cuma didasari nama produk.
Prasyarat dan contoh
Kamu sudah punya daftar pola akses dengan frekuensi dan syarat kebenaran (M04.01), dan paham target latensi serta durabilitas (M01.04).
Tim memilih "database NoSQL karena skalabel" untuk sistem pemesanan. Dua bulan kemudian mereka butuh laporan "total penjualan per kategori per minggu" dan aturan "stok nggak boleh negatif". Keduanya gampang di basis data relasional dan menyakitkan di store yang mereka pilih. Masalahnya bukan di produknya. Pilihan dibuat sebelum pola akses ditulis.
Keluarga penyimpanan itu cara mengatur data supaya sebagian jenis akses murah. Akses jenis lain otomatis jadi mahal.
Mekanisme
Enam keluarga, masing-masing dengan akses yang murah dan yang mahal:
| Keluarga | Murah | Mahal | | ------------ | ------------------------------------------ | ------------------------------------------ | | Relasional | Join, constraint, transaksi multi-baris, query ad hoc | Skala tulis melewati satu node, skema yang sering berubah drastis | | Dokumen | Baca satu agregat utuh (pesanan beserta itemnya) | Join lintas dokumen, constraint antar dokumen | | Key-value | Get/put berdasarkan key, latensi rendah | Query berdasarkan nilai, range, agregasi | | Wide-column | Tulis volume tinggi, baca rentang dalam satu partisi | Query ad hoc, join, indeks sekunder | | Kolumnar | Agregasi atas jutaan baris pada beberapa kolom | Update satu baris, baca baris utuh, tulis kecil sering | | Graf | Telusuri relasi berlapis (teman dari teman) | Agregasi massal, beban yang nggak berbentuk relasi |
Relasional. Bentuk data direpresentasikan sebagai tabel, dan database menjaga constraint serta transaksi. Default yang masuk akal untuk data bisnis inti sampai ada bukti sebaliknya. Satu node modern bisa melayani ribuan transaksi per detik, jadi batas skala tulisnya jauh lebih tinggi dari yang sering dibayangkan.
Dokumen. Data disimpan sebagai agregat, misalnya satu dokumen JSON untuk satu order lengkap. Cocok kalau hampir semua akses membaca atau menulis agregat itu utuh. Kalau kamu sering bertanya "semua order yang mengandung produk X", agregatnya malah jadi penghalang.
Key-value. Antarmuka paling sederhana: get(key) dan put(key, value). Cocok untuk sesi,
cache, dan konfigurasi. Kalau kamu butuh "cari semua sesi milik user X", kamu harus membangun
indeks sendiri.
Wide-column. Data dikelompokkan per partition key dan diurutkan dalam partisi. Bagus untuk deret waktu atau log per entitas: "semua event milik sensor 42 antara jam 10 dan 11". Query harus dirancang dulu sebelum tabel, kebalikan dari relasional.
Kolumnar. Nilai satu kolom disimpan berdekatan. Query yang menjumlahkan satu kolom dari 100 juta baris hanya membaca kolom itu, bukan seluruh baris, dan kompresinya bagus karena nilai sejenis berdekatan. Ini mesin analitik, bukan mesin transaksi.
Graf. Relasi jadi objek kelas satu. Menelusuri tiga lompatan hubungan itu murah di graf dan bisa meledak jadi join berantai di relasional. Hanya layak kalau penelusuran relasi memang inti beban kerja.
Polyglot itu biaya. Memakai dua store berarti dua operasional, dua mode gagal, dan masalah menjaga keduanya sinkron. Satu store utama plus satu salinan turunan (misalnya warehouse kolumnar untuk laporan) biasanya batas yang masih terkelola.
Saat rancangan ini gagal
- Memilih dari merek. "Perusahaan X pakai ini" tidak menjelaskan beban kerja mereka. Skala mereka mungkin 1.000 kali lebih besar atau pola aksesnya sangat beda.
- Dokumen dengan relasi banyak-ke-banyak. Menyimpan "pengguna" dan "grup" sebagai dokumen tertanam menghasilkan duplikasi, dan mengubah nama grup berarti memperbarui ribuan dokumen.
- Laporan di mesin transaksi. Query agregasi 30 detik di tabel order mengunci sumber daya yang dibutuhkan checkout. Pisahkan lewat replika baca atau salinan kolumnar.
- Mengira "skalabel" berarti "gratis". Store yang bisa partisi otomatis biasanya melepas join dan transaksi lintas partisi. Kamu membayar dengan kompleksitas di aplikasi.
Contoh tandingan: sistem kecil yang memakai tiga store (relasional, key-value, graf) untuk 500 pengguna. Tiap store benar secara teknis, tapi tim dua orang menghabiskan separuh waktunya mengoperasikannya.
Latihan
Tiga beban kerja: (A) profil pengguna, dibaca 2.000/detik berdasarkan user id, ditulis 20/detik; (B) dasbor "pendapatan per hari per wilayah" atas 500 juta baris transaksi, dijalankan 30 kali per jam oleh analis; (C) "rekomendasi teman": cari teman dari teman yang belum berteman, sampai dua lompatan.
Pilih keluarga untuk masing-masing dan sebut satu hal yang dikorbankan.
Lihat pembahasan
A: key-value atau relasional. Akses berdasarkan satu key dengan baca berat cocok untuk key-value, dan 2.000 baca/detik masih mudah untuk relasional dengan primary key. Kalau tidak ada kebutuhan lain, tetap di relasional yang sudah ada: nol store tambahan. Dikorbankan kalau pindah ke key-value: query "semua pengguna di kota X" jadi butuh indeks buatan sendiri.
B: kolumnar. Query menjumlah satu kolom jumlah dikelompokkan oleh dua kolom lain, di
atas 500 juta baris. Mesin kolumnar hanya membaca kolom yang perlu dan memampatkannya. Dikorbankan:
data datang lewat pemuatan berkala dari store transaksi, jadi dasbor tertinggal beberapa menit
sampai jam, dan update per baris mahal.
C: graf, atau relasional dulu. Dua lompatan di relasional itu self-join dua kali. Untuk puluhan juta hubungan bisa lambat, tapi untuk ratusan ribu masih oke dengan indeks yang benar. Pindah ke graf kalau query ini terbukti lambat dan jadi fitur inti. Dikorbankan: satu store lagi yang harus disinkronkan dengan data relasi utama.
Jawaban bagus menyebut angka (2.000/detik, 500 juta baris), bukan cuma label, dan mengakui bahwa A dan C mungkin tetap di relasional.
Terkait
- M01.04 Tentukan sasaran yang berguna menyediakan target latensi dan durabilitas yang memengaruhi pilihan ini.
- M04.01 menghasilkan daftar pola akses yang jadi masukan di sini.
- M07 Partisi dan penempatan data bahas apa yang terjadi saat satu node nggak cukup.
- M09 Mesin penyimpanan bahas B-tree dan LSM yang ada di balik beberapa keluarga ini.
- Rancangan D01 memakai pilihan ini di sistem nyata.
Catatan
- Asumsi: kategori keluarga di sini penyederhanaan. Banyak produk nyata menggabungkan ciri beberapa keluarga (misalnya relasional dengan kolom JSON).
- Yang nggak dibahas: pencarian teks penuh (M11), time-series khusus, dan layanan terkelola tertentu.
- Terakhir ditinjau: 26 Oktober 2026.