Soal 1Kamu menulis REFERENCES category(cat_id) pada sebuah kolom, namun baris yang menunjuk ke category yang tidak ada bisa masuk. Apa penyebab paling mungkin?
Batasan Foreign Key dan Aksi Referensial (ON DELETE / ON UPDATE)
Dengan setup parent/child category–item, pelajari REFERENCES untuk integritas referensial, mengapa PRAGMA foreign_keys=ON wajib untuk mengaktifkan pemeriksaan, dan bagaimana ON DELETE CASCADE / SET NULL / RESTRICT masing-masing memengaruhi child saat parent dihapus — semuanya langsung dipraktikkan.
Data yang akan kita pakai — category dan item
Batasan foreign key (batasan yang menjamin nilai kolom selalu ada sebagai primary key di tabel lain) adalah mekanisme yang melindungi integritas referensial antar tabel (keadaan di mana setiap baris yang dirujuk benar-benar ada).
Ia memblokir kontradiksi seperti "item menunjuk ke category yang tidak ada" atau "menghapus category meninggalkan itemnya menggantung", di lapisan database.
Pemeriksaan foreign-key diaktifkan dengan PRAGMA foreign_keys=ON
Batasan foreign key dideklarasikan dengan menulis REFERENCES tabel_parent(kolom_parent) di definisi kolom tabel child.
item.cat_id membawa REFERENCES category(cat_id), yang mengkodekan aturan: setiap nilai item.cat_id harus ada di category.
Namun, di konsol kursus ini pemeriksaan foreign-key secara default off (PRAGMA foreign_keys bernilai 0).
Selama off, `REFERENCES` sebetulnya tidak ditegakkan dan baris yang menunjuk ke category yang tidak ada bisa di-insert.
Untuk benar-benar menegakkan batasannya, jalankan PRAGMA foreign_keys=ON; sekali per koneksi.
-- Aktifkan pemeriksaan foreign-key
PRAGMA foreign_keys=ON;
-- Konfirmasi keadaan (1 berarti aktif)
PRAGMA foreign_keys;
-- Coba insert baris yang menunjuk ke cat_id=99 (tidak ada di category)
-- Dengan foreign_keys=ON, ini ditolak dengan FOREIGN KEY constraint failed
INSERT INTO item VALUES (5,'Mouse',99);
ON DELETE — apa yang harus dilakukan terhadap baris child ketika baris parent dihapus
Ketika baris parent (category) dihapus, apa yang harus terjadi pada baris child (item) yang menunjuk ke sana? Kamu memutuskannya dengan menulis aksi referensial di klausa REFERENCES.
Ada tiga aksi referensial yang umum.
ON DELETE CASCADE berarti menghapus parent juga menghapus child (cascade delete), ON DELETE SET NULL berarti kolom referensi child diset menjadi NULL dan barisnya disimpan, dan ON DELETE RESTRICT berarti delete parent itu sendiri ditolak selama child masih merujuknya.
Kalau kamu tidak menentukan aksi, defaultnya juga mirip RESTRICT (parent yang dirujuk tidak bisa dihapus).
Perilaku mana yang sesuai bergantung pada kebutuhan bisnis.
| Aksi referensial | Ketika parent category dihapus | Apa yang terjadi pada child item |
|---|---|---|
| ON DELETE CASCADE | Dihapus | Child ikut terhapus secara cascade |
| ON DELETE SET NULL | Dihapus | Child tetap, cat_id menjadi NULL |
| ON DELETE RESTRICT | Tidak bisa dihapus — error | Delete parent ditolak selama child ada (tidak tersentuh) |
-- Contoh deklarasi dengan ON DELETE SET NULL
CREATE TABLE cat_demo(cat_id INTEGER PRIMARY KEY, cat_name TEXT NOT NULL);
CREATE TABLE item_demo(
item_id INTEGER PRIMARY KEY,
item_name TEXT NOT NULL,
cat_id INTEGER REFERENCES cat_demo(cat_id) ON DELETE SET NULL
);
INSERT INTO cat_demo VALUES (1,'Stationery'),(2,'Electronics');
INSERT INTO item_demo VALUES (1,'Pen',1),(2,'Phone',2),(3,'Cable',2);
-- Menghapus parent cat_id=2 mengubah cat_id Phone / Cable menjadi NULL
DELETE FROM cat_demo WHERE cat_id=2;
SELECT item_id, item_name, cat_id FROM item_demo ORDER BY item_id;
SET NULL dan RESTRICT — pilih antara menyimpan dan menolak
ON DELETE SET NULL menyimpan baris child ketika parent dihapus, hanya menggantikan kolom yang merujuk dengan NULL.
Pakai ketika kamu tidak ingin menghapus record child itu sendiri, seperti "simpan item sebagai 'tanpa kategori'."
Kalau kolom referensi child adalah NOT NULL, NULL tidak bisa ditulis, jadi kolom yang dipakai dengan SET NULL harus mengizinkan NULL.
ON DELETE RESTRICT menolak delete parent itu sendiri selama child masih merujuknya.
Pakai ketika kamu ingin fail safe (jangan sengaja menjatuhkan baris master yang masih dirujuk).
Begitu kamu menghapus atau menugaskan ulang semua child sehingga tidak ada referensi tersisa, parent bisa dihapus.
Di latihan berikutnya kamu akan menyiapkan SET NULL dan RESTRICT berdampingan dalam satu konsol untuk membandingkannya.
-- Contoh RESTRICT: parent dengan child tidak bisa dihapus
CREATE TABLE cat_r(cat_id INTEGER PRIMARY KEY, cat_name TEXT NOT NULL);
CREATE TABLE item_r(
item_id INTEGER PRIMARY KEY,
item_name TEXT NOT NULL,
cat_id INTEGER REFERENCES cat_r(cat_id) ON DELETE RESTRICT
);
INSERT INTO cat_r VALUES (1,'Stationery'),(2,'Electronics');
INSERT INTO item_r VALUES (1,'Pen',1);
-- cat_id=1 dirujuk oleh item_r, jadi delete ditolak
DELETE FROM cat_r WHERE cat_id=1;
-- cat_id=2 tidak punya referensi, jadi bisa dihapus
DELETE FROM cat_r WHERE cat_id=2;
SELECT * FROM cat_r ORDER BY cat_id;
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Aksi referensial mana yang menyebabkan baris child otomatis terhapus ketika baris parent-nya dihapus?
Soal 3Kondisi apa yang harus dipenuhi kolom referensi tabel child untuk memakai ON DELETE SET NULL?