Database yang Hidup di RAM
SQLite punya nama file khusus: :memory:. Buka database dengan nama itu, dan SQLite sama sekali melewati disk: seluruh database hidup di RAM. Tabel, index, transaksi, foreign key, setiap fitur bekerja persis sama. Satu-satunya perbedaan adalah saat koneksi ditutup, database-nya hilang.
Dari command line:
sqlite3 :memory:
Sekarang kamu berada di prompt SQLite dengan database baru yang kosong dan hanya ada di memori. Buat tabel, masukkan beberapa baris, lalu jalankan query, semuanya seperti biasa:
Keluar dari sesi, dan data itu lenyap. Tidak ada file yang tertinggal, karena memang tidak pernah ada file yang dibuat.
Kenapa Kamu Menginginkannya
Database yang tidak bisa bertahan setelah restart kedengarannya seperti bug, bukan fitur. Tapi sebenarnya ini berguna dalam tiga situasi.
Pengujian. Setiap pengujian mendapat database bersih dalam hitungan milidetik. Tidak perlu membersihkan file sementara, tidak ada sisa state dari pengujian sebelumnya, tidak ada file fixture bersama yang terkunci. Sebagian besar test suite Python, Node, dan Go yang memakai SQLite membuka :memory: persis karena alasan ini.
Analisis sekali pakai. Muat sebuah CSV, jalankan beberapa query, lalu buang. Lebih cepat daripada menyiapkan database sungguhan, dan lebih mudah daripada mem-parse file di kode setiap kali.
Cache dan ruang coretan. Di dalam program yang berjalan lama, database SQLite in-memory adalah engine query sesaat yang ternyata sangat bagus untuk data yang sudah kamu muat.
Benang merahnya: kamu ingin SQL, tapi tidak ingin data yang tersimpan permanen.
Performa: Lebih Cepat, Tapi Bukan Sulap
Database in-memory melewati disk, jadi penulisan yang biasanya mengenai filesystem hanya menjadi pembaruan memori. Beban kerja yang terbatas oleh I/O terasa jauh lebih cepat. Beban kerja yang terbatas oleh CPU, seperti perencanaan query yang rumit atau pengurutan besar, hampir tidak berubah, karena SQLite memang sudah menyimpan page yang sering diakses di memori.
Demonstrasi singkat bahwa sintaksnya sama persis:
Query itu dijalankan pada database in-memory, tapi SQL-nya sama dengan yang akan kamu jalankan pada file. Engine database tidak peduli.
In-Memory vs File: Kapan Memilih yang Mana
Pertukarannya sederhana, dan layak dijelaskan dengan gamblang:
- Database file (
mydata.db): bertahan setelah restart. Beberapa proses bisa membukanya. Tahan terhadap crash (dengan mode WAL, sebagian besar). Pakai untuk apa pun yang perlu mengingat sesuatu. - Database in-memory (
:memory:): hilang saat ditutup. Secara bawaan, hanya milik koneksi yang membukanya. Lebih cepat untuk pekerjaan sekali pakai yang banyak menulis. Pakai untuk pengujian, pekerjaan coretan, dan cache berumur pendek.
Kalau ragu, pilih file. In-memory adalah kasus khusus.
Setiap Koneksi Mendapat Database Sendiri
Satu hal halus yang sering menjebak orang: membuka :memory: dua kali memberimu dua database yang terpisah. Keduanya tidak berbagi tabel, tidak berbagi data, dan sama sekali tidak saling melihat.
-- Terminal 1
sqlite3 :memory:
sqlite> CREATE TABLE t (x); INSERT INTO t VALUES (1);
-- Terminal 2
sqlite3 :memory:
sqlite> SELECT * FROM t;
Error: no such table: t
Itu bukan bug, melainkan memang begitu desainnya. :memory: berarti "database pribadi untuk koneksi ini." Hal yang sama berlaku di dalam satu program: kalau kodemu membuka dua koneksi ke :memory:, masing-masing mendapat database terisolasinya sendiri.
Berbagi Database In-Memory Antarkoneksi
Kalau kamu memang butuh beberapa koneksi untuk melihat database in-memory yang sama, SQLite mendukungnya lewat nama file URI dan shared cache. String ajaibnya adalah file::memory:?cache=shared:
sqlite3 'file::memory:?cache=shared'
Setiap koneksi di proses yang sama yang membuka URI yang persis sama akan bergabung ke database yang sama. Tutup semuanya, dan database-nya hilang.
Kamu juga bisa memberi nama pada database in-memory. Ini berguna kalau kamu ingin beberapa database bersama yang berbeda:
sqlite3 'file:mydb?mode=memory&cache=shared'
Nama mydb di sini hanyalah label, karena tetap tidak ada file. Dua koneksi yang membuka file:mydb?mode=memory&cache=shared berbagi satu database; koneksi yang membuka file:other?mode=memory&cache=shared mendapat database yang lain.
Menyimpan Database In-Memory ke Disk
Kadang kamu mengerjakan seluruh alur kerja di memori, lalu memutuskan ingin menyimpan hasilnya. CLI punya dot command .backup untuk ini:
sqlite3 :memory:
sqlite> CREATE TABLE results (id INTEGER, score REAL);
sqlite> INSERT INTO results VALUES (1, 0.91), (2, 0.87);
sqlite> .backup snapshot.db
sqlite> .quit
snapshot.db sekarang adalah database file biasa dengan isi yang sama. Kamu bisa membukanya nanti dengan sqlite3 snapshot.db dan melanjutkan dari situ.
Kebalikannya juga bisa: .restore memuat database file ke memori koneksi saat ini:
sqlite3 :memory:
sqlite> .restore snapshot.db
sqlite> SELECT * FROM results;
Dari kode aplikasi, C API SQLite menyediakan mekanisme yang sama lewat sqlite3_backup_init, dan sebagian besar binding bahasa membungkusnya. Contohnya, modul sqlite3 di Python punya Connection.backup().
Kesalahan yang Umum
Orang kadang mencoba "menyimpan" database in-memory dengan melampirkan sebuah file lalu menyalin:
Cara itu berhasil untuk menyalin tabel sederhana, tapi tidak mempertahankan index, trigger, view, atau foreign key persis seperti aslinya. Untuk salinan yang setia dari seluruh database, pakai .backup (atau backup API), yang menyalin secara akurat sampai ke tingkat biner per page.
Yang Perlu Kamu Ingat
:memory:adalah nama file khusus SQLite yang membuat database di RAM tanpa file di baliknya.- SQL-nya sama persis dengan database file: tabel yang sama, query yang sama, constraint yang sama.
- Setiap koneksi ke
:memory:bersifat pribadi; pakai URI shared cache (file::memory:?cache=shared) kalau beberapa koneksi perlu berbagi satu database. - Ini alat yang tepat untuk pengujian, analisis sekali pakai, dan cache berumur pendek, bukan untuk apa pun yang harus bertahan setelah restart.
- Pindahkan database memori ke disk dengan
.backupkalau kamu memutuskan ingin menyimpannya.
Berikutnya: Membuat Tabel
Kamu sudah melihat CREATE TABLE sekilas di beberapa contoh. Halaman berikutnya membahasnya dengan lebih pelan dan lengkap: definisi kolom, tipe, constraint yang bisa kamu pasang, dan pilihan-pilihan kecil yang membuat sebuah skema nyaman dipakai.
Pertanyaan yang sering diajukan
Bagaimana cara membuat database SQLite in-memory?
Buka SQLite dengan nama file khusus :memory:, bukan sebuah path. Dari CLI, caranya sqlite3 :memory:; dari library, pakai pemanggilan connect yang biasa dengan :memory: sebagai nama file. Database-nya hidup di RAM dan hilang saat koneksi ditutup.
Apa itu :memory: di SQLite?
:memory: adalah nama file ajaib yang dikenali SQLite sebagai 'jangan pakai file, simpan semuanya di RAM.' Kamu mendapat database SQLite lengkap, dengan tabel, index, transaksi, dan semuanya, tapi tidak ada yang pernah ditulis ke disk. Setiap koneksi yang membuka :memory: mendapat database pribadinya sendiri.
Bisakah dua koneksi berbagi satu database SQLite in-memory?
Tidak secara bawaan: setiap koneksi :memory: terisolasi. Untuk berbagi, buka database dengan URI seperti file::memory:?cache=shared dan aktifkan shared cache. Setiap koneksi yang membuka URI yang persis sama di dalam proses yang sama akan melihat database yang sama.
Bisakah database SQLite in-memory disimpan ke disk?
Bisa. Pakai perintah .backup di CLI atau backup API di library-mu untuk menyalin database in-memory ke sebuah file. Kamu juga bisa melakukan ATTACH pada database file lalu menjalankan INSERT INTO file.table SELECT * FROM main.table untuk menyalin datanya.