我必须在mysql中创建一个包含2个表的数据库,但是脚本因errno 150(外键问题)而失败。我仔细检查了两个表上的外键字段是否相同,我找不到任何错误。
这是脚本:
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
DROP SCHEMA IF EXISTS `testdb`;
CREATE SCHEMA IF NOT EXISTS `testdb` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
USE `testdb`;
DROP TABLE IF EXISTS `testdb`.`table1` ;
CREATE TABLE IF NOT EXISTS `testdb`.`table1` (
`id` INT UNSIGNED NOT NULL ,
`field1` VARCHAR(50) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
DROP TABLE IF EXISTS `testdb`.`table2` ;
CREATE TABLE IF NOT EXISTS `testdb`.`table2` (
`id` INT NOT NULL AUTO_INCREMENT ,
`field1` VARCHAR(50) NULL ,
`date` DATE NULL ,
`cnt` INT NULL ,
PRIMARY KEY (`id`) ,
INDEX `FK_table2_table1` (`field1` ASC) ,
CONSTRAINT `FK_table2_table1`
FOREIGN KEY (`field1`)
REFERENCES `testdb`.`table1` (`field1` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
我在Windows和Ubuntu中使用不同版本的Mysql尝试过它并且无效。
有什么想法吗?非常感谢。
答案 0 :(得分:54)
table1.field1
没有定义索引。
需要在FOREIGN KEY
上设置field1
约束。
有了这个:
CREATE TABLE IF NOT EXISTS `testdb`.`table1` (
`id` INT UNSIGNED NOT NULL ,
`field1` VARCHAR(50) NULL ,
KEY ix_table1_field1 (field1),
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
然后一切都应该按预期工作。
答案 1 :(得分:50)
在使用MySQL Workbench和MySQL 5.5.27时,我遇到了类似的问题。在我的情况下,问题是INT类型字段。错误地在一个表中它是INT UNSIGNED并且在引用表中它是INT。
答案 2 :(得分:13)
根据MySQL的版本,您可能需要首先在table1.field1上创建索引。
答案 3 :(得分:8)
此处的答案之一建议禁用外键完整性检查。这是一个坏主意。这里有两个可能的罪魁祸首:
答案 4 :(得分:6)
另一个提示:
即使您的数据类型看起来相同 - 在我的情况下,两列都有VARCHAR(50)
- 这还不够。
您还需要确保两列具有相同的COLLATION
。
答案 5 :(得分:5)
选项(取决于具体情况)将禁用mysql完整性检查:
SET FOREIGN_KEY_CHECKS = 0;
答案 6 :(得分:5)
另一个原因,虽然与其他原因略有不同:我指的是一张表格,而不是InnoDB,而是指的是MyISAM引擎。
答案 7 :(得分:5)
如果您错误地引用了引用表的名称,MySQL也会抛出此错误。我把头发拉了一会儿,直到我意识到我错过了foreign key (column1) references mistyped_table(column1)
答案 8 :(得分:1)
如果无效,请尝试:
外键名称是已存在键的副本。检查外键的名称在数据库中是否唯一。只需在密钥名称的末尾添加一些随机字符即可对其进行测试。
答案 9 :(得分:0)
当我遇到这个问题时,是因为我将第一个表中的id设置为unsigned
,而第二个表中的外键不是。{让它们unsigned
为我修复它。
答案 10 :(得分:0)
如果您正在使用mysql工作台并且您为关系表得到此错误,可能会有一个快速修复:只需删除它并让mysql workbench为您重新创建它。然后复制sql。修复了我的错误150问题。
答案 11 :(得分:0)
在非常奇怪的情况下,您的数据库可能会被破坏。在我的情况下,我没有任何外键,只有重命名表或更改引擎帮助。
原来,innoDB被打破,请参阅:https://dba.stackexchange.com/questions/86853/1025-error-on-rename-of-table-errno-150-table-was-deleted-while-tried-to-a?lq=1
答案 12 :(得分:0)
在我的情况下,可能是服务器错误丢弃具有相同名称的表。 放弃整个shcema并重新创建它解决了这个问题。
答案 13 :(得分:0)
尝试引用外键中的复合键时,也可能会遇到相同的错误。
例如:
CREATE TABLE `article` (
`id` int(10) unsigned NOT NULL,
`type` enum('X','Y','Z') NOT NULL,
PRIMARY KEY (`id`,`type`)
) ENGINE InnoDB;
CREATE TABLE `t1` (
`user_id` int(10) unsigned NOT NULL,
`type` enum('X','Y','Z') NOT NULL,
`article_id` int(10) unsigned NOT NULL,
CONSTRAINT `user_access_article_ibfk_2` FOREIGN KEY (`article_id`, `type`) REFERENCES `article` (`id`, `type`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
在这种情况下,重要的是在FK定义中使用article_id和type字段的顺序与它们在文章表PRIMARY KEY定义中出现的顺序完全相同。
答案 14 :(得分:0)
对我来说,问题是在CONSTRAINT
查询中使用CREATE TABLE
。
答案 15 :(得分:0)
在我的情况下,我在其中一个表中得到了旧表定义MyISAM,显然我无法从另一个表中创建外键。也许这有助于某人。
所以这可能是因为两个数据库/字段定义之间的不一致,试图检查:
Field Type
Field Collation
Table Engine
答案 16 :(得分:0)
我的一张桌子上有类似的错误。当选中列Collation不同时,一次将两列更改为相同的Collation类型。
在这里阅读了大部分建议的解决方案。我只是认为如果我只列出可能引发此错误的所有可能性,这可能会有所帮助。
1,检查列的CASE 2,检查列的COLLATION 3,检查是否在列的两个表中创建了一个密钥(唯一,主要)
答案 17 :(得分:0)
首先创建主/父表,然后创建详细/子表。
答案 18 :(得分:0)
我正在使用MySQL workBench
。问题是你不能使用相同的foreign key name
,它们必须是unique
。因此,如果多个表将引用相同的外键,则每次必须提供unique
名称。
答案 19 :(得分:0)
如果有人仍然遇到此问题,我尝试了上面的所有解决方案(SET FOREIGN_KEY_CHECKS除外)并没有任何效果。问题是,当您引用第一个表时,某些数据库对表名称区分大小写。我认为这很奇怪,因为我之前从未在MySQL,Oracle上看过这个,现在我在MariaDB上发生了这种情况。
例如:
如果不存在则创建表CADASTRO_MAQUINAS( Id VARCHAR(16), 主键(Id) );
创建表格(如果不存在)INFOS( Id_Maquina VARCHAR(16)NOT NULL, CONSTRAINT FK_infos_cadastro_maquinas外键(Id_Maquina)引用CADASTRO_MAQUINAS(Id) );
如果我尝试使用cadastro_maquinas(小写)而不是CADASTRO_MAQUINAS创建第二个表,我将收到此错误。
答案 20 :(得分:0)
就我而言,一个表在另一个尚不存在的表上使用外键约束。这是由于一个大的makefile而发生的,所以它并不像我预期的那么明显。