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 maju.
Kami akan mengambil contoh, tabel perusahaan dengan tabel pengguna yang berisi orang-orang dari perusahaan tesis 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 klausa ON UPDATE :
- PADA PEMBARUAN TERBARU : standar : jika Anda mencoba memperbarui company_id dalam tabel PERUSAHAAN mesin akan menolak operasi jika satu PENGGUNA setidaknya memiliki tautan pada perusahaan ini.
- PADA PEMBARUAN TANPA TINDAKAN : sama dengan RESTRICT.
- PADA UPDATE CASCADE : biasanya yang terbaik : jika Anda memperbarui company_id dalam satu baris tabel PERUSAHAAN, mesin akan memperbaruinya sesuai pada semua baris USER yang merujuk PERUSAHAAN ini (tetapi tidak ada pemicu yang diaktifkan pada tabel USER, peringatan). Mesin akan melacak perubahan untuk Anda, itu bagus.
- PADA UPDATE SET NULL : jika Anda memperbarui company_id di baris tabel PERUSAHAAN, mesin akan mengatur USER yang terkait company_id ke NULL (harus tersedia di bidang USER company_id). Saya tidak dapat melihat hal yang menarik untuk dilakukan dengan itu pada pembaruan, tetapi saya mungkin salah.
Dan sekarang di sisi ON DELETE :
- ON DELETE RESTRICT : default : jika Anda mencoba menghapus ID company_id di tabel PERUSAHAAN mesin akan menolak operasi jika satu PENGGUNA setidaknya memiliki tautan di perusahaan ini, dapat menyelamatkan hidup Anda.
- HAPUS TANPA TINDAKAN : sama dengan RESTRICT
- PADA HAPUS CASCADE : berbahaya : jika Anda menghapus baris perusahaan dalam tabel PERUSAHAAN mesin akan menghapus juga PENGGUNA terkait. Ini berbahaya tetapi dapat digunakan untuk melakukan pembersihan otomatis pada tabel sekunder (jadi itu bisa menjadi sesuatu yang Anda inginkan, tetapi tentu saja bukan untuk PERUSAHAAN <-> contoh PENGGUNA)
- ON DELETE SET NULL : handful : jika Anda menghapus baris PERUSAHAAN, PENGGUNA yang terkait akan secara otomatis memiliki hubungan dengan NULL. Jika Null adalah nilai Anda untuk pengguna yang tidak memiliki perusahaan, ini bisa menjadi perilaku yang baik, misalnya mungkin Anda perlu menyimpan pengguna dalam aplikasi Anda, sebagai penulis beberapa konten, tetapi menghapus perusahaan itu bukan masalah bagi Anda.
biasanya default saya adalah: ON DELETE RESTRICT ON UPDATE CASCADE . dengan beberapa ON DELETE CASCADE
untuk tabel track (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 PEKERJAAN untuk tabel USER.
Edit
Sudah lama sejak saya menulis itu. Sekarang saya pikir saya harus menambahkan satu peringatan penting. MySQL memiliki satu batasan besar yang didokumentasikan dengan kaskade.Cascade tidak memicu pemicu . Jadi, jika Anda terlalu percaya diri pada mesin itu untuk menggunakan pemicu, Anda harus menghindari kendala kaskade.
Pemicu MySQL hanya aktif untuk perubahan yang dibuat ke tabel oleh pernyataan SQL. Mereka tidak mengaktifkan untuk perubahan dalam tampilan, atau oleh perubahan pada tabel yang dibuat oleh API yang tidak mengirimkan pernyataan SQL ke Server MySQL
==> Lihat di bawah hasil edit terakhir, banyak hal bergerak di domain ini
Pemicu tidak diaktifkan oleh tindakan kunci asing.
Dan saya tidak berpikir ini akan diperbaiki suatu hari nanti. Batasan kunci asing dikelola oleh penyimpanan InnoDb dan Pemicu dikelola oleh mesin MySQL SQL. Keduanya terpisah. Innodb adalah satu-satunya penyimpanan dengan manajemen kendala, mungkin mereka akan menambahkan pemicu langsung di mesin penyimpanan suatu hari, mungkin tidak.
Tapi saya punya pendapat sendiri tentang elemen mana yang harus Anda pilih antara implementasi pemicu yang buruk dan dukungan kendala kunci asing yang sangat berguna. Dan begitu Anda terbiasa dengan konsistensi basis data, Anda akan menyukai PostgreSQL.
12/2017-Memperbarui Edit ini tentang MySQL:
seperti yang dinyatakan oleh @IstiaqueAhmed dalam komentar, situasinya telah berubah pada subjek ini. Jadi ikuti tautannya dan periksa situasi terkini yang sebenarnya (yang mungkin berubah lagi di masa mendatang).
ON DELETE CASCADE : dangerous
- ambil dengan sedikit garam.SET NULL
dalamON UPDATE
: memperbarui perusahaan merupakan pelepasan Perusahaan> Hubungan pengguna. Misalnya: jika perusahaan mengubah jenis bisnisnya, pengguna sebelumnya mungkin tidak lagi terkait dengan bisnis itu, karena ituNULL
mungkin lebih disukai untuk indeks ini.This includes changes to base tables that underlie updatable views
bukannya apa yang Anda tempel yaituThey do not activate for changes in views
CASCADE DELETE
umumnya juga oke, bahkan disukai. Saya tidak menganggapnya sangat berbahaya.Penambahan jawaban @MarkR - satu hal yang perlu diperhatikan adalah bahwa banyak kerangka kerja PHP dengan ORM tidak akan mengenali atau menggunakan pengaturan DB lanjutan (kunci asing, penghapusan cascading, kendala unik), dan ini dapat mengakibatkan perilaku yang tidak terduga.
Misalnya jika Anda menghapus catatan menggunakan ORM, dan Anda
DELETE CASCADE
akan menghapus catatan dalam tabel terkait, upaya ORM untuk menghapus catatan terkait ini (sering otomatis) akan menghasilkan kesalahan.sumber
Anda harus mempertimbangkan ini dalam konteks aplikasi. Secara umum, Anda harus mendesain aplikasi, bukan database (database hanya menjadi bagian dari aplikasi).
Pertimbangkan bagaimana aplikasi Anda harus menanggapi berbagai kasus.
Tindakan default adalah untuk membatasi (yaitu tidak mengizinkan) operasi, yang biasanya apa yang Anda inginkan karena mencegah kesalahan pemrograman bodoh. Namun, DELETE CASCADE juga bisa bermanfaat. Ini benar-benar tergantung pada aplikasi Anda dan bagaimana Anda ingin menghapus objek tertentu.
Secara pribadi, saya akan menggunakan InnoDB karena tidak membuang data Anda (lih. MyISAM, yang melakukannya), daripada karena memiliki kendala FK.
sumber