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)