我需要向表中添加复合外键,该表的 struct 如下所示

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`);

有位置id综合指数.我可以分别为location_id和server_id创建FK,这样列类型和范围应该是正确的.

我想运行alter table,它应该添加

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;

这给了我一个错误:General error: 1215 Cannot add foreign key constraint

有人知道问题出在哪里吗.

推荐答案

必须按照列在引用表的键中的顺序列出外键约束中的列.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;

键和约束中的列顺序不需要与表定义中的列顺序匹配.

Mysql相关问答推荐

筛选器中的Case When语句

MySQL将JSON值从对象类型更改为数组

透视从另一个表添加信息的查询

MySQL 搜索列字段字符串

WordPress的sql命令从帖子中删除随机文本

从单行中获取最大日期的最佳方法

为生日创建 MySQL 索引

谁能帮我优化where子句

MySQL 中的 LATERAL 语法 - 是否只是说左表首先执行以便下一个可以引用它?

如何从将分钟、天、月和年存储在不同列中的表中查询数据

非常规字符的不正确字符串值错误

mysql 5.5;可以从记录中排除表吗?

如何使用 C++ 连接 mySQL 数据库

如何使主键从 1000 开始?

有什么方法可以显示`gunzip < database.sql.gz | 的进度? mysql ...`进程?

MySQL:按字段排序,将空单元格放在末尾

MySQL术语约束与外键的区别?

如何将具有相同列值的mysql行分组为一行?

从另一个表中 Select 具有 id 的行

mysql错误'TYPE = MyISAM'