Menu

ATTACH DATABASE di SQLite: Query ke Banyak File Sekaligus

Cara ATTACH DATABASE membuka beberapa file SQLite dalam satu koneksi, menjalankan query lintas file dengan prefiks skema, dan melepasnya saat sudah selesai.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Satu Koneksi, Banyak File

Koneksi SQLite tidak terkunci pada satu file saja. Dengan ATTACH DATABASE, kamu bisa membuka file .db tambahan di samping file awal, lalu menjalankan query ke semuanya seolah-olah semuanya adalah skema di dalam satu database. Inilah hal yang paling mendekati "banyak database dalam satu server" di SQLite.

Bentuk dasarnya:

File archive.db dibuat kalau belum ada, sama seperti database utama. Mulai sekarang dalam sesi ini, apa pun yang diawali archive. berada di file kedua itu. Apa pun yang diawali main. (atau tanpa prefiks) berada di file aslinya.

Koneksimu selalu punya dua skema tersirat: main (file yang pertama kali kamu buka) dan temp (ruang coretan untuk tabel sementara). Melampirkan database menambah skema lagi.

Sintaks dan Fungsi Alias

ATTACH DATABASE 'path/to/file.db' AS alias_name;

Alias adalah nama skema yang akan kamu pakai untuk menandai tabel. Alias hanya berlaku di koneksi saat ini: koneksi lain yang melampirkan file yang sama boleh memilih alias berbeda. Pilih nama yang pendek dan jelas (archive, analytics, cache) karena kamu akan sering mengetiknya.

Beberapa hal yang perlu diketahui:

  • Path dihitung relatif terhadap direktori kerja proses, kecuali berupa path absolut.
  • String ':memory:' melampirkan database in-memory yang baru di bawah alias tersebut.
  • Alias tidak boleh bentrok dengan main atau temp, dan tidak boleh dipakai dua kali.

Join Lintas Database

Inilah fitur yang paling sering menjadi alasan orang melampirkan database. Begitu dua file berada di koneksi yang sama, kamu bisa melakukan join pada tabel-tabelnya dalam satu query:

Query planner memperlakukan kedua skema sama seperti tabel di main. Index pada tabel terlampir tetap dipakai. EXPLAIN QUERY PLAN juga bekerja lintas skema. Tidak ada perjalanan bolak-balik lewat jaringan, karena kedua file terbuka di proses yang sama.

Ini sangat berguna untuk memisahkan data yang sering diakses dari arsip lama, memisahkan file per tenant, atau mengambil data referensi dari database lookup yang read-only.

Lampiran Read-Only dan In-Memory

Kalau database kedua adalah sesuatu yang ingin kamu baca tapi tidak pernah kamu ubah, misalnya dataset referensi yang ikut dikirim, lampirkan sebagai read-only dengan URI:

Bentuk URI mengharuskan library SQLite mengaktifkan SQLITE_OPEN_URI (aktif di CLI dan sebagian besar binding bahasa pemrograman). Setiap INSERT, UPDATE, atau DELETE ke ref.* akan memunculkan error sebelum menyentuh file.

Lampiran in-memory juga praktis untuk menampung data sementara:

scratch hilang saat koneksi ditutup. Mirip temp, tapi kamu yang mengatur masa hidupnya.

Transaksi Mencakup Setiap Database Terlampir

Satu BEGIN/COMMIT mencakup penulisan ke main dan setiap skema terlampir. Semuanya di-commit atau semuanya di-rollback, jadi atomisitas tetap terjaga lintas file:

Memindahkan baris dari tabel aktif ke file arsip adalah contoh operasi yang membutuhkan jaminan ini. Tanpa atomisitas lintas file, crash di tengah proses bisa meninggalkan duplikat atau, lebih buruk lagi, baris yang hilang.

Satu catatan: saat lebih dari satu database terlampir ditulisi dalam satu transaksi, SQLite memakai protokol commit yang lebih hati-hati dan membutuhkan journal sementara. Prosesnya lebih lambat dibanding commit satu file, tapi tetap aman.

Melepas Database

Kalau kamu sudah selesai memakai database terlampir, lepaskan:

DETACH DATABASE archive;

File-nya tetap utuh di disk: DETACH hanya menutup handle di koneksi saat ini. Ada dua batasan yang perlu diingat:

  • Kamu tidak bisa melepas main atau temp.
  • Kamu tidak bisa melepas database yang sedang berada di dalam transaksi atau masih punya pernyataan yang terbuka terhadapnya.

Kalau kamu lupa melepasnya, itu bukan masalah besar: menutup koneksi akan membereskan semuanya.

Batasan dan Error yang Umum

Beberapa batasan praktis yang perlu diketahui:

  • Batas bawaannya adalah 10 database terlampir per koneksi (ditambah main dan temp). Maksimum saat kompilasi adalah 125. Kalau mencapai batas, kamu akan melihat too many attached databases - max 10.
  • Setiap file terlampir memakai page cache. Melampirkan selusin database besar tidak gratis, karena pemakaian RAM ikut naik.
  • ATTACH sendiri tidak bisa dijalankan di dalam transaksi. Jalankan sebelum BEGIN, atau setelah COMMIT.

Beberapa error yang kemungkinan besar akan kamu temui:

-- File doesn't exist and the directory isn't writable:
Error: unable to open database: 'missing/path.db'

-- You tried to write to a read-only attachment:
Error: attempt to write a readonly database

-- You used the same alias twice:
Error: database archive is already in use

Sebagian besar langsung jelas begitu kamu membacanya. Yang "already in use" sering menjebak orang: ATTACH tidak menggantikan alias yang sudah ada, jadi kamu harus menjalankan DETACH lebih dulu.

Pola Nyata: Memisahkan Data Aktif dan Arsip

Kalau semuanya digabungkan, berikut alur kerja arsip kecil yang memindahkan pesanan berumur lebih dari setahun keluar dari database utama:

Baris lama pindah ke archive.orders, baris yang baru tetap di main. Laporan yang butuh riwayat bisa melakukan join ke keduanya, sementara query sehari-hari ke main.orders tetap cepat karena tabelnya lebih kecil. Satu koneksi, dua file, satu transaksi.

Berikutnya: Prepared Statement

ATTACH adalah tentang memberi satu koneksi akses ke lebih banyak data. Topik-topik berikutnya membahas cara aplikasi berkomunikasi dengan SQLite secara aman dan efisien, dimulai dari prepared statement, fondasi dari parameter binding dan query yang kebal terhadap injection.

Pertanyaan yang sering diajukan

Apa yang dilakukan ATTACH DATABASE di SQLite?

ATTACH DATABASE 'file.db' AS alias membuka file database SQLite kedua di dalam koneksi yang sedang berjalan dan memberinya nama skema. Setelah itu, kamu bisa merujuk tabelnya sebagai alias.table_name dan menggabungkannya dengan tabel di database utamamu dalam satu query.

Berapa banyak database yang bisa dilampirkan SQLite sekaligus?

Secara bawaan, SQLite mengizinkan hingga 10 database terlampir per koneksi, ditambah skema main dan temp. Batas maksimalnya 125, yang bisa diatur saat kompilasi lewat SQLITE_MAX_ATTACHED. Kalau kamu mencapai batas itu, kamu akan mendapat error too many attached databases.

Bisakah saya menjalankan query lintas database SQLite terlampir dalam satu pernyataan?

Bisa. Setelah dilampirkan, tulis setiap tabel lengkap dengan nama skemanya: SELECT * FROM main.users JOIN archive.orders ON .... Join, subquery, dan INSERT ... SELECT semuanya bekerja lintas skema. Transaksi juga mencakup setiap database terlampir, jadi COMMIT bersifat atomik di semua file.

Bagaimana cara melepas database SQLite?

Jalankan DETACH DATABASE alias. File-nya tetap utuh di disk: DETACH hanya menutup handle di koneksi yang sedang berjalan. Kamu tidak bisa melepas main atau temp, dan tidak bisa melepas database yang sedang berada di tengah transaksi.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai