Bagaimana cara menggunakan RESTRICT untuk Foreign Key di mysql?

11

Dalam struktur basis data PT

  CREATE TABLE Country (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE City (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE Map (
  country varchar(40) NOT NULL,
  city varchar(100) NOT NULL,
  PRIMARY KEY  (country,city),
  FOREIGN KEY (country) REFERENCES Country (name) ON DELETE CASCADE,
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Saya berharap untuk menghapus induk dari Citydengan membiarkan nilai yang sesuai di child utuh dengan tiga perintah yang sama ini

  FOREIGN KEY (city) REFERENCES City (name) ON DELETE NO ACTION
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
  FOREIGN KEY (city) REFERENCES City (name)

Tetapi saat menggunakan NO ACTIONATAU RESTRICTatau menghilangkan ON DELETE. MySQL tidak mengizinkan saya untuk menghapus dari kolom induk dengan kesalahan ini:

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 
('test'.'Map', CONSTRAINT 'Map_ibfk_2' FOREIGN KEY ('city') REFERENCES 'City'('name')
 ON DELETE RESTRICT

Dimana saya salah Bukankah itu tanggung jawab SQL NO ACTIONuntuk menghapus orang tua dan meninggalkan anak yatim?

Googlebot
sumber

Jawaban:

13

Menurut Dokumentasi MySQL pada DELETE RESTRICT

• RESTRICT: Menolak operasi hapus atau perbarui untuk tabel induk. Menentukan RESTRICT (atau TANPA TINDAKAN) sama dengan menghilangkan klausa ON DELETE atau ON UPDATE.

Adapun TANPA TINDAKAN

• TANPA TINDAKAN: Kata kunci dari SQL standar. Di MySQL, setara dengan RESTRICT. InnoDB menolak operasi hapus atau perbarui untuk tabel induk jika ada nilai kunci asing terkait di tabel yang direferensikan. Beberapa sistem database memiliki cek yang ditangguhkan, dan NO ACTION adalah cek yang ditangguhkan. Di MySQL, batasan kunci asing diperiksa segera, jadi TIDAK ADA TINDAKAN sama dengan RESTRICT.

DELETE RESTRICT melindungi orang tua dari penghapusan, bukan anak-anak.

RolandoMySQLDBA
sumber
5

Jika Anda ingin menghapus orang tua dan meninggalkan anak, maka Anda mungkin menginginkan ON DELETE SET NULLopsi:

SET NULL: Hapus atau perbarui baris dari tabel induk, dan atur kolom kunci asing atau kolom di tabel anak ke NULL. Klausa ON DELETE SET NULL dan ON UPDATE SET NULL didukung.

Jika Anda menentukan tindakan SET NULL, pastikan Anda belum mendeklarasikan kolom dalam tabel anak sebagai NOT NULL.

Ada banyak 'tidak' dalam kalimat terakhir itu, jadi pastikan parent_id bisa NULL.

Lihat juga pertanyaan terkait ini: Apa tujuan SET NULL dalam batasan Hapus / Perbarui Kunci Asing?

Dengan mendefinisikan kunci asing, Anda telah memberitahu database untuk tidak menerima entri dalam tabel anak yang tidak memiliki nilai yang sesuai di induknya.

Derek Downey
sumber