Ringkasan :dalam tutorial ini, Anda akan mempelajari cara menggunakan batasan kunci asing SQLite untuk menegakkan hubungan antara tabel terkait.
Dukungan batasan kunci asing SQLite
SQLite telah mendukung batasan kunci asing sejak versi 3.6.19. Pustaka SQLite juga harus dikompilasi dengan baik SQLITE_OMIT_FOREIGN_KEY maupun SQLITE_OMIT_TRIGGER.
Untuk memeriksa apakah versi SQLite Anda saat ini mendukung batasan kunci asing atau tidak, gunakan perintah berikut.
PRAGMA foreign_keys;
Code language: SQL (Structured Query Language) (sql)
Perintah mengembalikan nilai integer:1:aktifkan, 0:dinonaktifkan. Jika perintah tidak mengembalikan apa pun, itu berarti versi SQLite Anda tidak mendukung batasan kunci asing.
Jika pustaka SQLite dikompilasi dengan dukungan batasan kunci asing, aplikasi dapat menggunakan PRAGMA foreign_keys
perintah untuk mengaktifkan atau menonaktifkan batasan kunci asing saat runtime.
Untuk menonaktifkan batasan kunci asing:
PRAGMA foreign_keys = OFF;
Code language: SQL (Structured Query Language) (sql)
Untuk mengaktifkan batasan kunci asing:
PRAGMA foreign_keys = ON;
Code language: SQL (Structured Query Language) (sql)
Pengantar batasan kunci asing SQLite
Mari kita mulai dengan dua tabel:suppliers
dan supplier_groups
:
CREATE TABLE suppliers (
supplier_id integer PRIMARY KEY,
supplier_name text NOT NULL,
group_id integer NOT NULL
);
CREATE TABLE supplier_groups (
group_id integer PRIMARY KEY,
group_name text NOT NULL
);
Code language: SQL (Structured Query Language) (sql)
Dengan asumsi bahwa setiap pemasok milik satu dan hanya satu kelompok pemasok. Dan setiap kelompok pemasok mungkin memiliki nol atau banyak pemasok. Hubungan antara supplier_groups
dan suppliers
tabel adalah satu-ke-banyak. Dengan kata lain, untuk setiap baris di suppliers
tabel, ada baris yang sesuai di supplier_groups
tabel.
Saat ini, tidak ada cara untuk mencegah Anda menambahkan baris ke suppliers
tabel tanpa baris yang sesuai di supplier_groups
tabel.
Selain itu, Anda dapat menghapus satu baris di supplier_groups
tabel tanpa menghapus atau memperbarui baris yang sesuai di suppliers
meja. Ini mungkin meninggalkan baris yatim piatu di suppliers
tabel.
Untuk menegakkan hubungan antar baris dalam suppliers
dan supplier_groups
tabel, Anda menggunakan batasan kunci asing .
Untuk menambahkan batasan kunci asing ke suppliers
tabel, Anda mengubah definisi CREATE TABLE
pernyataan di atas sebagai berikut:
DROP TABLE suppliers;
CREATE TABLE suppliers (
supplier_id INTEGER PRIMARY KEY,
supplier_name TEXT NOT NULL,
group_id INTEGER NOT NULL,
FOREIGN KEY (group_id)
REFERENCES supplier_groups (group_id)
);
Code language: SQL (Structured Query Language) (sql)
supplier_groups
tabel disebut tabel induk , yang merupakan tabel yang dirujuk oleh kunci asing. suppliers
tabel dikenal sebagai tabel anak , yang merupakan tabel tempat batasan kunci asing diterapkan.
group_id
kolom di supplier_groups
tabel disebut kunci induk , yang merupakan kolom atau kumpulan kolom di tabel induk yang dirujuk oleh batasan kunci asing. Biasanya, kunci induk adalah kunci utama dari tabel induk.
group_id
kolom di suppliers
tabel disebut kunci anak. Umumnya, kunci anak merujuk ke kunci utama tabel induk.
Contoh batasan kunci asing SQLite
Pertama, masukkan tiga baris ke dalam supplier_groups
tabel.
INSERT INTO supplier_groups (group_name)
VALUES
('Domestic'),
('Global'),
('One-Time');
Code language: SQL (Structured Query Language) (sql)
Kedua, masukkan pemasok baru ke dalam suppliers
tabel dengan grup pemasok yang ada di supplier_groups
tabel.
INSERT INTO suppliers (supplier_name, group_id)
VALUES ('HP', 2);
Code language: SQL (Structured Query Language) (sql)
Pernyataan ini berfungsi dengan baik.
Ketiga, coba masukkan pemasok baru ke dalam suppliers
tabel dengan grup pemasok yang tidak ada di supplier_groups
tabel.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Inc.', 4);
Code language: SQL (Structured Query Language) (sql)
SQLite memeriksa batasan kunci asing, menolak perubahan, dan mengeluarkan pesan kesalahan berikut:
[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
Code language: CSS (css)
Tindakan batasan kunci asing SQLite
Apa yang akan terjadi jika Anda menghapus baris di supplier_groups
meja? Haruskah semua baris yang sesuai di suppliers
tabel juga dihapus? Pertanyaan yang sama untuk operasi pembaruan.
Untuk menentukan bagaimana batasan kunci asing berperilaku setiap kali kunci induk dihapus atau diperbarui, Anda menggunakan ON DELETE
atau ON UPDATE
tindakan sebagai berikut:
FOREIGN KEY (foreign_key_columns)
REFERENCES parent_table(parent_key_columns)
ON UPDATE action
ON DELETE action;
Code language: SQL (Structured Query Language) (sql)
SQLite mendukung tindakan berikut:
- SETEL NULL
- SETEL DEFAULT
- BATAS
- TIDAK ADA TINDAKAN
- CASCADE
Dalam prakteknya, nilai dari kunci utama pada tabel induk tidak berubah oleh karena itu aturan pembaruan menjadi kurang penting. Aturan yang lebih penting adalah DELETE
aturan yang menentukan tindakan saat kunci induk dihapus.
Kami akan memeriksa setiap tindakan dengan contoh berikut
SETEL NULL
Saat kunci induk mengubah, menghapus, atau memperbarui, kunci turunan yang sesuai dari semua baris di tabel turunan disetel ke NULL.
Pertama, jatuhkan dan buat tabel suppliers
menggunakan SET NULL
tindakan untuk group_id
kunci asing:
DROP TABLE suppliers;
CREATE TABLE suppliers (
supplier_id INTEGER PRIMARY KEY,
supplier_name TEXT NOT NULL,
group_id INTEGER,
FOREIGN KEY (group_id)
REFERENCES supplier_groups (group_id)
ON UPDATE SET NULL
ON DELETE SET NULL
);
Code language: SQL (Structured Query Language) (sql)
Kedua, masukkan beberapa baris ke dalam suppliers
tabel:
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 3);
INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 3);
Code language: SQL (Structured Query Language) (sql)
Ketiga, hapus id grup pemasok 3 dari supplier_groups
tabel:
DELETE FROM supplier_groups
WHERE group_id = 3;
Code language: SQL (Structured Query Language) (sql)
Keempat, kueri data dari suppliers
tabel.
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Nilai group_id
kolom dari baris yang sesuai di suppliers
tabel disetel ke NULL.
SETEL DEFAULT
SET DEFAULT
action menyetel nilai kunci asing ke nilai default yang ditentukan dalam definisi kolom saat Anda membuat tabel.
Karena nilai pada kolom group_id
default ke NULL, jika Anda menghapus baris dari supplier_groups
tabel, nilai group_id
akan disetel ke NULL.
Setelah menetapkan nilai default, batasan kunci asing masuk dan membawa cek.
BATAS
RESTRICT
tindakan tidak mengizinkan Anda mengubah atau menghapus nilai di kunci induk tabel induk.
Pertama, jatuhkan dan buat suppliers
tabel dengan RESTRICT
tindakan dalam kunci asing group_id
:
DROP TABLE suppliers;
CREATE TABLE suppliers (
supplier_id INTEGER PRIMARY KEY,
supplier_name TEXT NOT NULL,
group_id INTEGER,
FOREIGN KEY (group_id)
REFERENCES supplier_groups (group_id)
ON UPDATE RESTRICT
ON DELETE RESTRICT
);
Code language: SQL (Structured Query Language) (sql)
Kedua, masukkan baris ke dalam tabel suppliers
dengan group_id 1.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);
Code language: SQL (Structured Query Language) (sql)
Ketiga, hapus grup pemasok dengan id 1 dari supplier_groups
tabel:
DELETE FROM supplier_groups
WHERE group_id = 1;
Code language: SQL (Structured Query Language) (sql)
SQLite mengeluarkan kesalahan berikut:
[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
Code language: CSS (css)
Untuk memperbaikinya, Anda harus terlebih dahulu menghapus semua baris dari suppliers
tabel yang memiliki group_id
1:
DELETE FROM suppliers
WHERE group_id =1;
Code language: SQL (Structured Query Language) (sql)
Kemudian, Anda dapat menghapus grup pemasok 1 dari supplier_groups
tabel:
DELETE FROM supplier_groups
WHERE group_id = 1;
Code language: SQL (Structured Query Language) (sql)
TIDAK ADA TINDAKAN
NO ACTION
tidak berarti melewati batasan kunci asing. Ini memiliki efek yang mirip dengan RESTRICT
.
CASCADE
CASCADE
action menyebarkan perubahan dari tabel induk ke tabel anak saat Anda memperbarui atau menghapus kunci induk.
Pertama, masukkan suppliers
mengelompokkan ke dalam supplier_groups
tabel:
INSERT INTO supplier_groups (group_name)
VALUES
('Domestic'),
('Global'),
('One-Time');
Code language: SQL (Structured Query Language) (sql)
Kedua, jatuhkan dan buat tabel suppliers
dengan CASCADE
tindakan dalam kunci asing group_id
:
DROP TABLE suppliers;
CREATE TABLE suppliers (
supplier_id INTEGER PRIMARY KEY,
supplier_name TEXT NOT NULL,
group_id INTEGER,
FOREIGN KEY (group_id)
REFERENCES supplier_groups (group_id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
Code language: SQL (Structured Query Language) (sql)
Ketiga, masukkan beberapa supplier ke dalam tabel suppliers
:
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);
INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 2);
Code language: SQL (Structured Query Language) (sql)
Keempat, perbarui group_id
dari Domestic
grup pemasok ke 100:
UPDATE supplier_groups
SET group_id = 100
WHERE group_name = 'Domestic';
Code language: SQL (Structured Query Language) (sql)
Kelima, query data dari tabel suppliers
:
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Seperti yang Anda lihat nilainya di group_id
kolom XYZ Corp
dalam tabel suppliers
berubah dari 1 menjadi 100 saat kami memperbarui group_id
di supplier_groups
meja. Ini adalah hasil dari ON UPDATE CASCADE
tindakan.
Keenam, hapus id grup pemasok 2 dari supplier_groups
tabel:
DELETE FROM supplier_groups
WHERE group_id = 2;
Code language: SQL (Structured Query Language) (sql)
Ketujuh, query data dari tabel suppliers
:
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Id pemasok 2 yang group_id
is 2 telah dihapus ketika id grup pemasok 2 telah dihapus dari supplier_groups
meja. Ini adalah efek dari ON DELETE CASCADE
tindakan.
Dalam tutorial ini, Anda telah mempelajari tentang batasan kunci asing SQLite dan cara menggunakannya untuk menegakkan hubungan antara tabel terkait.