MySQL utf8mb4 外键错误

标签 mysql sql database

几天前,我们将数据库从 utf8 迁移到 utf8mb4。由于迁移,我们的大多数主键都从 VARCHAR(255) 更新为 VARCHAR(191),因为每个字符都有额外的字节数。

问题是现在我们不能在引用现有表的新表上添加新的外键。我们在 MySQL Workbench 中收到以下错误:

"Referenced table has no candidate columns with a compatible type for table.id. Hint: source column has type VARCHAR(191), PK of referenced table is VARCHAR(191)."

如果我们尝试通过控制台添加外键,我们会得到:

最新的外键错误

2014-02-13 10:27:51 126bb3000 Error in foreign key constraint of table table/#sql-159_2b2: foreign key (fk_id) references table (id): Cannot find an index in the referenced table where the referenced columns appear as the first columns, or column types in the table and the referenced table do not match for constraint.

但是,正如您在报告的错误中看到的那样,这两种类型都被定义为 VARCHAR(191)

我们缺少什么?

最佳答案

找到问题和解决方案。似乎 MYSQL 在使用 utf8mb4 时在排序规则内进行比较时出现了一些问题。

假设您的 MYSQL 服务器使用 utf8mb4 作为默认排序规则,这意味着任何新表都将继承该排序规则作为它们的默认排序规则。

如果我们要创建一个新表,我们称它为 A,表 A 的排序规则为 utf8mb4 - 默认排序规则(继承自 DB 默认值)。如果您想从 A 中的 p 列(其排序规则为“Table Default”,应该为“utf8mb4 - 默认排序规则”)到表 B 的 x 列创建一个外键,其中 B 具有相同的排序规则:utf8mb4 - 默认排序规则但是x 列的排序规则为 utf8mb4_unicode_ci 你会得到问题中的错误:

Referenced table has no candidate columns with a compatible type for table.id. Hint: source column has type VARCHAR(191), PK of referenced table is VARCHAR(191).

因此,如果您有索引并且类型相同,则错误是因为列排序规则不匹配。

为了解决这个问题,我必须显式地更改列 p 以使用与引用列相同的排序规则:

ALTER TABLE `database`.`A` CHARACTER SET = utf8mb4 ;
ALTER TABLE `database`.`A` CHANGE COLUMN `p` `p` VARCHAR(191) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci' NOT NULL  

然后添加外键就像一个魅力:

ALTER TABLE `database`.`A` 
ADD CONSTRAINT `FKD84ACC0C2200B55`
FOREIGN KEY (`p` )
REFERENCES `database`.`B` (`x` )
ON DELETE CASCADE
ON UPDATE CASCADE;

关于MySQL utf8mb4 外键错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21760128/

相关文章:

mysql - 使用 case 语句更新查询,给出缺少关键字错误

c# - 在 Nhibernate 中创建查询 "sum"多列

php - 数据库结构,Eav模型,搜索查询太慢

database - Golang 不使用数据库

php - 如何将变量作为字符串保存在数据库中?

php - Socket.io私信通知

mysql - 当 'IN' 条件的所有值都没有结果时,SQL 选择默认值

sql - 分组连续行

mysql - 为什么 SQL 查询不更新特定行

SQL根据case语句部分更新列?