Aku punya dua tabel di MySQL database- parent
, child
. Saya mencoba menambahkan referensi kunci asing ke tabel anak saya berdasarkan tabel induk. Apakah ada perbedaan yang signifikan antara ON UPDATE CASCADE
danON DELETE CASCADE
My Parent Table
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Pertanyaan saya adalah: Apa perbedaan antara kueri sql berikut.
ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=INNODB;
Apakah ada kesalahan dalam kueri? Apa maksud dari pertanyaan ini (1,2 & 3) ?? Apakah mereka sama ???
mysql
innodb
mysql-5.5
foreign-key
Lonewolf
sumber
sumber
Jawaban:
Sebuah utas yang sangat baik mengenai hal ini dapat ditemukan di sini dan juga di sini . Panduan definitif untuk MySQL, tentu saja, dokumentasi, dapat ditemukan di sini .
Dalam standar SQL 2003 ada 5 tindakan referensial yang berbeda:
Untuk menjawab pertanyaan:
RIAM
ON DELETE CASCADE
berarti bahwa jika catatan induk dihapus, catatan anak apa pun juga dihapus. Ini bukan ide yang bagus menurut saya. Anda harus melacak semua data yang pernah ada di database, meskipun ini bisa dilakukan dengan menggunakanTRIGGER
s. (Namun, lihat peringatan dalam komentar di bawah).ON UPDATE CASCADE
berarti bahwa jika kunci utama induk diubah, nilai anak juga akan berubah untuk mencerminkan itu. Sekali lagi menurut saya, bukan ide yang bagus. Jika Anda mengubahPRIMARY KEY
dengan keteraturan (atau bahkan sama sekali!), Ada yang salah dengan desain Anda. Sekali lagi, lihat komentar.ON UPDATE CASCADE ON DELETE CASCADE
berarti bahwa jika AndaUPDATE
ATAUDELETE
orang tua, perubahan akan mengalir ke anak. Ini setaraAND
dengan hasil dari dua pernyataan pertama.MEMBATASI
RESTRICT
berarti bahwa setiap upaya untuk menghapus dan / atau memperbarui induk akan gagal melempar kesalahan. Ini adalah perilaku default jika suatu tindakan referensial tidak ditentukan secara eksplisit.TIDAK ADA TINDAKAN
NO ACTION
: Dari manual . Kata kunci dari SQL standar. Di MySQL, setara denganRESTRICT
. Server MySQL menolak operasi hapus atau perbarui untuk tabel induk jika ada nilai kunci asing terkait di tabel referensi. Beberapa sistem database memiliki cek yang ditangguhkan, danNO ACTION
merupakan cek yang ditangguhkan. Di MySQL, batasan kunci asing diperiksa segera, jadiNO ACTION
sama denganRESTRICT
.SET NULL
SET NULL
- lagi dari manual. Hapus atau perbarui baris dari tabel induk, dan atur kolom kunci asing atau kolom di tabel anakNULL
. Ini bukan yang terbaik dari ide IMHO, terutama karena tidak ada cara "perjalanan waktu" - yaitu melihat kembali ke tabel anak dan mengaitkan catatan denganNULL
s dengan catatan induk yang relevan - baikCASCADE
atau menggunakanTRIGGER
s untuk mengisi tabel logging untuk melacak perubahan (tetapi, lihat komentar).SET STANDAR
SET DEFAULT
. Namun, bagian lain (berpotensi sangat berguna) dari standar SQL yang tidak pernah diimplementasikan oleh MySQL! Mengizinkan pengembang menentukan nilai yang akan ditetapkan kolom kunci asing pada PEMBARUAN atau HAPUS. InnoDB dan NDB akan menolak definisi tabel denganSET DEFAULT
klausa.Seperti disebutkan di atas, Anda harus meluangkan waktu melihat dokumentasi, di sini .
sumber
Keduanya adalah tindakan yang harus dilakukan, masing-masing, ketika catatan yang direferensikan pada tabel induk mengubah id dan ketika itu dihapus.
Jika Anda menjalankan:
Dan setidaknya ada satu rekaman
child
denganparent_id = 1
, 1) akan gagal; dalam kasus 2) dan 3), semua catatan dengan parent_id = 1 diperbarui ke parent_id = -1.Jika Anda menjalankan:
Dan setidaknya ada satu rekaman
child
denganparent_id = 1
, 2) akan gagal; dalam kasus 1) dan 3), semua catatan denganparent_id = 1
dihapus.3) secara sintaksis benar.
Dokumentasi lengkap dapat ditemukan pada manual .
sumber
Saya tidak memiliki reputasi yang cukup untuk mengomentari jawaban sebelumnya. Jadi saya pikir saya akan menguraikan sedikit.
1) ON DELETE CASCADE berarti jika catatan induk dihapus, maka setiap catatan anak referensi juga dihapus. PADA UPDATE secara default ke RESTRICT, yang berarti UPDATE pada catatan induk akan gagal.
2) ON DELETE action default ke RESTRICT, yang berarti DELETE pada record induk akan gagal. TENTANG PEMBARUAN CASCADE akan memperbarui semua catatan anak referensi ketika catatan induk diperbarui.
3) Lihat tindakan CASCADE dalam 1) dan 2) di atas.
Saat menggunakan ID induk dicatat sebagai kunci asing (dalam tabel anak) - pengalaman mengatakan a) jika ID adalah nomor urut yang dihasilkan secara otomatis, maka JANGAN menggunakannya sebagai kunci asing. Gunakan beberapa kunci induk unik lainnya sebagai gantinya. b) jika ID adalah GUID, maka boleh saja menggunakannya sebagai kunci asing. Anda akan melihat kebijaksanaan dalam saran ini ketika Anda mengekspor dan mengimpor catatan atau menyalin catatan ke database lain. Terlalu rumit untuk berurusan dengan nomor urut yang dibuat secara otomatis selama migrasi data ketika mereka dirujuk sebagai kunci asing.
sumber