Не, не е наред. Кръговите препратки между таблиците са разхвърляни. Вижте тази (стара десетилетие) статия:SQL By Design:The Circular Reference
Някои СУБД могат да се справят с тях и то със специално внимание, но MySQL ще има проблеми.
Опция 1
Като ваш дизайн, за да направите един от двата FK нулеви. Това ви позволява да решите проблема с пилето и яйцето (в коя маса първо да вмъкна?).
Има обаче проблем с вашия код. Това ще позволи на продукт да има картина по подразбиране, където тази снимка ще препраща към друг продукт!
За да забраните такава грешка, вашето FK ограничение трябва да бъде:
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
Това ще изисква UNIQUE
ограничение/индекс в таблица products_pictures
на (product_id, id)
за да бъде дефиниран и работи правилно горният FK.
Вариант 2
Друг подход е да премахнете Default_Picture_ID
колона от product
таблица и добавете IsDefault BIT
колона в picture
маса. Проблемът с това решение е как да позволите само на една снимка на продукт да има този бит, а всички други да го изключват. В SQL-Server (и мисля, че в Postgres) това може да се направи с частичен индекс:
CREATE UNIQUE INDEX is_DefaultPicture
ON products_pictures (Product_ID)
WHERE IsDefault = 1 ;
Но MySQL няма такава функция.
Вариант 3
Този подход ви позволява дори да имате и двете FK колони, дефинирани като NOT NULL
е да се използват отлагаеми ограничения. Това работи в PostgreSQL и мисля в Oracle. Проверете този въпрос и отговора от @Erwin:Сложно ограничение на външния ключ в SQLAlchemy
(Всички ключови колони НЕ СА NULL Част).
Ограниченията в MySQL не могат да бъдат отложени.
Вариант 4
Подходът (който намирам за най-чист) е да премахнете Default_Picture_ID
колона и добавете друга таблица. Няма кръгов път в ограниченията на FK и всички FK колони ще бъдат NOT NULL
с това решение:
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)
Това също ще изисква UNIQUE
ограничение/индекс в таблица products_pictures
на (product_id, id)
както в решение 1.
За да обобщим, с MySQL имате две възможности:
-
опция 1 (колона FK с нула) с корекцията по-горе, за да се наложи правилно целостта
-
опция 4 (без нулеви FK колони)