Siklus hidup struktur tidak berhenti di membuat dan mengubah — tabel percobaan perlu dibersihkan, database proyek yang sudah ditutup perlu dikembalikan menjadi ruang kosong. Di sinilah keluarga perintah DROP bekerja, dan di sinilah pula satu salah ketik bisa menghapus data produksi dalam hitungan detik tanpa tombol undo. Pada chapter ini kita menghapus tabel biasa, menabrak error ketika tabel masih dipakai tabel lain, memakai CASCADE dengan sadar konsekuensinya, menenangkan script dengan IF EXISTS, lalu menutup dengan DROP DATABASE dari database maintenance — semuanya dengan prosedur yang sama-sama berlaku di server latihan maupun produksi.
Menyiapkan Dua Tabel yang Saling Terkait #
Menghapus menjadi menarik justru ketika tabel-tabelnya berhubungan. Kita siapkan pelanggan dan pesanan, dengan pesanan merujuk pelanggan lewat foreign key — constraint yang menyatakan “nilai kolom ini harus ada sebagai primary key di tabel itu”:
CREATE TABLE pelanggan (
id integer PRIMARY KEY,
nama text NOT NULL
);
CREATE TABLE pesanan (
id integer PRIMARY KEY,
pelanggan_id integer REFERENCES pelanggan (id)
);
INSERT INTO pelanggan (id, nama)
VALUES
(1, 'Budi'),
(2, 'Siti');
INSERT INTO pesanan (id, pelanggan_id)
VALUES
(101, 1),
(102, 2);
SELECT id, nama
FROM pelanggan
ORDER BY id;
SELECT id, pelanggan_id
FROM pesanan
ORDER BY id;
\d pesananOutput yang Dihasilkan:
CREATE TABLE
CREATE TABLE
INSERT 0 2
INSERT 0 2
id | nama
----+------
1 | Budi
2 | Siti
(2 rows)
id | pelanggan_id
-----+--------------
101 | 1
102 | 2
(2 rows)
Table "public.pesanan"
Column | Type | Collation | Nullable | Default
--------------+---------+-----------+----------+---------
id | integer | | not null |
pelanggan_id | integer | | |
Indexes:
"pesanan_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"pesanan_pelanggan_id_fkey" FOREIGN KEY (pelanggan_id) REFERENCES pelanggan(id)Bagian pelanggan_id integer REFERENCES pelanggan (id) adalah deklarasi foreign key-nya: setiap pesanan harus menunjuk pelanggan yang benar-benar ada. Relasi seperti ini kita bahas tuntas di Section Table Design; untuk urusan hari ini, satu fakta yang penting: foreign key menciptakan dependensi — pesanan bergantung pada pelanggan.
Ketika DROP TABLE Ditolak #
Menghapus tabel yang dirujuk tabel lain akan meruntuhkan integritas data, jadi server menolaknya lebih dulu. File berikut mencoba menghapus pelanggan selagi pesanan masih bergantung padanya:
DROP TABLE pelanggan;Output yang Dihasilkan:
psql:hapus-tabel-dipakai.sql:1: ERROR: cannot drop table pelanggan because other objects depend on it
DETAIL: constraint pesanan_pelanggan_id_fkey on table pesanan depends on table pelanggan
HINT: Use DROP ... CASCADE to drop the dependent objects too.Pesan error-nya jelas bertingkat: baris ERROR menyatakan penolakan utama, baris DETAIL menunjuk pelaku dependensinya (constraint pesanan_pelanggan_id_fkey di tabel pesanan), dan baris HINT menawarkan dua jalan keluar. Jalan pertama — dan yang paling sering benar — adalah menghapus dalam urutan yang tepat: tabel yang bergantung dulu, tabel yang dirujuk belakangan:
DROP TABLE pesanan;
DROP TABLE pelanggan;Dengan pesanan sudah tidak ada, tidak lagi ada yang bergantung pada pelanggan, dan penghapusannya berjalan mulus. Jalan kedua diberikan oleh HINT: CASCADE, yang kita coba berikutnya.
DROP TABLE … CASCADE #
Menambahkan CASCADE memerintahkan server menghapus objek dependen yang menghalangi — bukan tabelnya, melainkan dependensinya. Percobaan DROP TABLE pada bagian sebelumnya gagal tanpa menghapus apa pun, jadi kedua tabel masih utuh saat file berikut berjalan — dan kali ini pelanggan dihapus dengan CASCADE selagi pesanan masih ada:
DROP TABLE pelanggan CASCADE;
\d pesananOutput yang Dihasilkan:
DROP TABLE
Table "public.pesanan"
Column | Type | Collation | Nullable | Default
--------------+---------+-----------+----------+---------
id | integer | | not null |
pelanggan_id | integer | | |
Indexes:
"pesanan_pkey" PRIMARY KEY, btree (id)pesanan tetap hidup — barisnya, kolomnya, semuanya — tetapi foreign key-nya ikut terhapus: hasil \d pesanan di atas tidak lagi memuat bagian Foreign keys (bandingkan dengan struktur awalnya di file pertama). psql menampilkan pemberitahuan NOTICE: drop cascades to constraint pesanan_pelanggan_id_fkey on table pesanan di layar saat itu terjadi. Inilah arti penting CASCADE: server memilih melonggarkan struktur agar penghapusan bisa jalan — keputusan yang seharusnya kita ambil secara sadar, bukan sekadar menambahkan kata untuk “menghilangkan error”.
IF EXISTS: Kegagalan yang Ditenangkan #
Sekali tabel terhapus, namanya benar-benar lepas — mencoba menghapusnya lagi berakhir error. Ini merepotkan script pembersihan yang harus aman dijalankan berulang kali, entah tabelnya masih ada atau tidak:
DROP TABLE pelanggan;Output yang Dihasilkan:
psql:hapus-tak-ada.sql:1: ERROR: table "pelanggan" does not existTambahkan IF EXISTS dan perintah yang sama menjadi tenang: tabel yang tidak ada cukup dilewati dengan NOTICE, bukan error. File berikut membersihkan sisa chapter ini sekaligus memverifikasi hasilnya lewat information_schema:
DROP TABLE IF EXISTS pelanggan;
DROP TABLE IF EXISTS pesanan;
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;Output yang Dihasilkan:
DROP TABLE
DROP TABLE
table_name
------------
(0 rows)Dua perintah DROP TABLE IF EXISTS di file itu menghasilkan tag DROP TABLE — yang pertama hanya melewati tabel yang sudah tidak ada (dengan NOTICE: table "pelanggan" does not exist, skipping di layar), yang kedua sungguhan menghapus pesanan. Query penutup memastikan schema public sudah bersih dari tabel: hasilnya kosong. Pola IF NOT EXISTS yang kita kenal di chapter Membuat Tabel dan IF EXISTS di sini adalah pasangan serasi untuk script yang idempoten — aman dijalankan berkali-kali.
DROP DATABASE #
Menghapus database adalah operasi yang lebih besar: seluruh schema, tabel, dan data di dalamnya lenyap sekaligus. Syaratnya dua: kita harus terhubung ke database lain (tidak bisa menghapus database tempat kita sedang berdiri), dan tidak boleh ada pengguna lain yang masih terhubung ke database itu. File berikut memperagakan siklusnya penuh dari database maintenance postgres:
CREATE DATABASE toko_lama;
\connect toko_lama
CREATE TABLE stok (
id integer PRIMARY KEY,
nama text NOT NULL
);
\connect postgres
DROP DATABASE toko_lama;Output yang Dihasilkan:
CREATE DATABASE
You are now connected to database "toko_lama" as user "postgres".
CREATE TABLE
You are now connected to database "postgres" as user "postgres".
DROP DATABASEAlurnya empat babak: CREATE DATABASE toko_lama membuat databasenya; \connect toko_lama pindah ke dalamnya dan mengisi satu tabel; \connect postgres pindah keluar (langkah wajib — tanpa ini server menolak dengan error cannot drop the currently open database); lalu DROP DATABASE toko_lama menjatuhkan semuanya — tabel stok ikut lenyap tanpa perlu dihapus satu per satu.
Untuk database yang masih ada pengguna terhubung, PostgreSQL 13 ke atas menyediakan opsi DROP DATABASE nama WITH (FORCE): server memutus koneksi penghuni lain lebih dulu, lalu menghapus databasenya. Gunakan seperlunya — memutus koneksi aplikasi yang sedang bekerja adalah tindakan serius sendiri.
Sebagai penutup yang tegas: jangan pernah menjalankan DROP DATABASE postgres — database itu adalah pusat kendali maintenance server itu sendiri.
Siklus struktur kini lengkap: kita bisa membuat, memeriksa, mengubah, dan membersihkannya. Sebelum melangkah ke isi tabel, ada satu kebiasaan kecil yang membedakan proyek yang sehat dari yang cepat membusuk: mendokumentasikan struktur dan query dengan komentar — topik penutup section ini, Komentar dalam SQL.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
buat-tabel-berelasi.sql
Unduh berkasCREATE TABLE pelanggan (
id integer PRIMARY KEY,
nama text NOT NULL
);
CREATE TABLE pesanan (
id integer PRIMARY KEY,
pelanggan_id integer REFERENCES pelanggan (id)
);
INSERT INTO pelanggan (id, nama)
VALUES
(1, 'Budi'),
(2, 'Siti');
INSERT INTO pesanan (id, pelanggan_id)
VALUES
(101, 1),
(102, 2);
SELECT id, nama
FROM pelanggan
ORDER BY id;
SELECT id, pelanggan_id
FROM pesanan
ORDER BY id;
\d pesanan
hapus-cascade.sql
Unduh berkasDROP TABLE pelanggan CASCADE;
\d pesanan
hapus-database.sql
Unduh berkasCREATE DATABASE toko_lama;
\connect toko_lama
CREATE TABLE stok (
id integer PRIMARY KEY,
nama text NOT NULL
);
\connect postgres
DROP DATABASE toko_lama;
hapus-tabel-dipakai.sql
Unduh berkasDROP TABLE pelanggan;
hapus-tak-ada.sql
Unduh berkasDROP TABLE pelanggan;
if-exists.sql
Unduh berkasDROP TABLE IF EXISTS pelanggan;
DROP TABLE IF EXISTS pesanan;
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;