【问题标题】:MySql Error 150 - Foreign keysMySql 错误 150 - 外键
【发布时间】:2010-10-23 22:42:34
【问题描述】:

当我执行以下两个查询时(我已将它们精简为绝对必要的):

mysql> CREATE TABLE foo(id INT PRIMARY KEY);
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE bar ( id INT, ref INT, FOREIGN KEY (ref) REFERENCES foo(id)) ENGINE InnoDB;

我收到以下错误: ERROR 1005 (HY000): 无法创建表 './test/bar.frm' (errno: 150)

我的错误在哪里?我盯着这个看了半个小时都没找到他。

【问题讨论】:

    标签: mysql foreign-keys mysql-error-150


    【解决方案1】:

    来自FOREIGN KEY Constraints

    如果您重新创建一个表 丢弃,它必须有一个定义 符合外键的 引用它的约束。它必须 具有正确的列名和类型, 它必须有索引 引用的键,如前所述。如果 这些不满足,MySQL返回 错误号 1005,指的是错误 150 在错误消息中。

    我的怀疑是因为您没有将foo 创建为 InnoDB,因为其他一切看起来都不错。

    编辑:来自同一页面 -

    两个表都必须是 InnoDB 表,并且不能是 TEMPORARY 表。

    【讨论】:

    • 一些快速测试,如上用 MyISAM 创建一个foo,用 InnoDB 创建一个bar,表明情况就是这样——尝试仔细检查你的表类型是否为foo
    • 即使两个表都是 InnoDB,我仍然遇到同样的问题。我通过在创建外键之前在引用表上创建索引来修复它。
    • 当我创建新表时,MySQL Workbench 6.3 似乎将引擎类型从 InnoDB 随机更改为 MyISAM 并没有帮助。
    【解决方案2】:

    我有同样的问题,对于那些也有这个问题的人:

    检查引用表的表名

    我忘记了表名末尾的“s”

    例如表客户端 --> 客户端

    :)

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,原因是列的“整理”不同。一个是latin1,另一个是utf8

      【讨论】:

        【解决方案4】:

        您可以使用命令SHOW ENGINE INNODB STATUS 获取有关错误的更多具体信息。

        它会给你一个包含大量文本的Status 列的结果。

        查找名为 LATEST FOREIGN KEY ERROR 的部分,例如可能如下所示:

        ------------------------
        LATEST FOREIGN KEY ERROR
        ------------------------
        190215 11:51:26 Error in foreign key constraint of table `mydb1`.`contacts`:
        Create  table `mydb1`.`contacts` with foreign key constraint failed. You have defined a SET NULL condition but column 'domain_id' is defined as NOT NULL in ' FOREIGN KEY (domain_id) REFERENCES domains (id) ON DELETE SET NULL ON UPDATE CASCADE,
            CONSTRAINT contacts_teams_id_fk FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE SET NULL ON UPDATE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT' near ' ON DELETE SET NULL ON UPDATE CASCADE,
            CONSTRAINT contacts_teams_id_fk FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE SET NULL ON UPDATE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT'.
        

        【讨论】:

        • 同意!它显示了“最后一个外键错误”部分,在我的情况下,它告诉我找不到外键约束的目标字段名称。这比纯粹的“错误 150”更有帮助;-)
        • 在我的情况下,我忘记将列设置为允许 NULL,并将 SET NULL 放在约束上。但我只是通过运行SHOW ENGINE INNODB STATUS 才发现原因
        • 这应该是最佳答案!尽管知道此查询的“状态”列输出中有一个 LATEST FOREIGN KEY ERROR 部分可能会有所帮助。正如@MarekStanley 也明确指出的那样。
        【解决方案5】:

        除了导致 MySql 错误 150 的许多其他原因(使用 InnoDB 时),可能的原因之一是表的创建语句中未定义的 KEY 包含作为外键引用的列名相对表。

        假设主表的create语句是-

        CREATE TABLE 'master_table' (
         'id' int(10) NOT NULL AUTO_INCREMENT,
         'record_id' char(10) NOT NULL,
         'name' varchar(50) NOT NULL DEFAULT '',
         'address' varchar(200) NOT NULL DEFAULT '',
         PRIMARY KEY ('id')
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        以及从主表设置外键约束的 relative_table 表的创建语法 -

        CREATE TABLE 'relative_table' (
         'id' int(10) NOT NULL AUTO_INCREMENT,
         'salary' int(10) NOT NULL DEFAULT '',
         'grade' char(2) NOT NULL DEFAULT '',
         'record_id' char(10) DEFAULT NULL,
         PRIMARY KEY ('id'),
         CONSTRAINT 'fk_slave_master' FOREIGN KEY ('record_id') REFERENCES 'master' ('record_id')
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        如果使用 InnoDB,这个脚本肯定会以 MySql 错误 150 结束。

        为了解决这个问题,我们需要在master_table 表中为record_id 列添加一个KEY,然后在relative_table 表中引用以用作foreign_key。

        最后,master_table 的创建语句将是 -

        CREATE TABLE 'master_table' (
         'id' int(10) NOT NULL AUTO_INCREMENT,
         'record_id' char(10) NOT NULL,
         'name' varchar(50) NOT NULL DEFAULT '',
         'address' varchar(200) NOT NULL DEFAULT '',
         PRIMARY KEY ('id'),
         KEY 'record_id' ('record_id')
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        【讨论】:

          【解决方案6】:

          要创建外键,

          1. 主列和引用列的定义必须相同。
          2. 两个表引擎都必须是 InnoDB。

          您可以使用此命令更改表的引擎,请在执行此命令之前进行备份。

          更改表 [表名] ENGINE=InnoDB;

          【讨论】:

          • “必须具有相同的定义”对我来说是相同的字符集编码
          • “必须具有相同的定义”对我来说是相同的列标志:我引用的现有主键是未签名的,所以我必须使我的新表的列也成为第一个外键
          【解决方案7】:

          如果您在“references”关键字后没有给出正确的列名,也可能发生这种情况。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-18
            • 2011-12-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多