【问题标题】:Foreign key rejected despite columns having different data types尽管列具有不同的数据类型,但外键被拒绝
【发布时间】:2020-07-24 18:43:35
【问题描述】:

我正在尝试在数据库中设置两个表,并在它们之间添加一个外键。它们声明如下:

CREATE TABLE `clothing` (
  `name` varchar(26) COLLATE utf8_bin NOT NULL,
  `image` varchar(64) COLLATE utf8_bin NOT NULL,
  `localized_name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`localized_name`)),
  `main` varchar(18) COLLATE utf8_bin DEFAULT NULL,
  `stars` tinyint(3) unsigned NOT NULL,
  `id` tinyint(3) unsigned NOT NULL,
  `splatnet` smallint(5) unsigned NOT NULL,
  PRIMARY KEY (`splatnet`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `abilities` (
  `name` varchar(18) COLLATE utf8_bin DEFAULT NULL,
  `image` varchar(48) COLLATE utf8_bin NOT NULL,
  `id` tinyint(3) unsigned NOT NULL,
  `localized_name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`localized_name`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

我想使用以下命令在 clothing 上创建一个引用 abilities 的外键:

ALTER TABLE `abilities` ADD FOREIGN KEY (`name`) REFERENCES `clothing` (`main`);

但是,尝试这样做会引发此错误:

Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.
Can't create table `prismarine_rusted`.`abilities` (errno: 150 "Foreign key constraint is incorrectly formed")

我不完全确定是什么原因造成的,除非我忽略了一些真正明显的东西,mainname 具有相同的类型,因此应该能够通过外键绑定在一起。我使用的是 MariaDB v10.4.12,SQL 模式设置为TRADITIONAL

【问题讨论】:

    标签: mysql sql mariadb


    【解决方案1】:

    虽然这里涉及的外键列和主键列是同一类型,但您试图引用clothing.main,它不是唯一或主键列。来自 MariaDB documentation

    引用的列必须是 PRIMARY KEY 或 UNIQUE 索引。

    请注意,这与 MySQL 上的 InnoDB 不同,其中外键列实际上可以引用另一个表中的非唯一列。

    纠正此错误的一种方法是将clothing.main 设为唯一列:

    ALTER TABLE clothing ADD UNIQUE (main);
    

    请注意,只有在 main 中的值已经是唯一的情况下,这样做才合乎逻辑。如果不是,那么您可能需要重新审视您的数据模型。

    【讨论】:

    • 更不用说错误消息甚至说必须对列进行索引。
    • @Powerlord 我记得你from this question.
    【解决方案2】:

    这可能是因为abilities.name 中有一个值在引用的表中不匹配。

    【讨论】:

      猜你喜欢
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多