将外键添加到现有表


324

我想将外键添加到名为“ 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 Query。

表创建语句:

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

1
由于您没有发布的输出SHOW CREATE TABLE,所以我只能问-列名是否真的是ID,大写?
NB

嗯,这是现在更容易被发现- katalogint(11) unsignedsprache没有该usigned部分,因此两列不相同。
NB 2012年

您是说两个“主”字段都必须是相同的数据类型吗?
frgtv10 2012年

2
这是您设计的问题:首先,您要引用两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.。因此,是的,数据类型相似且符号相同。
NB 2012年

2
我没有引用两个auto_increment字段。katalog.Sprache(非自动)-> sprache.ID(自动)
frgtv10'4

Answers:


559

要将外键(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);

12
原因可以帮助我理解和记住。这是因为您不能将外键添加到未签名的字段中,对吗?
PixMach

8
@PixMach,答案是否定的。您可以将带符号的整数作为外键。正如NB在问题上指出的那样,字段的类型和符号必须匹配。因此,如果您在查找表中的主键是UNSIGNED,则外键字段也必须是UNSIGNED。如果主键字段是SIGNED,则外键字段也必须被签名。这样想:无论一个表中的列是如SHOW CREATE TABLE中定义的,它都需要在另一个表中具有相同的定义。
本·基恩

1
请注意,这也可以通过单个查询来完成(在发生故障等情况下可能会更好)
Stijn de Witt

6
我必须运行“ SET FOREIGN_KEY_CHECKS = 0;” 在运行ADD CONSTRAINT命令或SQL之前,它将抱怨“无法添加或更新子行:外键约束失败”。
艾琳·盖尔

2
不要只是运行“SET FOREIGN_KEY_CHECKS = 0;” 如果出现错误“外键约束失败”,则显然您必须修复错误的数据,否则将遇到更大的问题。
MazeChaZer

72

只需使用此查询,我就根据自己的情况进行了尝试,并且效果很好

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

25

简单步骤...

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

15

检查此链接。它帮助我解决了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(如果今天我的大脑不像往常那样倒退……)。

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


13
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

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;

干杯!


5

怎么修 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个小时之后,我想出了解决方案,希望这能拯救一个灵魂。


4

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

  1. 创建索引
  2. 修改表

我为两者创建了索引。当我尝试运行时,我得到与以前相同的错误消息。当我否认“在更新时删除”部分时,它起作用,但使用了“在删除时”操作错误;)
frgtv10 2012年

@ frgtv10最有可能与“删除时”表数据冲突。
Maksym Polshcha '04年

3

一站式尝试

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

0

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


0

我遇到了同样的问题。我的情况是该表已经有数据,并且该表中的键在引用表中不存在。所以我不得不删除不遵守约束条件的行,并且一切正常。


0

步骤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;

-1
 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)

例:-

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

1
请为您的代码添加一些解释,以便其他人可以从中学习
Nico Haase
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.