Mysql
 sql >> база данни >  >> RDS >> Mysql

В SQL добре ли е две таблици да се отнасят една към друга?

Не, не е наред. Кръговите препратки между таблиците са разхвърляни. Вижте тази (стара десетилетие) статия: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 колони)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на MySQL релационни бази данни на Arch Linux

  2. MySQL, по-добре да вмъкнете NULL или празен низ?

  3. Въведение в SQL Joins

  4. Емулирайте MySQL LIMIT клауза в Microsoft SQL Server 2000

  5. Използване на SELECT INTO OUTFILE в MySQL