MySQL — несколько внешних ключей, которые действительны только для отдельных проверочных ограничений

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

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

Я буду использовать тип элемента ('Действие' или «Риск») в своем проверочном ограничении, чтобы определить, на какую таблицу я ссылаюсь.

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

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?

MySQL вообще не реализует ограничения CHECK.

Barmar 10.04.2019 23:35

Упс, это уже не так, 8.0.16 их добавляет.

Barmar 10.04.2019 23:36

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

Vahe Jabagchourian 10.04.2019 23:37

Однако проверочные ограничения имеют ряд ограничений. Вы не можете выполнить в них подзапрос, поэтому это предотвращает использование CHECK для проверки внешнего ключа. Невозможно сделать внешние ключи условными.

Barmar 10.04.2019 23:40

Поэтому используйте триггер или хранимую процедуру.

Barmar 10.04.2019 23:40
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
5
1 031
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Если вам нужно сослаться на одну из нескольких родительских таблиц, один из способов сделать это — создать несколько столбцов, каждый из которых допускает значение 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)
);

Смотрите также:

Спасибо или разъяснение фактического метода, по имени, я ориентируюсь здесь.

Vahe Jabagchourian 10.04.2019 23:59

Привет, хорошо ли иметь два внешних ключа, один из которых может быть нулевым?

Arash 05.09.2021 15:48

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

Bill Karwin 05.09.2021 18:15

Спасибо, @Билл. Извините, я не силен в английском; Я плохо задавал вопросы. Я имел в виду в один ряд. Это хорошая практика или я должен изменить дизайн своих таблиц?

Arash 05.09.2021 18:44

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

Bill Karwin 05.09.2021 20:52

Другие вопросы по теме