MySQL - несколько внешних ключей, которые действительны только для отдельных проверочных ограничений - PullRequest
1 голос
/ 10 апреля 2019

Заголовок говорит в значительной степени о том, что мне нужно, но я хочу посмотреть, как я могу взять два ограничения внешнего ключа из таблицы и два проверочных ограничения и связать одно проверочное ограничение, связывая второе проверочное ограничение со вторым ограничением внешнего ключа.

Например, у меня есть две таблицы 3, item, action, risk. Item ссылки action или risk, itemid Только я хочу условные ссылки на более чем один внешний ключ с каждым внешним ключом, имеющим одно уникальное проверочное ограничение .

Я буду использовать itemtype ( 'Action' или 'Risk' ) в моем проверочном ограничении, чтобы определить, на какую таблицу я ссылаюсь.

Вот моя команда:

ALTER TABLE `projectaim`.`items`  
              ADD CONSTRAINT `fk_item_risk` FOREIGN KEY (`ItemID`) REFERENCES `projectaim`.`risks`(`RiskID`)
ADD CONSTRAINT ck_item_type CHECK (itemtype = 'Risk') 

Это вообще возможно в MySQL?

1 Ответ

1 голос
/ 11 апреля 2019

Похоже, вы пытаетесь реализовать , где заданный столбец может быть идентификатором, ссылающимся на любую из нескольких родительских таблиц.

Ограничение внешнего ключа ссылается на одного из родителейТаблица.Вы не можете сделать это условным.Вот почему полиморфные ассоциации принципиально не совместимы с реляционными ограничениями.

Если вам нужно сослаться на одну из нескольких родительских таблиц, один из способов сделать это - создать несколько столбцов, каждый из которых может иметь значение NULL.Затем вы можете использовать проверочное ограничение или триггер, чтобы убедиться, что ровно один из них не равен нулю.

CREATE TABLE items (
  Itemid INT NOT NULL PRIMARY KEY,
  Itemtype ENUM ('Action', 'Risk') NOT NULL,
  Actionid INT NULL,
  Riskid INT NULL,
  FOREIGN KEY (Actionid) REFERENCES actions (Actionid),
  FOREIGN KEY (Riskid) REFERENCES risks (riskid),
  CHECK (CASE Itemtype
         WHEN 'Action' THEN Actionid IS NOT NULL AND Riskid IS NULL
         WHEN 'Risk' THEN Riskid IS NOT NULL AND Actionid IS NULL
         END)
);

См. Также:

...