【问题标题】:Add Foreign Key to existing table将外键添加到现有表
【发布时间】:2012-04-19 04:04:59
【问题描述】:

我想将外键添加到名为“katalog”的表中。

ALTER TABLE katalog 
ADD CONSTRAINT `fk_katalog_sprache` 
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

当我尝试这样做时,我收到以下错误消息:

Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)

INNODB 状态错误:

120405 14:02:57 表外键约束出错 mytable.#sql-7fb1_7d3a:

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL

当我使用此查询时,它可以工作,但“删除时”操作错误:

ALTER TABLE `katalog` 
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )

两个表都是 InnoDB,两个字段都是“INT(11) not null”。我正在使用 MySQL 5.1.61。尝试在 MacBook Pro 上使用 MySQL Workbench(最新)触发此 ALTER 查询。

表创建语句:

CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
 ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$

CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
 `Bezeichnung` varchar(45) NOT NULL,
 PRIMARY KEY (`ID`),
 UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

【问题讨论】:

  • 既然你没有发布SHOW CREATE TABLE的输出,我只能问——列名真的是ID,大写吗?
  • 嗯,现在更容易发现 - katalogint(11) unsignedsprache 没有 usigned 部分,因此两列不一样。
  • 你的意思是,两个主字段必须是相同的数据类型?
  • 这是您设计的问题:首先,您引用了两个 auto_increment 列,这很糟糕。此外,MySQL 手册说:Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.。因此,是的,相似数据类型和符号相同。
  • 我没有引用两个 auto_increment 字段。 katalog.Sprache(非自动)-> sprache.ID(自动)

标签: mysql foreign-keys


【解决方案1】:

当您使用 ALTER TABLE 向表添加外键约束时,请记住首先创建所需的索引。

  1. 创建索引
  2. 更改表

【讨论】:

  • 我为两者创建了索引。当我尝试运行时,我收到与以前相同的错误消息。当我拒绝“更新时删除”部分时,它可以工作,但“删除时”操作错误;)
  • @frgtv10 表数据最有可能与“删除时”发生冲突。
【解决方案2】:

检查此链接。它帮助我解决了 errno 150: http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

在我的脑海中浮现出两件事。

  • 您的外键索引在整个数据库中是唯一的名称(列表中的#3)吗?
  • 您是否尝试在更新时将表 PK 设置为 NULL(列表中的 #5)?

我猜问题出在更新时设置为 NULL(如果我的大脑今天没有像往常那样倒退的话……)。

编辑:我错过了您原始帖子中的 cmets。 Unsigned/not unsigned int 列可能会解决您的问题。希望我的链接对以后的想法有所帮助。

【讨论】:

    【解决方案3】:

    要将外键 (grade_id) 添加到现有表(用户),请执行以下步骤:

    ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
    ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);
    

    【讨论】:

    • 原因帮助我理解和记住。这是因为您不能将外键添加到非无符号字段,对吗?
    • @PixMach,答案是否定的。您可以将有符号整数作为外键。作为 N.B.在问题上注明,字段的类型和符号需要匹配。因此,如果查找表中的主键是 UNSIGNED,那么外键字段也必须是 UNSIGNED。如果主键字段是签名的,那么外键字段也必须签名。可以这样想:无论一个表中的列在 SHOW CREATE TABLE 中如何定义,它都需要在另一个表中具有相同的定义。
    • 请注意,这也可以通过单个查询来完成(在失败等情况下可能会更好)
    • 我必须运行“SET FOREIGN_KEY_CHECKS=0;”在运行 ADD CONSTRAINT 命令或 SQL 之前会报错“无法添加或更新子行:外键约束失败”。
    • 不要不要只运行“SET FOREIGN_KEY_CHECKS=0;”如果您收到错误“外键约束失败”,则显然您有必须修复的错误数据,否则您将遇到更大的问题。
    【解决方案4】:
    FOREIGN KEY (`Sprache`)
    REFERENCES `Sprache` (`ID`)
    ON DELETE SET NULL
    ON UPDATE SET NULL;
    

    但是你的桌子有:

    CREATE TABLE `katalog` (
    `Sprache` int(11) NOT NULL,
    

    不能将 Sprache 列设置为 NULL,因为它被定义为 NOT NULL。

    【讨论】:

      【解决方案5】:

      只需使用此查询,我已根据我的场景尝试过,效果很好

      ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);
      

      【讨论】:

        【解决方案6】:

        在一个查询中尝试所有内容

          ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
              ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);
        

        【讨论】:

          【解决方案7】:

          简单的步骤...

          ALTER TABLE t_name1 ADD FOREIGN KEY (column_name) REFERENCES t_name2(column_name)
          

          【讨论】:

            【解决方案8】:

            MySQL 将执行此查询:

            ALTER TABLE `db`.`table1`
            ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
            ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
            ADD CONSTRAINT `col_table2_fk1`
            FOREIGN KEY (`col_table2_fk`)
            REFERENCES `db`.`table2` (`table2_id`)
            ON DELETE NO ACTION
            ON UPDATE NO ACTION;
            

            干杯!

            【讨论】:

              【解决方案9】:

              如何修复Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

              1. 更改您的表格并为其添加索引..

                ALTER TABLE users ADD INDEX index_name (index_column)
                
              2. 现在添加约束

                ALTER TABLE foreign_key_table
                ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
                REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
                ON UPDATE CASCADE;
                

              请注意,如果您不添加索引,它将无法正常工作。

              在与它战斗了大约 6 个小时后,我想出了解决方案 我希望这能拯救一个灵魂。

              【讨论】:

                【解决方案10】:
                 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)
                

                例子:-

                ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)
                

                【讨论】:

                • 请在您的代码中添加一些解释,以便其他人可以从中学习
                【解决方案11】:

                这基本上是因为您的表位于两个不同的字符集中。例如,在 charset=utf-8 中创建的一个表和在 CHARSET=latin1 中创建的其他表,因此您希望能够为这些表添加外键。在两个表中使用相同的字符集,那么您将能够添加外键。错误 1005 外键约束格式不正确可以从此解决

                【讨论】:

                  【解决方案12】:

                  我遇到了同样的问题。在我的情况下,该表已经有数据,并且该表中存在参考表中不存在的键。所以我不得不删除这些不尊重约束并且一切正常的行。

                  【讨论】:

                    【解决方案13】:

                    第 1 步:运行此脚本

                    SET FOREIGN_KEY_CHECKS=0;
                    

                    第 2 步:添加列

                    ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL
                    

                    第 3 步:将外键添加到添加的列中

                    ALTER TABLE mileage_unit
                    ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);
                    

                    第 4 步:运行此脚本

                    SET FOREIGN_KEY_CHECKS=1;
                    

                    【讨论】:

                      【解决方案14】:

                      外键约束必须与引用表和列中的主键数据类型相同

                      【讨论】:

                        【解决方案15】:

                        仔细检查两个表的enginecharset 是否相同。

                        如果没有,它会显示这个错误。

                        【讨论】:

                          猜你喜欢
                          • 2014-02-20
                          • 1970-01-01
                          • 2013-07-13
                          • 2014-01-15
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-05-10
                          • 1970-01-01
                          相关资源
                          最近更新 更多