Siklus hidup basis data

Membuat, menyiapkan schema, dan menghapus basis data secara terkendali.

Daftar isi

Topik ini membahas siklus hidup basis data, yaitu pembuatan melalui CREATE DATABASE, pemisahan ruang nama melalui schema, dan penghapusan yang terkendali. Basis data adalah unit isolasi terbesar pada server, dan schema menjadi pembatasan di dalamnya, sehingga keduanya membentuk tata letak yang dipikirkan sejak awal.

Blok penyiapan dataset#

bash
# basis data kerja dan role latihan untuk topik ini
PGOPTIONS='-c client_min_messages=warning' psql -q -U postgres -d perpustakaan <<'SQL'
DROP TABLE IF EXISTS peminjaman, buku, anggota, kategori CASCADE;
CREATE TABLE kategori (id SERIAL PRIMARY KEY, nama TEXT NOT NULL UNIQUE);
CREATE TABLE anggota (id SERIAL PRIMARY KEY, nama TEXT NOT NULL, email TEXT UNIQUE, bergabung DATE NOT NULL, aktif BOOLEAN NOT NULL DEFAULT TRUE);
CREATE TABLE buku (id SERIAL PRIMARY KEY, judul TEXT NOT NULL, penulis TEXT NOT NULL, tahun INTEGER NOT NULL, kategori_id INTEGER REFERENCES kategori(id));
CREATE TABLE peminjaman (id SERIAL PRIMARY KEY, anggota_id INTEGER NOT NULL REFERENCES anggota(id), buku_id INTEGER NOT NULL REFERENCES buku(id), tanggal_pinjam DATE NOT NULL, tanggal_kembali DATE);
INSERT INTO kategori (nama) VALUES ('Pemrograman'), ('Sains'), ('Sejarah'), ('Fiksi'), ('Statistika');
INSERT INTO anggota (nama, email, bergabung, aktif) VALUES ('Ali Rahman', '[email protected]', '2024-01-15', TRUE), ('Budi Santoso', '[email protected]', '2024-03-02', TRUE), ('Citra Kirana', '[email protected]', '2024-05-20', FALSE), ('Dewi Lestari', '[email protected]', '2024-08-11', TRUE), ('Eka Pratama', NULL, '2025-01-30', TRUE);
INSERT INTO buku (judul, penulis, tahun, kategori_id) VALUES ('Dasar Basis Data', 'Sari Wulandari', 2021, 1), ('Jaringan Komputer', 'Ahmad Fauzi', 2019, 1), ('Fisika untuk Pemula', 'Rina Marlina', 2020, 2), ('Kimia Organik', 'Rina Marlina', 2022, 2), ('Sejarah Nusantara', 'Bambang Wijaya', 2018, 3), ('Cerita Kota Lama', 'Nur Aisyah', 2023, 4), ('Statistika Terapan', 'Sari Wulandari', 2022, 5), ('Algoritma dan Struktur Data', 'Ahmad Fauzi', 2021, 1);
INSERT INTO peminjaman (anggota_id, buku_id, tanggal_pinjam, tanggal_kembali) VALUES (1, 1, '2025-03-01', '2025-03-15'), (1, 7, '2025-03-05', '2025-03-20'), (2, 3, '2025-03-10', NULL), (3, 5, '2025-02-20', '2025-03-01'), (2, 1, '2025-04-02', NULL), (4, 6, '2025-04-07', NULL), (5, 8, '2025-04-09', '2025-04-25'), (4, 2, '2025-05-01', NULL);
SQL

Membuat dan memeriksa basis data#

CREATE DATABASE menyalin templat bawaan menjadi basis data baru, dan utilitas createdb adalah pembungkusnya yang nyaman dari baris perintah. Blok berikut membuat basis data latihan, memeriksa keberadaannya, lalu menempatkan satu tabel di dalamnya.

bash
# basis data latihan dibuat, diisi, diperiksa, dihapus
PGOPTIONS='-c client_min_messages=warning' psql -q -U postgres -d perpustakaan <<'SQL'
DROP TABLE IF EXISTS peminjaman, buku, anggota, kategori CASCADE;
SQL
psql -U postgres -d postgres -c "DROP DATABASE IF EXISTS uji_lingkup;"
psql -U postgres -d postgres -c "CREATE DATABASE uji_lingkup;"
psql -U postgres -d uji_lingkup -c "CREATE TABLE catatan (id INTEGER PRIMARY KEY, isi TEXT);"
psql -U postgres -d postgres -tAc "SELECT datname FROM pg_database WHERE datname = 'uji_lingkup';"
psql -U postgres -d postgres -c "DROP DATABASE uji_lingkup;"
text Keluaran
NOTICE:  database "uji_lingkup" does not exist, skipping
DROP DATABASE
CREATE DATABASE
CREATE TABLE
uji_lingkup
DROP DATABASE

Basis data baru mewarisi isi templatnya, yang bawaannya kosong dari tabel pengguna, dan pemeriksaan melalui pg_database menegaskan keberadaannya sebelum dihapus. Penyiapan pertama mengosongkan tabel dataset utama pada perpustakaan agar topik ini berdiri sendiri, dan penghapusannya menuntut tidak ada sesi yang tersambung ke basis data sasaran.

Schema sebagai ruang nama#

Schema membagi satu basis data menjadi ruang nama yang saling terpisah, sehingga dua objek boleh bernama sama pada schema yang berbeda. Blok berikut membentuk schema keuangan, menempatkan tabel di dalamnya, dan menunjukkan peran search_path pada pencarian nama.

bash
# schema keuangan dan pengaruh search_path
psql -U postgres -d perpustakaan <<'SQL'
CREATE SCHEMA IF NOT EXISTS keuangan;
CREATE TABLE keuangan.kas (id INTEGER PRIMARY KEY, sisa NUMERIC(12,2) NOT NULL);
INSERT INTO keuangan.kas VALUES (1, 250000.00);
SHOW search_path;
SET search_path = keuangan;
SELECT sisa FROM kas WHERE id = 1;
RESET search_path;
SELECT sisa FROM keuangan.kas WHERE id = 1;
DROP TABLE keuangan.kas;
DROP SCHEMA keuangan;
SQL
text Keluaran
CREATE SCHEMA
CREATE TABLE
INSERT 0 1
   search_path
-----------------
 "$user", public
(1 row)

SET
   sisa
-----------
 250000.00
(1 row)

RESET
   sisa
-----------
 250000.00
(1 row)

DROP TABLE
DROP SCHEMA

Nama tabel tanpa awalan dicari menurut search_path sesi, dan SET search_path memindahkan pencarian ke keuangan sehingga kas menemukan tabelnya tanpa awalan. Bentuk berawalan selalu sah dan lebih eksplisit, sedangkan search_path melayani kenyamanan, dan keduanya menentukan mengapa query yang sama dapat menyasar tabel yang berbeda di dua sesi.

Penghapusan yang terkendali#

DROP DATABASE menolak ketika masih ada koneksi tersambung, perlindungan yang mencegah penghapusan di tengah lalu lintas, dan kebutuhan pemaksaan memakai klausa WITH (FORCE) yang memutus koneksi tersisa. Kebiasaan yang menyertai adalah menegaskan basis data yang dihapus melalui daftar pg_database terlebih dahulu, sebagaimana blok pertama menunjukkan.

DROP SCHEMA juga menerima IF EXISTS untuk pengulangan yang aman, sedangkan CASCADE-nya menghapus seluruh isi schema, perilaku yang dibedah pada topik DROP dan TRUNCATE. Penghapusan basis data tidak dapat dibatalkan melalui transaksi karena melampaui isi satu basis data, sehingga backup pada topik tersendiri menjadi satu-satunya jaring pengamannya.

Kesalahan umum#

Kesalahan pertama adalah bekerja terus pada basis data postgres, yaitu basis data bawaan yang seharusnya hanya untuk administrasi, dan setiap aplikasi memperoleh basis datanya sendiri. Kesalahan kedua adalah mengira schema seperti basis data terpisah, padahal keduanya satu unit backup dan konfigurasi, dan pemisahan antar aplikasi tetap wilayah basis data.

Kesalahan ketiga adalah mengandalkan search_path yang diputar tanpa disiplin, sehingga query yang sama menyasar tabel berbeda menurut sesinya, dan bentuk berawalan untuk objek lintas schema menjadi kebiasaan yang aman. Kesalahan keempat adalah mencoba DROP DATABASE dari sesi yang tersambung ke basis datanya sendiri, yang ditolak server, dan penghapusannya dijalankan dari basis data lain.

Siklus hidup ini menyertakan satu pintu praktis berupa templat basis data, yaitu basis data contoh yang dibuat sekali lalu ditandai sebagai templat melalui kata IS TEMPLATE. Setiap lingkungan uji baru kemudian lahir dari salinan yang seragam dengan satu pernyataan CREATE DATABASE. Salinannya jauh lebih cepat daripada membangun ulang skema melalui migration, sedangkan keterbatasannya jelas, yaitu templat hanya cocok untuk keadaan awal yang tidak sering berubah. Keduanya berpasangan, yaitu migration untuk evolusi dan templat untuk kelahiran.

Ringkasan#

  • CREATE DATABASE atau createdb menyalin templat menjadi basis data baru, dan pg_database memeriksa keberadaannya.
  • Schema memisahkan ruang nama di dalam basis data, dan search_path menentukan pencarian nama tanpa awalan.
  • DROP DATABASE menolak saat masih ada koneksi, dan penghapusannya dijalankan dari basis data lain.
  • Kebiasaan aman memakai bentuk berawalan lintas schema dan menegaskan sasaran sebelum penghapusan.

Referensi#