Как создать составной внешний ключ в Mysql

Мне нужно добавить составной внешний ключ в таблицу, структура которой выглядит так

CREATE TABLE IF NOT EXISTS `discount_month_devices` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `discount_month_id` int(11) UNSIGNED NOT NULL,
  `global_device_id` int(11) DEFAULT NULL,
  `location_id` int(11) UNSIGNED DEFAULT NULL,
  `server_id` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `discount_month_id` (`discount_month_id`),
  KEY `global_device_id` (`global_device_id`),
  KEY `location_id` (`location_id`,`server_id`),
  KEY `server_id` (`server_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Таблица устройств DDL выглядит так

CREATE TABLE IF NOT EXISTS `devices` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `server_id` varchar(20) CHARACTER SET utf8mb4 NOT NULL,
  `device_id` int(11) DEFAULT NULL,
  `location_id` int(11) UNSIGNED DEFAULT NULL,
  `device_lat` float DEFAULT NULL,
  `device_long` float DEFAULT NULL,
   ....
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `devices_idx1` (`server_id`,`device_id`) USING BTREE,
  KEY `devices_idx5` (`server_id`) USING BTREE,
  KEY `devices_idx6` (`device_id`) USING BTREE,
  KEY `devices_idx8` (`server_id`,`owner_id`) USING BTREE,
  KEY `server_id` (`server_id`,`location_id`),
  KEY `devices_idx14` (`location_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1583586 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

ALTER TABLE `devices`
  ADD CONSTRAINT `devices_fk1` FOREIGN KEY (`server_id`,`location_id`) REFERENCES `locations` (`server_id`, `location_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `devices_fk2` FOREIGN KEY (`discount_month_id`) REFERENCES `discount_month` (`id`);

Есть составной индекс location_id. Я могу создать FK для location_id и server_id отдельно, поэтому типы и диапазоны столбцов должны быть правильными.

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

ALTER TABLE `discount_month_devices` ADD CONSTRAINT `discount_month_devices_fk3` 
FOREIGN KEY (`location_id`, `server_id`) REFERENCES `devices`(`location_id`, `server_id`) 
ON DELETE CASCADE ON UPDATE CASCADE;

Это выдает мне ошибку: Общая ошибка: 1215 Невозможно добавить ограничение внешнего ключа

Может кто знает в чем может быть проблема.

Можете ли вы добавить таблицу DDL устройств к вопросу?

pringi 16.03.2022 15:21

Да, я добавлю.

Čamo 16.03.2022 15:31

DDL для таблицы устройств есть.

Čamo 16.03.2022 15:36
Освоение архитектуры микросервисов с 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
3
42
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы должны перечислить столбцы в ограничении внешнего ключа в том же порядке, в котором они появляются в ключе в таблице, на которую ссылаются. Ваш ключ в devices включен (server_id, location_id), но вы пытались сослаться на них в своем ограничении внешнего ключа как (location_id, server_id).

Попробуй это:

ALTER TABLE `discount_month_devices` 
  ADD CONSTRAINT `discount_month_devices_fk3` 
  FOREIGN KEY (`server_id`, `location_id`) 
  REFERENCES `devices`(`server_id`, `location_id`)
  ON DELETE CASCADE ON UPDATE CASCADE;

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

Да, ты прав. Большое спасибо.

Čamo 16.03.2022 17:06

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