Foreign key komposit dan self-referencing
Kunci komposit terdiri dari dua atau lebih kolom yang secara unik mengidentifikasi sebuah record dan harus dirujuk bersama. Pola ini digunakan saat kunci alami mencakup beberapa kolom, atau jika Anda ingin mencegah hubungan duplikat. Misalnya, Anda mungkin memiliki penawaran mata kuliah yang diidentifikasi oleh (course_id, semester) atau sebuah junction table dengan student_id dan course_id sebagai primary key komposit.
-- Defines courses table
CREATE TABLE course_offerings (
course_id INT,
semester VARCHAR(10),
-- Composite primary key ensures a course can only be offered once per semester
PRIMARY KEY (course_id, semester)
);
-- Create enrollment table
CREATE TABLE enrollment (
student_id INT,
course_id INT,
semester VARCHAR(10),
-- This foreign key links enrollment records to a valid course offering
FOREIGN KEY (course_id, semester)
REFERENCES course_offerings(course_id, semester)
);
Foreign key yang mereferensikan dirinya sendiri (self-referencing) atau rekursif adalah foreign key yang merujuk ke primary key dalam tabel yang sama. Pola ini umum pada data hierarkis seperti Karyawan → Manajer. Ini memungkinkan cara merepresentasikan hubungan rekursif tanpa membuat tabel tambahan.
Pada kueri di bawah, manager_id merujuk ke employee_id dalam tabel yang sama.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100),
-- manager_id references employee_id in the same table
manager_id INT,
FOREIGN KEY (manager_id) REFERENCES employees(employee_id)
);
Bekerja dengan Data dan Menjaga Integritas
Kini kita tahu bahwa foreign key digunakan untuk memastikan integritas data dalam basis data. Pada bagian ini, kita akan melihat pertimbangan praktis saat bekerja dengan foreign key untuk operasi SQL, tantangan umum, dan cara mengelola constraint.
Operasi INSERT, UPDATE, dan DELETE
Mari lihat bagaimana operasi-operasi ini berinteraksi dengan foreign key.
Operasi insert dengan foreign key
Untuk menyisipkan record anak, nilai induk yang dirujuk harus ada. Jika tidak, operasi insert akan gagal. Misalnya, kueri di bawah akan menyisipkan record ke tabel orders jika tabel users berisi record dengan user_id bernilai 1.
-- users table contains user_id = 1
INSERT INTO orders (order_id, user_id, order_date)
VALUES (100, 1, '2024-02-01');
Jika Anda mencoba menyisipkan record untuk pengguna yang tidak ada di tabel induk, Anda akan mendapatkan error yang menunjukkan pelanggaran constraint foreign key.
-- user_id = 999 does NOT exist in users table
INSERT INTO orders (order_id, user_id, order_date)
VALUES (101, 999, '2024-02-01');
ERROR: insert or update on table "orders" violates foreign key constraint "fk_orders_users"
Operasi update dan perilaku cascading
Update dapat memengaruhi foreign key atau tabel primary key. Misalnya, jika Anda memperbarui foreign key di tabel orders, itu hanya akan berhasil jika primary key ada di tabel induk. Sebagai contoh, update di bawah hanya akan berhasil jika users.user_id = 5 exists.
-- updating foreign key value
UPDATE orders
SET user_id = 5
WHERE order_id = 100;
Dari contoh di atas, Anda tidak dapat memperbarui primary key tanpa ON UPDATE CASCADE karena baris anak masih mereferensikan 1. Untuk menghindarinya, pertama kita hapus constraint foreign key yang ada, lalu buat ulang dengan ON UPDATE CASCADE aktif. Dengan metode ini, nilai terkait orders.user_id diperbarui secara otomatis.
-- Drop existing foreign key constraint
ALTER TABLE orders
DROP CONSTRAINT fk_orders_users;
-- Recreate FK with ON UPDATE CASCADE enabled
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON UPDATE CASCADE; -- Automatically update child rows when parent key changes
UPDATE users
SET user_id = 500
WHERE user_id = 1;
Operasi delete dan cascade
Jika Anda mencoba menghapus baris induk tanpa aturan cascade, penghapusan akan gagal dan Anda akan mendapat error. Saat Anda menambahkan klausa ON DELETE CASCADE, ini memberi tahu basis data untuk secara otomatis menghapus baris anak terkait ketika record induk dihapus, agar semuanya tetap konsisten.
Pada contoh di bawah, kita membuat foreign key pada orders.user_id yang merujuk ke users.user_id. Dengan ON DELETE CASCADE, jika seorang pengguna dihapus dari tabel users, semua pesanan terkait akan dihapus secara otomatis.
-- Add a new foreign key constraint to the orders table
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE CASCADE; -- Delete orders automatically when user is deleted
Terkadang Anda mungkin ingin basis data menangani penghapusan secara otomatis. Anda dapat menegakkannya dengan ON DELETE SET NULL saat membuat tabel. Ini akan menetapkan kolom foreign key di tabel anak menjadi NULL jika record induk berubah atau dihapus.
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT, -- FK referencing users.user_id
order_date DATE,
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE SET NULL -- If a user is deleted, set user_id in orders to NULL
);
Menangani tantangan umum
Saat Anda merancang basis data yang kompleks, Anda kemungkinan akan menemui tantangan dengan foreign key. Berikut masalah umum yang saya alami dengan foreign key dan solusi praktisnya masing-masing.
-
Jenis data tidak cocok: Jika kolom foreign key dan kolom primary key yang dirujuk memiliki tipe data yang tidak kompatibel, constraint tidak dapat dibuat. Untuk menghindarinya, selalu standarkan tipe di seluruh tabel terkait.
-
Ketergantungan sirkular: Terjadi ketika dua tabel saling merujuk, yang berpotensi menyebabkan deadlock saat insert. Untuk mengatasinya, Anda harus mengevaluasi ulang desain skema atau buat tabel tanpa foreign key terlebih dahulu, muat data dasar, lalu gunakan
ALTER TABLEuntuk menambahkan constraint. -
Foreign key menggantung: Masalah ini terjadi ketika foreign key pada anak menunjuk ke tabel induk yang tidak ada. Untuk memperbaikinya, gunakan aksi cascading untuk memvalidasi data selama operasi delete dan update.
Mengelola modifikasi dan menghapus constraint
Terkadang Anda mungkin ingin memodifikasi constraint foreign key saat mendesain ulang skema basis data. Berikut cara menghapus foreign key dengan sedikit variasi sintaks antar dialek SQL.
Di PostgreSQL, SQL Server, dan Oracle, kita menggunakan pernyataan DROP CONSTRAINT.
-- Drop foreign key
ALTER TABLE orders
DROP CONSTRAINT fk_orders_users;
Namun, di MySQL, kita menggunakan pernyataan DROP FOREIGN KEY untuk menghapus foreign key.
-- Drop foreign key
ALTER TABLE orders
DROP FOREIGN KEY fk_orders_users;
Perlu dicatat bahwa menghapus constraint foreign key menghapus penegakan integritas referensial oleh basis data. Setelah dihapus, Anda dapat melakukan insert atau update data yang melanggar hubungan, yang dapat menyebabkan data tidak konsisten.
Kinerja dan Optimasi
Dari contoh di atas, kita telah melihat bagaimana foreign key memastikan desain data yang efektif dengan menjaga integritas data. Namun, Anda perlu memahami cara mengoptimalkan foreign key untuk meningkatkan kinerja basis data Anda. Berikut beberapa kiat yang saya anggap membantu saat bekerja dengan foreign key:
Pengindeksan dan kinerja kueri
Saat Anda mengindeks foreign key, basis data dapat dengan cepat memvalidasi perubahan selama operasi insert, update, atau delete dengan menemukan kunci yang sesuai di tabel induk. Demikian pula, indeks mempercepat operasi join yang menautkan tabel anak dan induk dengan memungkinkan mesin basis data mencocokkan baris berdasarkan nilai foreign key.
Sebagai praktik terbaik, saya sarankan Anda secara eksplisit mengindeks kolom foreign key jika DBMS tidak menanganinya secara otomatis.
Teknik optimasi kueri
Beberapa mesin SQL menggunakan keberadaan foreign key untuk menerapkan join elimination, teknik yang mengidentifikasi dan menghapus join yang tidak diperlukan dari rencana eksekusi kueri. Misalnya, jika sebuah kueri hanya mengakses kolom dari tabel anak namun menyertakan join pada tabel induk untuk penyaringan yang sudah dijamin oleh constraint foreign key, operasi join dapat dioptimalkan untuk dihilangkan.
Anda selalu dapat melihat rencana eksekusi untuk mengetahui bagaimana pengoptimal kueri menangani foreign key dan join. Optimasi dan efisiensinya bervariasi di berbagai mesin SQL, seperti PostgreSQL, MySQL, dan SQL Server. Memahami perilaku pengoptimal basis data spesifik Anda membantu dalam menulis kueri yang berkinerja tinggi dan memanfaatkan constraint foreign key secara maksimal.
Sebagai contoh, Anda dapat menggunakan kueri berikut untuk melihat rencana eksekusi di PostgreSQL:
-- View execution plan
EXPLAIN ANALYZE
SELECT o.order_id, u.email
FROM orders o
JOIN users u ON o.user_id = u.user_id;
Tabel ini merangkum cara melihat rencana eksekusi di berbagai basis data:
|
Basis data |
Perintah |
|
PostgreSQL |
|
|
MySQL |
|
|
SQL Server |
Estimated / Actual Execution Plan |
|
Oracle |
|
Saya merekomendasikan mengikuti Joining Data in SQL untuk mempelajari berbagai jenis join di SQL dan cara bekerja dengan berbagai tabel terkait dalam basis data.
Kasus Penggunaan Lanjutan dan Praktik Terbaik
Di luar implementasi dasar, Anda dapat menggunakan foreign key untuk membangun arsitektur basis data yang tangguh, skalabel, dan mudah dirawat. Pada bagian ini, saya akan menjelaskan skenario khusus dan prinsip desain tingkat tinggi yang perlu dipertimbangkan saat menggunakan foreign key.
Hubungan lintas basis data atau lintas skema
Meskipun foreign key dirancang untuk menegakkan integritas dalam satu basis data atau skema, lingkungan perusahaan yang lebih kompleks sering kali memerlukan hubungan melintasi batas-batas tersebut. Tabel di bawah merangkum dukungan lintas skema dan dukungan lintas basis data untuk berbagai dialek SQL.
|
Basis data |
Dukungan Lintas Skema |
Dukungan Lintas Basis Data |
Keterbatasan |
|
PostgreSQL |
Ya |
Tidak |
Terbatas pada satu klaster basis data. |
|
SQL Server |
Ya |
Ya |
Integritas lintas basis data dikelola oleh logika aplikasi atau trigger, bukan FK native. |
|
Oracle |
Ya |
Ya |
Database link untuk akses data; constraint FK native umumnya tidak ditegakkan lintas link. |
|
MySQL |
Tidak |
Tidak |
Sangat terbatas pada tabel dalam basis data dan mesin penyimpanan yang sama, seperti InnoDB. |
|
SQLite |
Tidak |
Tidak |
Terbatas pada file/koneksi basis data tertentu. |
Pemeliharaan dan audit
Saat Anda membangun foreign key, Anda akan melihat bahwa foreign key berubah setiap kali logika bisnis Anda bergeser. Pertimbangkan cara berikut untuk mengaudit dan memelihara foreign key agar tetap mutakhir:
- Tinjau constraint: Secara berkala audit constraint foreign key untuk memastikan tetap selaras dengan aturan bisnis dan perubahan skema yang berkembang.
- Audit indeks rutin: Selalu verifikasi bahwa indeks ada pada semua kolom foreign key untuk menjaga kinerja join dan validasi yang optimal, terutama setelah impor data besar atau peningkatan sistem.
- Dokumentasi dan visualisasi: Gunakan diagram Entity-Relationship (ER) atau alat visualisasi skema untuk mendokumentasikan hubungan. Alat visual ini akan memastikan semua pengembang dan analis memahami hubungan serta aturan integritas yang ditegakkan oleh foreign key Anda.
Praktik terbaik untuk desain basis data yang tangguh
Agar Anda mendapatkan manfaat maksimal dari cara kerja foreign key, patuhi pedoman berikut:
-
Selaraskan kunci dengan logika bisnis nyata: Pastikan primary key dan foreign key benar-benar merepresentasikan entitas nyata dan hubungan di antaranya, bukan mengandalkan pengenal yang artifisial atau tidak stabil.
-
Gunakan nama yang jelas dan konsisten: Pilih nama constraint yang deskriptif, seperti
fk_orders_user_idsehingga skema Anda lebih mudah dirawat, di-debug, dan dikerjakan bersama orang lain. -
Seimbangkan ketegasan dan fleksibilitas: Constraint harus melindungi kualitas data, tetapi desain Anda tetap harus memungkinkan kasus tepi yang praktis atau validasi yang ditangani di lapisan aplikasi.
-
Hindari hubungan sirkular: Strukturkan skema Anda sehingga ketergantungan foreign key tidak berputar kembali satu sama lain, karena ini membuat insert, update, dan delete menjadi terlalu kompleks.
-
Optimalkan kinerja: Indeks foreign key Anda dengan tepat, dan terapkan aksi cascading secara cermat agar integritas terjaga tanpa memperlambat sistem Anda.
Kesimpulan
Seperti halnya keterampilan lain, menguasai foreign key datang melalui praktik. Saya mendorong Anda untuk bereksperimen dengan pemodelan skema, menguji aksi cascading, dan memahami bagaimana constraint berperilaku dalam skenario dunia nyata. Seiring waktu, Anda akan belajar menyeimbangkan aturan yang ketat dengan fleksibilitas yang dibutuhkan aplikasi Anda, menciptakan basis data yang tangguh sekaligus adaptif seiring berkembangnya kebutuhan.
Sekarang setelah Anda memahami cara menggunakan foreign key dalam desain basis data, saya sarankan mencoba jalur karier Associate Data Engineer in SQL untuk mempelajari dasar-dasar rekayasa data dan gudang data. Terakhir, jika Anda ingin meningkatkan keterampilan manajemen basis data untuk big data, saya sarankan mengikuti kursus Introduction to Data Modeling in Snowflake untuk mempelajari lebih lanjut tentang pemodelan dimensional.

FAQ
Apa perbedaan antara primary key dan foreign key?
Primary key mengidentifikasi record secara unik dalam tabelnya sendiri, sedangkan foreign key merujuk ke primary key di tabel lain untuk membentuk hubungan.
Bisakah sebuah tabel memiliki beberapa foreign key?
Ya, sebuah tabel dapat memiliki beberapa foreign key, masing-masing menautkan ke tabel induk yang berbeda.
Haruskah kolom foreign key unik dalam sebuah tabel?
Tidak, kolom foreign key boleh berisi nilai duplikat tetapi harus merujuk ke baris yang valid di tabel induk.
Apa yang terjadi jika Anda menghapus record yang dirujuk oleh foreign key?
Bergantung pada constraint, basis data dapat membatasi penghapusan, melakukan cascade untuk menghapus baris terkait, atau menyetel nilai foreign key menjadi NULL.
Apakah foreign key wajib dalam basis data relasional?
Meskipun tidak wajib, foreign key sangat penting untuk menegakkan integritas relasional dan desain basis data yang andal.

Dalam basis data relasional, data biasanya tersebar di beberapa tabel, masing-masing menyimpan aspek tertentu dari sebuah sistem yang lebih besar. Pemisahan ini adalah pilihan desain yang baik, tetapi memang menimbulkan tantangan karena data dapat dengan cepat menjadi sulit ditafsirkan.
Untuk mengatasi tantangan ini, basis data relasional mengandalkan aturan yang menegakkan hubungan antar tabel. Salah satu mekanisme terpenting untuk mempertahankan struktur dan keandalan ini adalah penggunaan kunci asing (foreign key), yang digunakan untuk memastikan data terkait tetap selaras.
Dalam tutorial ini, saya akan menjelaskan cara kerja kunci asing. Jika Anda baru memulai sebagai insinyur basis data, saya sarankan mengikuti kursus Introduction to Relational Databases in SQL dan Database Design untuk mempelajari cara membuat hubungan saat mendefinisikan skema basis data Anda.
Primary Key vs. Foreign Key
Baik primary key, yang sudah kami bahas di artikel lain, maupun foreign key membantu menjaga struktur dan integritas basis data relasional. Berikut penjelasannya:
Apa itu foreign key?
Foreign key adalah sebuah kolom atau sekumpulan kolom dalam satu tabel yang merujuk ke primary key di tabel lain. Foreign key ini membuat tautan antar tabel untuk memastikan data di tabel referencing cocok dengan entri yang valid di tabel referenced.
Misalkan Anda memiliki basis data dengan tabel
usersdan tabelorders. Tabelordersmungkin menyertakan kolomuser_id, yang harus cocok denganuser_idyang ada di tabelusers. Batasan foreign key memastikan Anda tidak dapat membuat pesanan yang terikat ke pengguna yang tidak ada.Memahami foreign key juga memerlukan pemahaman tentang primary key, karena foreign key bergantung pada primary key untuk membentuk dan mempertahankan hubungan ini.
Apa itu primary key?
Primary key adalah sebuah kolom atau kombinasi kolom yang mengidentifikasi setiap record dalam tabel secara unik. Tidak ada dua baris yang boleh berbagi nilai primary key yang sama, dan nilainya tidak boleh
NULL. Karena itu, sebuah tabel harus memiliki satu primary key yang menjadi pengenal unik yang dirujuk oleh semua foreign key di tabel lain.Sebagai contoh, kueri di bawah ini membuat tabel
users, dengan kolomuser_idsebagai primary key:Perbedaan utama antara primary key dan foreign key
Saya telah merangkum perbedaan antara primary key dan foreign key pada tabel di bawah:
Aspek
Primary Key
Foreign Key
Tujuan
Mengidentifikasi setiap record dalam sebuah tabel secara unik
Membuat hubungan dengan merujuk primary key di tabel lain
Keunikan
Harus unik
Dapat berisi nilai duplikat
Nilai NULL
Tidak boleh NULL
Boleh NULL (kecuali dibatasi)
Lokasi
Didefinisikan dalam tabel yang sama
Merujuk primary key tabel lain
Dari penjelasan di atas, kita melihat bahwa primary key dan foreign key penting untuk membuat basis data yang terstruktur dan andal. Keduanya bekerja sama untuk memastikan data konsisten, hubungan terjaga, dan integritas basis data dipelihara.
Membangun dan Mengelola Foreign Key di SQL
Sekarang setelah Anda memahami apa itu foreign key dan mengapa penting dalam basis data, mari pelajari cara mendefinisikan, mengelola, dan mengendalikan perilakunya saat merancang basis data Anda.
Mendefinisikan foreign key dengan SQL
Anda dapat menyiapkan foreign key di SQL dengan dua cara; saat membuat tabel atau menambahkannya setelahnya jika tabel sudah ada.
Contoh di bawah menunjukkan opsi pertama tentang cara mendefinisikan foreign key saat membuat tabel di SQL Server.
Sintaksnya sama untuk PostgreSQL, meskipun kita menggunakan
SERIALuntuk auto-increment pada primary key.Saat menyiapkan foreign key di MySQL, Anda harus menggunakan
InnoDBseperti ditunjukkan di bawah ini.Jika Anda menggunakan basis data Oracle, Anda dapat mendefinisikan foreign key, namun pastikan tipe data persis sama untuk kedua tabel.
Untuk menambahkan foreign key ke tabel yang sudah ada, gunakan kueri berikut:
Saya sarankan mengikuti kursus Introduction to SQL Server dan Creating PostgreSQL Databases untuk mempelajari lebih lanjut perbedaan dialek SQL saat membuat basis data.
Mengelola constraints dan konvensi penamaan
Foreign key adalah jenis constraint, yaitu aturan yang ditegakkan oleh sistem manajemen basis data (DBMS) untuk memvalidasi data selama operasi seperti insert, update, dan delete. Saat constraint foreign key aktif, basis data memastikan bahwa setiap nilai yang dimasukkan di kolom foreign key sudah ada di kolom primary key yang dirujuk.
Praktik umum adalah menamai constraint dengan pola
fk_<child>_<parent>. Dari contoh kita, foreign key menjadifk_orders_users. Jika Anda menamai foreign key seperti ini, skema menjadi mudah dibaca, membantu saat debug pelanggaran constraint, dan bekerja baik dengan alat migrasi. Validasi constraint berlaku jika Anda melakukan operasi berikut:INSERT: Menolak baris jika nilai induk yang dirujuk tidak adaUPDATE: Mencegah modifikasi yang akan merusak hubungan.DELETE: Memblokir operasi hapus saat baris anak yang bergantung masih ada.Integritas referensial dan aksi cascading
Integritas referensial adalah prinsip inti yang ditegakkan oleh constraint foreign key. Foreign key membantu menegakkannya dengan mencegah record yatim piatu, yang terjadi ketika baris di tabel anak menunjuk ke baris yang tidak ada di tabel induk.
SQL juga memungkinkan Anda mengatur aksi cascading. Ini adalah instruksi otomatis yang memberi tahu sistem manajemen basis data (DBMS) bagaimana menangani perubahan yang dilakukan pada record yang dirujuk. Misalnya, Anda dapat menggunakan operasi cascading ini untuk melakukan hal-hal seperti:
Aksi
Perilaku
ON DELETE CASCADEMenghapus baris anak saat baris induk dihapus
ON UPDATE CASCADEMemperbarui kunci anak saat kunci induk berubah
SET NULLForeign key pada anak menjadi
NULLSET DEFAULTAnak menerima nilai default
NO ACTION/RESTRICTMencegah perubahan yang merusak hubungan
Sebagai contoh, kueri berikut menambahkan operasi cascading untuk menghapus record pengguna jika mereka menghapus pesanannya, dan memperbarui secara otomatis jika
user_idmereka berubah.Merancang Hubungan Antar Tabel
Foreign key adalah blok bangunan dalam pemodelan data yang mendefinisikan hubungan antar tabel dalam basis data. Pada bagian ini, kita akan melihat berbagai cara foreign key memastikan konsistensi data saat menautkan tabel.
Hubungan one-to-many dan many-to-many
Dalam hubungan one-to-many (1:N), satu baris di tabel induk dapat ditautkan ke banyak record di tabel anak. Hubungan ini ditegakkan dengan menempatkan primary key dari tabel induk, seperti
users.user_id, sebagai foreign key di tabel anak, sepertiorders.customer_id.Sebagai contoh, satu pengguna dapat memiliki banyak pesanan, atau satu departemen dapat memiliki banyak karyawan.
Contoh hubungan one-to-many. Gambar oleh Penulis.
Di sisi lain, hubungan many-to-many (M:N) terjadi ketika beberapa record di satu tabel dapat terkait dengan beberapa record di tabel lain. Karena Anda tidak dapat menerapkan hubungan many-to-many secara langsung dalam basis data ternormalisasi, kita menggunakan tabel perantara (junction/bridge table) yang berisi dua foreign key.
Contoh hubungan many-to-many. Gambar oleh Penulis.