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

Dalam SQL, bolehkah dua tabel saling merujuk?

Tidak, tidak apa-apa. Referensi melingkar antar tabel berantakan. Lihat artikel (lama satu dekade) ini:SQL By Design:The Circular Reference

Beberapa DBMS dapat menangani ini, dan dengan perhatian khusus, tetapi MySQL akan mengalami masalah.

Opsi 1

Sebagai desain Anda, untuk membuat salah satu dari dua FK dapat dibatalkan. Ini memungkinkan Anda untuk memecahkan masalah ayam-dan-telur (meja mana yang harus saya masukkan terlebih dahulu?).

Ada masalah dengan kode Anda. Ini akan memungkinkan produk memiliki gambar default di mana gambar itu akan merujuk ke produk lain!

Untuk melarang kesalahan seperti itu, batasan FK Anda harus:

CONSTRAINT FK_products_1 
  FOREIGN KEY (id, default_picture_id) 
  REFERENCES products_pictures (product_id, id)
  ON DELETE RESTRICT                            --- the SET NULL options would 
  ON UPDATE RESTRICT                            --- lead to other issues

Ini akan membutuhkan UNIQUE kendala/indeks dalam tabel products_pictures di (product_id, id) agar FK di atas dapat didefinisikan dan berfungsi dengan baik.

Opsi 2

Pendekatan lain adalah menghapus Default_Picture_ID kolom membentuk product tabel dan tambahkan IsDefault BIT kolom di picture meja. Masalah dengan solusi ini adalah bagaimana mengizinkan hanya satu gambar per produk yang memiliki bit itu dan semua yang lain menonaktifkannya. Di SQL-Server (dan saya pikir di Postgres) ini dapat dilakukan dengan indeks parsial:

CREATE UNIQUE INDEX is_DefaultPicture 
  ON products_pictures (Product_ID)
  WHERE IsDefault = 1 ;

Tetapi MySQL tidak memiliki fitur seperti itu.

Opsi 3

Pendekatan ini, memungkinkan Anda untuk bahkan memiliki kedua kolom FK yang didefinisikan sebagai NOT NULL adalah dengan menggunakan batasan yang dapat ditangguhkan. Ini berfungsi di PostgreSQL dan saya pikir di Oracle. Periksa pertanyaan ini dan jawabannya oleh @Erwin: Batasan kunci asing yang rumit di SQLAlchemy (Semua kolom kunci BUKAN NULL Bagian).

Batasan di MySQL tidak dapat ditangguhkan.

Opsi 4

Pendekatannya (yang menurut saya paling bersih) adalah menghapus Default_Picture_ID kolom dan menambahkan tabel lain. Tidak ada jalur melingkar dalam batasan FK dan semua kolom FK akan menjadi NOT NULL dengan solusi ini:

product_default_picture
----------------------
product_id          NOT NULL
default_picture_id  NOT NULL
PRIMARY KEY (product_id)
FOREIGN KEY (product_id, default_picture_id)
  REFERENCES products_pictures (product_id, id)

Ini juga akan membutuhkan UNIQUE kendala/indeks dalam tabel products_pictures di (product_id, id) seperti pada solusi 1.

Untuk meringkas, dengan MySQL Anda memiliki dua opsi:

  • opsi 1 (kolom FK yang dapat dibatalkan) dengan koreksi di atas untuk menegakkan integritas dengan benar

  • opsi 4 (tidak ada kolom FK yang dapat dibatalkan)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pengantar tipe data MySQL

  2. MySQL Pesan sebelum Grup oleh

  3. Bagaimana cara menarik kembali kata sandi yang diasinkan dari Database dan pengguna auth?

  4. Kueri SQL:Hapus semua catatan dari tabel kecuali N terbaru?

  5. Cara Mengenkripsi Lalu Lintas Database Cloud Hibrida