Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

KONSTRAIN KUNCI ASING SQL:Panduan Utama dan Mudah untuk Pemula

Anak baru? Maka kunci asing SQL mungkin asing bagi Anda.

Anda mungkin pernah mendengar pendapat berbeda tentang kunci asing SQL. Jika belum, Anda akan segera melakukannya. Atau pengalaman Anda akan memengaruhi pandangan Anda. Hal utama yang perlu diketahui adalah, kunci asing adalah suatu keharusan dalam database relasional.

Namun, beberapa pengembang mungkin menghapus atau mengabaikan kunci asing saat menghadapi beberapa komplikasi. Jadi, apa yang harus dilakukan? Untuk menggunakan kunci asing atau tidak menggunakannya? Akankah ada saatnya Anda tidak perlu menggunakannya?

Panduan ini bagi Anda untuk melihat betapa pentingnya hal ini. Anda juga akan mengetahui beberapa kode gotcha dan mempelajari cara memperbaikinya. Selain itu, tentu saja, kami akan menggunakan contoh praktis. Tidak ada yang tidak bisa Anda tangani.

Apa itu Kunci Asing SQL?

Hal pertama yang pertama. Apa itu kunci asing dalam SQL? Singkatnya, ini adalah kunci yang menghubungkan 2 tabel. Katakanlah Anda memiliki tabel induk dan tabel anak. Ada beberapa kesamaan yang menjadikannya orang tua dan anak – kunci yang menghubungkan 2 tabel ini.

Namun, dalam database SQL, kunci asing tidak hanya berhubungan dengan tabel. Ini memaksakan hubungan. Itulah mengapa ini disebut batasan kunci asing.

Kesalahan akan terjadi jika Anda mencoba menambahkan catatan anak dengan nilai kunci asing yang tidak ada di kunci utama tabel induk. Nanti, kita akan melihat contoh kode yang menggambarkan hal ini.

Tabel Manakah yang Harus Memiliki Batasan Kunci Asing SQL?

Tabel anak dapat memiliki kunci asing. Satu kunci asing mungkin mereferensikan tabel lain. Juga, mungkin ada beberapa kunci asing di tabel "anak". Di SQL Server, kunci asing dapat mereferensikan kunci utama atau kunci unik di tabel lain.

Bagaimana Dengan Referensi Mandiri?

Ini keluar dari definisi umum kunci asing. Sebuah referensi diri berarti Anda dapat menetapkan kunci asing yang direferensikan kolom yang berbeda dalam tabel yang sama . SQL Server, MySQL, dan Oracle mendukung ini.

Referensi diri berlaku ketika Anda ingin membuat hierarki seperti hubungan manajer-staf. Itu diperbolehkan, namun, sebagian besar implementasi kunci asing berada di antara 2 tabel.

Nanti kita punya contohnya.

4 Manfaat Menggunakan Kunci Asing SQL

Mari kita jelajahi kunci utama dan kunci asing di SQL secara detail. Apa yang membuat kunci asing harus dimiliki oleh database SQL? Mari kita periksa 4 poin (di sini, sintaks batasan tidak masalah).

1. Hindari Data yang “Hilang”

Data "hilang" adalah nilai kunci asing dari tabel anak tanpa nilai kunci utama terkait dari tabel induk. Mereka juga disebut sebagai baris yatim piatu. Ketika itu terjadi, kita dapat mengatakan bahwa database memiliki sedikit atau tidak ada integritas referensial.

Dengan diberlakukannya batasan kunci asing, data "hilang" tidak akan terjadi sama sekali. Mesin database tidak akan mengizinkan penghapusan nilai kunci utama yang direferensikan oleh tabel lain. Demikian pula, memasukkan kunci asing di tabel anak yang tidak ada di kunci utama tabel induk akan memicu kesalahan.

Apa hal terburuk yang bisa terjadi jika Anda tidak menggunakan batasan kunci asing? Berikut adalah beberapa:

  • Pelanggan tidak akan menerima produk yang mereka bayar.
  • Pengobatan tidak diberikan kepada pasien.
  • Daftar periksa yang tidak ada, lewati tindakan pencegahan keselamatan.

Anda dapat menangani hal ini di luar database, tetapi Anda harus mengkodekannya. Lebih lanjut tentang ini akan mengikuti.

Katakanlah pengembang di organisasi Anda menangani kendala yang sama di luar database. Apakah dia akan bertanggung jawab dan memperbaiki masalah dalam produksi jika kode gagal? Saya kira tidak demikian. Dan bagaimana jika Anda adalah admin database? Kemudian, Anda harus membersihkan kekacauan mereka. Tidak terlalu menggembirakan jika Anda bertanya kepada saya.

2. Hindari Laporan yang Tidak Konsisten

Ini berkaitan dengan poin pertama. Jika beberapa data “hilang”, total yang tidak konsisten akan muncul di laporan yang berbeda. Detail tidak cocok dengan ringkasan. Baris yatim menambah total ringkasan. Sementara itu, laporan mendetail tidak menangkap baris yatim karena penggabungan dalam ke tabel induk.

Jika tugas Anda adalah menjaga database Anda dalam kondisi baik, Anda juga akan membersihkan kekacauan ini.

3. Tidak Perlu Kode untuk Menghindari Baris Yatim

Batasan kunci asing bertindak seperti agen pembersih diri. Alih-alih Anda membersihkan kekacauan, database melakukannya dengan tidak mengizinkan baris yatim piatu. Kendala kunci asing juga bertindak sebagai polisi. Mereka menangkap logika yang salah yang menyebabkan baris yatim piatu, memperlakukannya seperti kejahatan yang dilakukan di luar database.

Apakah Anda ingin database mengkilap bebas dari baris yatim piatu? Tentu saja. Jika Anda ingin menganalisis data suatu hari nanti, Anda akan senang telah menggunakan kunci asing. Basis data ini akan menjadi sumber yang baik untuk menyalin data yang diperlukan ke staging area Anda.

4. Memahami Hubungan Tabel dengan Cepat dalam Diagram

SQL Server Management Studio memiliki alat diagram bawaan untuk database Anda. Kunci utama dan kunci asing membuat diagram database informatif sekilas. Namun, itu akan tergantung pada berapa banyak tabel dengan hubungan yang telah Anda sertakan dalam diagram.

Diagram membantu anggota tim baru memahami struktur data. Untuk rekan tim senior, ini bisa berguna juga sebagai dokumentasi.

Ketika Kunci Asing SQL Dapat Menjadi "Masalah" (ditambah Perbaikannya)

Untuk memigrasikan data lama ke database baru, Anda akan memasukkan catatan secara massal. Jika database sumber memiliki integritas referensial yang rendah, akan sulit untuk memasukkan catatan dari sumbernya. Alasannya adalah kesalahan kunci asing muncul di sana-sini.

Apakah ada perbaikan? Anda memiliki 2 opsi.

  1. Pastikan untuk mengisi tabel referensi atau tabel induk terlebih dahulu. Setelah itu, isi tabel anak. Salah satu komplikasi berjalan sangat lambat. Dalam kasus lain, lebih banyak kesalahan batasan kunci asing terjadi. Jika kasus terakhir terjadi, Anda perlu mengevaluasi kembali urutan penyisipan dan memastikan kunci utama dimasukkan terlebih dahulu. Jika ada masalah "berjalan lambat", pertimbangkan opsi berikutnya.
  2. Nonaktifkan kunci asing untuk sementara dan aktifkan setelah migrasi selesai (dan dibersihkan). Anda dapat melakukannya di SQL Server Management Studio atau menggunakan T-SQL ALTER TABLE. Namun, itu lebih mudah diucapkan daripada dilakukan. Pada titik ini, Anda membutuhkan lebih banyak kesabaran selain kecerdasan dan kemauan Anda. Nanti, kita akan menemukan sintaks untuk menonaktifkan dan mengaktifkan kembali kunci asing.

Hal lain yang perlu dipertimbangkan adalah menggunakan database sebagai staging area untuk OLAP atau analisis data. Misalkan database transaksional sumber bersih dari baris yatim piatu. Atau Anda dapat mengatur untuk menghindari baris ini melalui kode. Kemudian Anda dapat memilih untuk tidak menggunakan kunci asing. Kunci asing akan memperlambat penyisipan dan pembaruan massal, terutama pada kumpulan data yang sangat besar.

3 Cara Mudah untuk Menambah, Mengedit, dan Menghapus Batasan Kunci Asing SQL

Apa yang diperlukan untuk menambah, mengedit, atau menghapus kunci asing? Mudah dengan 3 tips ini.

Dua langkah pertama menggunakan antarmuka pengguna grafis. Alat seperti SQL Server Management Studio atau dbForge Studio untuk SQL Server adalah kandidat yang sangat baik. Yang ketiga akan menggunakan kode T-SQL. Pilihan kode GUI atau T-SQL tergantung pada situasinya.

1. Menggunakan Perancang Tabel untuk Menambah, Mengedit, dan Menghapus Batasan Kunci Asing SQL

Di SQL dimungkinkan untuk menambahkan batasan kunci asing saat membuat atau mengubah struktur tabel menggunakan Perancang Tabel di SSMS. Gambar 1 di bawah ini menunjukkan cara mengaksesnya dari menu utama saat struktur tabel terbuka.

Opsi lainnya adalah mengeklik kanan di mana saja dari desainer tabel dan memilih Relationships dari menu konteks:

Setelah Anda memilih Hubungan , Hubungan Kunci Asing jendela akan muncul:

Dalam Hubungan Kunci Asing jendela, Anda dapat memilih untuk menambahkan kunci asing baru atau mengedit/menghapus yang sudah ada.

Jika Anda memilih untuk menambahkan atau mengedit, klik untuk meluaskan Tabel dan Kolom Spesifikasi. Kemudian klik elipsis tombol untuk menentukan atau mengedit tabel kunci utama dan asing.

Dari sana, Anda dapat menunjukkan kolom kunci utama dan asing.

Setelah menentukan kunci utama dan kunci asing, klik OK . Kemudian navigasikan kembali ke desainer tabel dan simpan perubahannya.

2. Menggunakan Diagram Basis Data untuk Menambah, Mengedit, dan Menghapus Batasan Kunci Asing SQL

Anda dapat menggunakan Diagram Basis Data untuk membuat batasan kunci asing SQL. Gambar 5 menunjukkan cara membuat hubungan antara dua tabel dengan mengklik tabel kunci asing dan menyeretnya ke tabel kunci utama.

Saat Anda melepaskan mouse, Tabel dan Kolom akan muncul jendela seperti pada Gambar 4. Kemudian Anda dapat menunjukkan kolom kunci utama dan asing. Kemudian klik OK.

Untuk mengedit hubungan yang sudah ada, klik kanan hubungan dalam diagram. Kemudian pilih Properti :

Kemudian, di Properti jendela, luaskan Tabel dan Kolom dan klik elipsis tombol:

Setelah mengklik elipsis tombol, Tabel dan Kolom jendela akan muncul. Anda dapat mengubah kolom primary dan foreign key (lihat kembali Gambar 4 di atas).

Sementara itu, menghapus hubungan memerlukan klik kanan yang sudah ada hubungan. Pilih Hapus Hubungan dari Basis Data dan klik Ya saat diminta.

3. Menggunakan T-SQL untuk Menambah, Mengedit, dan Menghapus Batasan Kunci Asing SQL

Cara ketiga untuk menambahkan kunci asing adalah melalui kode T-SQL. Anda dapat menggunakan SQL CREATE TABLE dan menambahkan batasan kunci asing. Atau Anda juga dapat menggunakan ALTER TABLE untuk menambahkan batasan ini setelah membuat tabel.

Berikut adalah sintaks untuk menggunakan CREATE TABLE:

-- Single-column foreign key
CREATE TABLE Table2
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
 col1 INT NULL REFERENCES Table1(col1)
)
GO

Setelah menentukan nama dan jenis kolom, Anda dapat menambahkan REFERENCES ke tabel dan kolom. Sintaks di atas menunjukkan Tabel1 tabel di col1 kolom. Perhatikan bahwa nama kolom pada kedua tabel harus sama agar valid untuk kunci asing.

Sintaks di atas adalah untuk kunci asing satu kolom. Jika Anda membutuhkan beberapa kolom sebagai kunci asing, gunakan klausa KUNCI ASING seperti di bawah ini:

-- Multiple-column foreign key
CREATE TABLE Table2
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
 col1 INT NOT NULL,
 col2 INT NOT NULL,
 col3 VARCHAR(10) NULL
 CONSTRAINT FK_Table1_Table2 FOREIGN KEY(col1, col2)
	REFERENCES Table1(col1,col2)
)
GO

Setelah membuat tabel, Anda dapat menambahkan kunci asing menggunakan ALTER TABLE. Berikut sintaksnya:

ALTER TABLE Table2 WITH CHECK ADD CONSTRAINT FK_Table1_Table2_2 FOREIGN KEY(col3)
	REFERENCES Table3(col1)
GO

Untuk menghapus batasan kunci asing, Anda dapat menggunakan ALTER TABLE dengan DROP CONSTRAINT:

ALTER TABLE Table2 
DROP CONSTRAINT FK_Table1_Table2_2
GO

Sekarang, kita dapat merangkum 3 cara untuk menambah, mengedit, dan menghapus kunci asing:

Contoh Batasan Kunci Asing SQL (MySQL)

Meja Anak Memiliki 1 Referensi ke Tabel Induk

-- Single Reference
CREATE TABLE [dbo].[Countries](
	[CountryID] [int] IDENTITY(1,1) NOT NULL,
	[Country] [nvarchar](50) NOT NULL,
	[ContinentID] [int] NULL,
	[Modified] [datetime] NOT NULL,
 CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED 
(
	[CountryID] ASC
))
GO

ALTER TABLE [dbo].[Countries]  WITH CHECK ADD CONSTRAINT [FK_Countries_Continent] FOREIGN KEY([ContinentID])
REFERENCES [dbo].[Continent] ([ContinentID])

GO

ALTER TABLE [dbo].[Countries] CHECK CONSTRAINT [FK_Countries_Continent]
GO

Untuk memvisualisasikan hubungan ini, lihat Gambar 9 di bawah ini:

ContinentID adalah kunci yang menghubungkan kedua tabel.

Tabel Anak Memiliki Banyak Referensi

SportsCar tabel memiliki banyak referensi ke tiga tabel berbeda:

-- Multiple References
CREATE TABLE [dbo].[SportsCars](
	[SportsCarID] [int] IDENTITY(1,1) NOT NULL,
	[ManufacturerID] [int] NULL,
	[StyleID] [int] NULL,
	[CountryID] [int] NULL,
	[Model] [nvarchar](50) NOT NULL,
	[Years] [varchar](50) NOT NULL,
	[Notes] [varchar](255) NOT NULL,
	[Modified] [datetime] NOT NULL,
 CONSTRAINT [PK_SportsCars] PRIMARY KEY CLUSTERED 
(
	[SportsCarID] ASC
))
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Country] FOREIGN KEY([CountryID])
REFERENCES [dbo].[Countries] ([CountryID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Country]
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Manufacturer] FOREIGN KEY([ManufacturerID])
REFERENCES [dbo].[Manufacturers] ([ManufacturerID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Manufacturer]
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Styles] FOREIGN KEY([StyleID])
REFERENCES [dbo].[Styles] ([StyleID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Styles]
GO

Berikut adalah tampilannya dalam diagram database:

Referensi Mandiri

Hirarki Posisi menunjukkan referensi diri dalam tabel berikut:

CREATE TABLE [dbo].[Ranks](
	[RankId] [int] IDENTITY(1,1) NOT NULL,
	[Rank] [varchar](50) NOT NULL,
	[RankLevel] [smallint] NOT NULL,
	[RankParentId] [int] NULL,
 CONSTRAINT [PK_Ranks] PRIMARY KEY CLUSTERED 
(
	[RankId] ASC
)) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Ranks] WITH CHECK ADD CONSTRAINT [FK_Ranks_Ranks] FOREIGN KEY([RankParentId])
REFERENCES [dbo].[Ranks] ([RankId])
GO

ALTER TABLE [dbo].[Ranks] CHECK CONSTRAINT [FK_Ranks_Ranks]
GO

Diagram referensi diri ini sederhana. Garis menunjuk ke tabel yang sama dalam referensi sendiri.

Dengan ON UPDATE dan ON DELETE

Dengan ON UPDATE CASCADE, memperbarui nilai kolom kunci utama akan memperbarui nilai kunci asing di tabel terkait juga. Sementara itu, ketika Anda menggunakan ON DELETE CASCADE, menghapus kunci utama juga akan menghapus kunci asing. Default untuk ON UPDATE dan ON DELETE adalah NO ACTION.

Berikut ini contoh UPDATE dan DELETE CASCADE:

ALTER TABLE [dbo].[Countries] WITH CHECK ADD CONSTRAINT [FK_Countries_Continent] FOREIGN KEY([ContinentID])
REFERENCES [dbo].[Continent] ([ContinentID]) 
ON UPDATE CASCADE 
ON DELETE CASCADE
GO

Menonaktifkan Batasan Kunci Asing SQL

Berikut ini akan menonaktifkan batasan kunci asing yang ada. Perhatikan bahwa hubungan masih ada.

ALTER TABLE [dbo].[SportsCars] NOCHECK CONSTRAINT [FK_SportsCars_Country]
GO

Ini bukan default, dan tidak disarankan. Tetapi untuk mempercepat penyisipan dan pembaruan massal, Anda dapat menonaktifkan sementara kunci asing seperti di atas. Setelah selesai, Anda harus mengaktifkannya kembali menggunakan CHECK CONSTRAINT.

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Country]
GO

Dapatkan dan Perbaikan

Bagian ini akan menunjukkan kepada Anda apa yang terjadi ketika Anda INSERT, UPDATE, atau DELETE record dengan foreign key. Ini juga mengasumsikan bahwa kunci asing tidak dinonaktifkan dengan KENDALA NOCHECK. Ini akan membantu Anda saat menghadapi masalah umum ini.

Saat INSERT

-- This will cause an error because countryID = 47 does not exist in the Countries table
INSERT INTO SportsCars 
(ManufacturerID, StyleID, CountryID, Model, Years, Notes) 
VALUES (108, 10, 47, 'F2', '2021', 'Limited Edition')
GO

Berikut pesan kesalahannya:

Msg 547, Level 16, State 0, Line 56
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_SportsCars_Country". The conflict occurred in database "Vehicles", table "dbo.Countries", column 'CountryID'.
The statement has been terminated.

Perbaikan :Tambahkan CountryID =47 ke dalam Negara meja dulu. Kemudian, jalankan kembali pernyataan INSERT di atas. Urutannya dimulai dengan menyisipkan record ke tabel induk, lalu ke tabel anak.

Pada PEMBARUAN

-- Update CountryID to 47 will trigger an error.
UPDATE SportsCars
SET CountryID = 47
WHERE ManufacturerID = 108
GO

Inilah kesalahan UPDATE:

Msg 547, Level 16, State 0, Line 60
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_SportsCars_Country". The conflict occurred in database "Vehicles", table "dbo.Countries", column 'CountryID'.
The statement has been terminated.

Perbaikan :Tambahkan CountryID =47 ke dalam Negara meja. Kemudian, jalankan kembali pernyataan UPDATE.

Pada HAPUS

-- This will trigger an error because ManufacturerID = 108 is referenced in the SportsCars table
DELETE FROM Manufacturers
WHERE ManufacturerID = 108

Kode ini akan memicu kesalahan seperti di bawah ini:

Msg 547, Level 16, State 0, Line 64
The DELETE statement conflicted with the REFERENCE constraint "FK_SportsCars_Manufacturer". The conflict occurred in database "Vehicles", table "dbo.SportsCars", column 'ManufacturerID'.
The statement has been terminated.

Perbaikan :Hapus catatan yang sesuai dari SportsCars tabel dengan ManufacturerID =108. Kemudian, jalankan kembali pernyataan DELETE di atas. Cara lain adalah dengan mengaktifkan ON DELETE CASCADE jika berlaku. Urutannya dimulai dengan menghapus record dari tabel anak, dan kemudian – dari tabel induk.

Bawa Pulang

Jadi, apakah kunci asing masih asing bagi Anda?

Mari kita rekap apa yang telah kita pelajari sejauh ini.

  • Kunci asing menghubungkan dua tabel (atau satu tabel saat menggunakan referensi sendiri). Anda membutuhkannya untuk memastikan integritas referensial.
  • Anda dapat menggunakan alat GUI atau T-SQL untuk menambah, mengedit, atau menghapus batasan kunci asing.
  • Untuk alat GUI, Anda dapat menggunakan SQL Server Management Studio atau dbForge Studio untuk SQL Server. Keduanya menawarkan diagram database dan desainer tabel untuk membuat tabel dengan kunci utama dan kunci asing.
  • CREATE TABLE dan ALTER TABLE cocok untuk menambahkan dan menghapus batasan kunci asing.
  • Anda dapat menonaktifkan kunci asing untuk sementara dengan NOCHECK CONSTRAINT di ALTER TABLE. Ini akan mempercepat penyisipan dan pembaruan massal. Tapi pastikan untuk mengaktifkannya kembali dengan CHECK CONSTRAINT.
  • Untuk menghindari gotcha dengan kunci asing, pastikan untuk mengikuti urutan yang benar. Untuk INSERT dan UPDATE, masukkan dulu ke tabel induk, lalu ke tabel anak. Untuk DELETE, hapus record anak terlebih dahulu, lalu hapus record induk.

Apakah Anda ingin menambahkan sesuatu untuk membantu pemula menguasai kunci asing? Komentar bagian terbuka untuk ide-ide cemerlang Anda. Jika Anda menyukai postingan ini, silakan bagikan ke platform media sosial favorit Anda.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PL/SQL Strong Ref Cursor Dengan Tipe Data Rekam Buatan Pengguna

  2. Dapatkan dinyalakan dengan Apache Spark – Bagian 1

  3. Menggunakan DBCC CLOENDATABASE dan Query Store untuk Pengujian

  4. Paket Berbeda untuk Server Identik

  5. Pengantar Concurrent Collection API di Java