Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Batasan kunci asing:Kapan menggunakan ON UPDATE dan ON DELETE

Jangan ragu untuk memberikan batasan pada database. Anda pasti akan memiliki database yang konsisten, dan itulah salah satu alasan bagus untuk menggunakan database. Terutama jika Anda memiliki beberapa aplikasi yang memintanya (atau hanya satu aplikasi tetapi dengan mode langsung dan mode batch menggunakan sumber yang berbeda).

Dengan MySQL Anda tidak memiliki batasan lanjutan seperti yang Anda miliki di postgreSQL tetapi setidaknya batasan kunci asing cukup canggih.

Kami akan mengambil contoh, tabel perusahaan dengan tabel pengguna yang berisi orang-orang dari perusahaan ini

CREATE TABLE COMPANY (
     company_id INT NOT NULL,
     company_name VARCHAR(50),
     PRIMARY KEY (company_id)
) ENGINE=INNODB;

CREATE TABLE USER (
     user_id INT, 
     user_name VARCHAR(50), 
     company_id INT,
     INDEX company_id_idx (company_id),
     FOREIGN KEY (company_id) REFERENCES COMPANY (company_id) ON...
) ENGINE=INNODB;

Mari kita lihat DI UPDATE klausa:

  • PADA PEMBARUAN PEMBATASAN :default :jika Anda mencoba memperbarui company_id di tabel PERUSAHAAN, mesin akan menolak operasi jika setidaknya satu PENGGUNA menautkan perusahaan ini.
  • TIDAK PERBARUI TANPA TINDAKAN :sama seperti MEMBATASI.
  • SELAMAT UPDATE CASCADE :biasanya yang terbaik :jika Anda memperbarui company_id di baris tabel PERUSAHAAN, mesin akan memperbaruinya sesuai dengan semua baris PENGGUNA yang merujuk PERUSAHAAN ini (tetapi tidak ada pemicu yang diaktifkan pada tabel PENGGUNA, peringatan). Mesin akan melacak perubahan untuk Anda, bagus.
  • ON UPDATE SET NULL :jika Anda memperbarui company_id di deretan tabel COMPANY, mesin akan menyetel USERs company_id terkait ke NULL (harus tersedia di bidang USER company_id). Saya tidak dapat melihat hal menarik terkait hal itu pada pembaruan, tetapi saya mungkin salah.

Dan sekarang di ON DELETE samping:

  • HAPUS PEMBATASAN :default :jika Anda mencoba menghapus ID company_id di tabel PERUSAHAAN, mesin akan menolak operasi jika setidaknya satu PENGGUNA menautkan ke perusahaan ini, dapat menyelamatkan hidup Anda.
  • TIDAK ADA TINDAKAN DIHAPUS :sama seperti MEMBATASI
  • SELAMAT HAPUS CASCADE :berbahaya :jika Anda menghapus baris perusahaan di tabel PERUSAHAAN, mesin juga akan menghapus PENGGUNA terkait. Ini berbahaya tetapi dapat digunakan untuk melakukan pembersihan otomatis pada tabel sekunder (sehingga dapat menjadi sesuatu yang Anda inginkan, tetapi tentu saja tidak untuk PERUSAHAAN<->contoh PENGGUNA)
  • ON DELETE SET NULL :segenggam :jika Anda menghapus baris PERUSAHAAN, PENGGUNA terkait akan secara otomatis memiliki hubungan dengan NULL. Jika Null adalah nilai Anda untuk pengguna tanpa perusahaan, ini bisa menjadi perilaku yang baik, misalnya mungkin Anda perlu mempertahankan pengguna di aplikasi Anda, sebagai pembuat beberapa konten, tetapi menghapus perusahaan tidak menjadi masalah bagi Anda.

biasanya default saya adalah:ON DELETE RESTRICT ON UPDATE CASCADE . dengan beberapa ON DELETE CASCADE untuk tabel trek (log--tidak semua log--, hal-hal seperti itu) dan ON DELETE SET NULL ketika tabel master adalah 'atribut sederhana' untuk tabel yang berisi kunci asing, seperti tabel JOB untuk tabel USER.

Sunting

Sudah lama sejak saya menulis itu. Sekarang saya pikir saya harus menambahkan satu peringatan penting. MySQL memiliki satu batasan besar yang terdokumentasi dengan kaskade. Cascade bukan pemicu pemicu . Jadi, jika Anda terlalu percaya diri dengan mesin itu untuk menggunakan pemicu, Anda harus menghindari kendala kaskade.

==> Lihat di bawah editan terakhir, segala sesuatunya bergerak di domain ini

Dan saya tidak berpikir ini akan diperbaiki suatu hari nanti. Batasan kunci asing dikelola oleh penyimpanan InnoDb dan Pemicu dikelola oleh mesin SQL MySQL. Keduanya dipisahkan. Innodb adalah satu-satunya penyimpanan dengan manajemen batasan, mungkin mereka akan menambahkan pemicu langsung di mesin penyimpanan suatu hari nanti, mungkin tidak.

Tetapi saya memiliki pendapat saya sendiri tentang elemen mana yang harus Anda pilih antara implementasi pemicu yang buruk dan dukungan batasan kunci asing yang sangat berguna. Dan setelah Anda terbiasa dengan konsistensi basis data, Anda akan menyukai PostgreSQL.

12/2017-Memperbarui Editan tentang MySQL ini:

seperti yang dinyatakan oleh @IstiaqueAhmed di komentar, situasi telah berubah tentang hal ini. Jadi, ikuti tautan dan periksa situasi terkini yang sebenarnya (yang dapat berubah lagi di masa mendatang).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bisakah kunci asing mereferensikan indeks yang tidak unik?

  2. disederhanakan:mysqli num_rows tidak berfungsi

  3. php mysql bandingkan panjang dan lat, kembalikan yang di bawah 10 mil

  4. Bagaimana cara membandingkan dua bidang/kolom dalam suatu kondisi?

  5. MySQL:Bagaimana mengizinkan koneksi jarak jauh ke mysql