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

Masalah MySQL dan FK

Kolom kunci asing harus merujuk kolom yang terdiri dari awalan paling kiri dari kunci utama atau kunci unik di tabel induk.

Dengan kata lain, contoh berikut berfungsi di InnoDB:

CREATE TABLE Foo ( a INT, b INT, c INT, PRIMARY KEY (a,b,c) );
CREATE TABLE Bar ( x INT, y INT );

ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(b,c); -- WRONG

ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,c); -- WRONG

ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,b); -- RIGHT

ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(b); -- WRONG

ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(a); -- RIGHT

Anda mendapatkan kesalahan karena Anda mencoba melakukan yang setara dengan (x) referensi Foo(b).
Kolom Anda codmenuitem adalah kolom kedua dari tiga kolom di kunci utama induk.

Ini akan berfungsi jika smenuitememp.codemenuitem adalah untuk referensi smenuitem.codmodulo , karena kolom itu adalah kolom paling kiri di kunci utama tabel induk.

Kembali pertanyaan tindak lanjut Anda:

Ingatlah cara kerja kunci asing. Setiap kali Anda menyisipkan atau memperbarui baris di tabel anak, baris tersebut perlu mencari baris di tabel induk untuk memverifikasi bahwa nilai ada di kolom yang direferensikan. Jika kolom tidak diindeks, itu harus melakukan pemindaian tabel untuk mencapai pencarian ini, dan itu akan sangat mahal, dengan asumsi tabel induk Anda bertambah.

Jika Anda mencoba mencari baris berdasarkan kolom tengah indeks multi-kolom, indeks tidak membantu Anda. Dengan analogi, ini seperti mencari buku telepon untuk semua orang dengan nama tengah tertentu.

Standar ANSI SQL mengharuskan kolom yang direferensikan menjadi bagian dari KUNCI UTAMA atau KUNCI UNIK, dan kolom kunci asing harus cocok dengan semua kolom dari batasan utama atau unik di induknya.

Tapi InnoDB lebih permisif. Itu masih mengharuskan kolom yang direferensikan di tabel induk diindeks sehingga pencarian bisa efisien, dan bahwa kolom yang direferensikan menjadi yang paling kiri dalam indeks. Tapi indeks non-unik tidak apa-apa; itu diperbolehkan untuk kunci asing untuk referensi itu.

Hal ini dapat menyebabkan kasus aneh seperti baris anak yang mereferensikan lebih dari satu baris di induknya, tetapi diharapkan Anda akan menangani anomali tersebut.

Saya merasa perlu untuk menekankan poin terakhir. Anda akan dapatkan data anomali jika Anda mendefinisikan kunci asing ke kolom yang diindeks secara tidak unik di induknya. Ini mungkin akan menyebabkan kueri Anda melaporkan baris beberapa kali saat Anda bergabung. Anda tidak boleh menggunakan perilaku InnoDB ini; Anda harus mendefinisikan kunci asing hanya untuk kolom induk yang unik.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah tabel database diurutkan sebelum atau setelah diambil?

  2. jdbc4.MySQLSyntaxErrorException:Tabel tidak ada di database

  3. mysql_fetch_array() mengharapkan parameter 1 menjadi sumber daya, string diberikan

  4. Bagaimana cara mengganti pola regex di MySQL

  5. Bantuan kueri sql Magento diperlukan dengan kueri besar-besaran