在填充的数据库中进行正向工程某些新关系失败(errno 150)

尼克·扎菲里迪斯(Nick Zafiridis)

这是另一个错误1005,在创建表线程上出现错误errno 150。我见过很多,但没有一个能回答我的问题。

我在mysql工作台中有一个数据库,该数据库是前向设计的,并充满了数据。然后,从模型视图创建一个新表。然后,在此新表和数据库中的现有表之间添加一个:m关系。

最后,我尝试同步数据库。为创建两个新表而生成的代码是:

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,ALLOW_INVALID_DATES';

CREATE TABLE IF NOT EXISTS `mydb`.`SEntences` (
  `idSEntences` INT(11) NOT NULL,
  PRIMARY KEY (`idSEntences`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1
COLLATE = latin1_bin;

CREATE TABLE IF NOT EXISTS `mydb`.`Tips_has_SEntences` (
  `Tips_idTips` VARCHAR(45) NOT NULL,
  `SEntences_idSEntences` INT(11) NOT NULL,
  PRIMARY KEY (`Tips_idTips`, `SEntences_idSEntences`),
  INDEX `fk_Tips_has_SEntences_SEntences1_idx` (`SEntences_idSEntences` ASC),
  INDEX `fk_Tips_has_SEntences_Tips1_idx` (`Tips_idTips` ASC),
  CONSTRAINT `fk_Tips_has_SEntences_Tips1`
    FOREIGN KEY (`Tips_idTips`)
    REFERENCES `mydb`.`Tips` (`idTips`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Tips_has_SEntences_SEntences1`
    FOREIGN KEY (`SEntences_idSEntences`)
    REFERENCES `mydb`.`SEntences` (`idSEntences`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1
COLLATE = latin1_bin;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

使用此日志,我得到一个错误:

Executing SQL script in server
ERROR: Error 1005: Can't create table 'mydb.Tips_has_SEntences' (errno: 150)


CREATE TABLE IF NOT EXISTS `mydb`.`Tips_has_SEntences` (
  `Tips_idTips` VARCHAR(45) NOT NULL,
  `SEntences_idSEntences` INT(11) NOT NULL,
  PRIMARY KEY (`Tips_idTips`, `SEntences_idSEntences`),
  INDEX `fk_Tips_has_SEntences_SEntences1_idx` (`SEntences_idSEntences` ASC),
  INDEX `fk_Tips_has_SEntences_Tips1_idx` (`Tips_idTips` ASC),
  CONSTRAINT `fk_Tips_has_SEntences_Tips1`
    FOREIGN KEY (`Tips_idTips`)
    REFERENCES `mydb`.`Tips` (`idTips`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Tips_has_SEntences_SEntences1`
    FOREIGN KEY (`SEntences_idSEntences`)
    REFERENCES `mydb`.`SEntences` (`idSEntences`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1
COLLATE = latin1_bin

SQL script execution finished: statements: 3 succeeded, 1 failed

Fetching back view definitions in final form.
Nothing to fetch

使用SHOW ENGINE INNODB STATUS \ G命令从终端运行mysql,我从最近的外键错误字段获得以下输出:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
141007 14:18:53 Error in foreign key constraint of table mydb/Tips_has_SEntences:

    FOREIGN KEY (`Tips_idTips`)
    REFERENCES `mydb`.`Tips` (`idTips`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Tips_has_SEntences_SEntences1`
    FOREIGN KEY (`SEntences_idSEntences`)
    REFERENCES `mydb`.`SEntences` (`idSEntences`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1
COLLATE = latin1_bin:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.

在研究了我的问题之后,我无法弄清楚出了什么问题。所有数据类型都是相同的,外键在主键上(主键上有主索引)等等。我研究了此错误的各种堆栈溢出答案,并查看了此页面,并链接其中一个:MySQL错误号1005不能创建表'。\ mydb#sql-328_45.frm'(errno:150)我已进行了尽可能详尽的搜索,但答案仍然在那里。在这种情况下,我很抱歉。

也许它与旧表(提示)中已经有数据的事实有关。同步一个1:n关系,这在旧表(提示)中添加了一个外键,尽管很奇怪。如果数据是问题,那将行不通,正如我在这篇文章中发现的:如何向MySQL表添加外键?

另一方面,添加1:n关系(这需要将旧表的外键(提示)添加到新表)会产生相同的错误和日志(除了引用这样的表之外: 。\ mydb#sql-328_45.frm')。

我应该注意,这些问题对于我的任何旧表(数据库中已有数据的表)都会发生。另外,我相当确定在用数据填充数据库之后,在继续填充数据库之前以及尝试添加这些新表之前,我更新了mysql工作台。现在是第6版,可以在Linux的kubuntu中运行。

这里有什么问题,如何解决?是否走到了极限,例如导出数据库,删除和导入数据库是唯一的方法?即使在这种情况下,我该怎么办?请记住,这是一个包含许多数据条目的数据库,大约100000。

如果您需要更多信息,我将在这里提供。

提示表创建代码:

SHOW CREATE TABLE mydb.Tips;

CREATE TABLE `Tips` (
  `idTips` varchar(45) CHARACTER SET latin1 NOT NULL,
  `like_count` int(10) unsigned DEFAULT NULL,
  `text` longtext CHARACTER SET latin1,
  `created_at` bigint(19) unsigned DEFAULT NULL,
  `url` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `todo_count` bigint(19) unsigned DEFAULT NULL,
  `save_count` bigint(19) unsigned DEFAULT NULL,
  `Venues_idVenues` varchar(45) CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`idTips`),
  KEY `fk_Tips_Venues1` (`Venues_idVenues`),
  CONSTRAINT `fk_Tips_Venues1` FOREIGN KEY (`Venues_idVenues`) REFERENCES `Venues` (`idVenues`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
用户名

tl; dr

恕我直言,您需要同步Tips.idTips列和Tips_has_SEntences.Tips_idTips的定义

特别是各列的字符集和排序规则不对应。

解析度

因此,在代码中,请执行以下操作之一:

  • 明确定义字符集或Tips_has_SEntences.Tips_idTips列的排序规则

    `Tips_idTips` VARCHAR(45) CHARACTER SET latin1 NOT NULL,
    

    或者

    `Tips_idTips` VARCHAR(45) COLLATE latin1_swedish_ci NOT NULL,
    
  • 将显式默认排序规则放到Tips_has_SEntences表上。

    COLLATE = latin1_bin -- remove this section
    
  • Tips.idTips上删除显式字符集定义

    `idTips` varchar(45) NOT NULL,
    
  • latin1_binTips.idTips指定排序规则

    `idTips` varchar(45) COLLATE latin1_bin NOT NULL,
    

请注意:如果使用ALTER TABLE查询时,“ to”和“ from”字符集不兼容,则后两个选项可能会导致数据丢失
您应该很安全,因为latin1_binlatin1_swedish_ci归类使用相同的字符集(latin1)。

解释

实验

当我在Tips_has_SEntences CREATE TABLE语句中禁用麻烦的外键时

--  CONSTRAINT `fk_Tips_has_SEntences_Tips1`
--    FOREIGN KEY (`Tips_idTips`)
--    REFERENCES `mydb`.`Tips` (`idTips`)
--    ON DELETE NO ACTION
--    ON UPDATE NO ACTION,

运行查询并SHOW CREATE TABLETipsTips_has_SEntences表上进行操作,我发现外键耦合的两列的定义有所不同。

    ...
    `idTips` varchar(45) CHARACTER SET latin1 NOT NULL,
    ...
    `Tips_idTips` varchar(45) COLLATE latin1_bin NOT NULL,
    ...

Tips.idTips上显式设置字符集,并在Tips_has_SEntences.Tips_idTips列上设置表的默认排序规则

我的猜测是,当涉及的两列的排序规则或字符集不完全相同时,无法轻松比较外键的列,并且不支持引用完整性。

进一步的调查

接下来,我运行SHOW FULL COLUMN以显示所讨论列的详细信息。

Field           Type            Collation          Null    Key
idTips          varchar(45)     latin1_swedish_ci  NO      PRI
...
Tips_idTips     varchar(45)     latin1_bin         NO      PRI

为什么排序规则有所不同?

当我进一步阅读列上的字符集和排序规则时,MySQL文档说:

  • 如果指定的字符集X不带COLLATE,则使用字符集X及其默认排序规则。
  • 如果指定了COLLATE Y而没有CHARACTER SET,则使用与Y和归类Y关联的字符集。

要查看默认排序规则和关联的字符集,我运行了SHOW COLLATION

Collation               Charset Id      Default Compiled        Sortlen
...
latin1_german1_ci       latin1  5               Yes             1
latin1_swedish_ci       latin1  8       Yes     Yes             1
latin1_danish_ci        latin1  15              Yes             1
latin1_german2_ci       latin1  31              Yes             2
latin1_bin              latin1  47              Yes             1
latin1_general_ci       latin1  48              Yes             1
latin1_general_cs       latin1  49              Yes             1
latin1_spanish_ci       latin1  94              Yes             1
...

现在我们可以看到MySQL将Tips.idTips的排序规则解析latin1_swedish_ci,因为这是显式设置的latin1字符集的默认排序规则

排序规则将由字符集解析,而不是从表继承,因为字符集是在列上显式设置的。这正是在文档中指定的方式,因此这可能是所需的行为。

更进一步

现在我知道该Tips.idTips专栏的整理latin1_swedish_ci因此Tips_has_SEntences.Tips_idTips,我认为我可以只将排序规则更改为,而不是显式更改的字符集latin1_swedish_ci

`Tips_idTips` VARCHAR(45) COLLATE latin1_swedish_ci NOT NULL,

这也有效。现在
有趣的SHOW CREATE TABLE是说该列是/应该用以下行创建的:

`Tips_idTips` varchar(45) CHARACTER SET latin1 NOT NULL,

结论

字符集,排序规则外键在一起都是地狱。
如果可以选择的话,我更喜欢使用整数列作为外键,而不是字符串/文本类型。现在我知道为什么了:)

查看您发布的代码,这似乎是数据库中所有“旧”表的问题,因为所有文本列似乎都具有latin1明确定义的字符集

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在填充的数据库中进行正向工程某些新关系失败(错误号150)

来自分类Dev

MySQL 错误 #1005 errno 150

来自分类Dev

#1005-无法创建表errno:150

来自分类Dev

错误1005:无法创建表(errno 150)

来自分类Dev

创建外键时,mysql errno 150

来自分类Dev

无法创建表errno150

来自分类Dev

#1005-无法创建表errno:150

来自分类Dev

无法创建表(errno 150)Openshift的phpmyadmin

来自分类Dev

MySQL无法导入数据库(错误号:150)

来自分类Dev

如何从熊猫数据框中排除前 150 行和后 150 行?

来自分类Dev

#1025-在mysql中重命名(errno:150)时出错

来自分类Dev

在MySQL中创建表时如何摆脱errno 150?

来自分类Dev

Mysql errno:150创建时,删除字段后工作

来自分类Dev

无法制作2个外键,“ errno:150”

来自分类Dev

创建表时出现外键错误(errno 150)

来自分类Dev

MYSQL外键,无法创建表(errno:150)

来自分类Dev

以下SQL在MySQL中生成错误1005和errno 150

来自分类Dev

无法使NotifyIcon加载高DPI资源以进行DPI缩放> = 150%

来自分类Dev

统计数据框中的150个变量

来自分类Dev

图像转换:(150,150) -> (150,150,3)

来自分类Dev

[mysql]在小于150kb的数据库中存储小文件的最佳数据类型是什么

来自分类Dev

MySQL-errno 150:“外键约束格式不正确”

来自分类Dev

它继续显示“错误1005无法创建表注册。panepistimio(errno:150)

来自分类Dev

错误 1005 (HY000): 无法创建表 'CBDB.Subsystem' (errno: 150)

来自分类Dev

errno: 150 Laravel 迁移中的“外键约束形成不正确”

来自分类Dev

pyPdf拆分大PDF在拆分150-152页PDF后失败

来自分类Dev

为什么我的形状在每个新形状的左侧都会生成150px?

来自分类Dev

ValueError:从数据框中提取值时,项目的长度长度错误为0,而不是150。

来自分类Dev

使用150多个参数和数据不匹配访问INSERT查询。如何找到错误的参数?

Related 相关文章

  1. 1

    在填充的数据库中进行正向工程某些新关系失败(错误号150)

  2. 2

    MySQL 错误 #1005 errno 150

  3. 3

    #1005-无法创建表errno:150

  4. 4

    错误1005:无法创建表(errno 150)

  5. 5

    创建外键时,mysql errno 150

  6. 6

    无法创建表errno150

  7. 7

    #1005-无法创建表errno:150

  8. 8

    无法创建表(errno 150)Openshift的phpmyadmin

  9. 9

    MySQL无法导入数据库(错误号:150)

  10. 10

    如何从熊猫数据框中排除前 150 行和后 150 行?

  11. 11

    #1025-在mysql中重命名(errno:150)时出错

  12. 12

    在MySQL中创建表时如何摆脱errno 150?

  13. 13

    Mysql errno:150创建时,删除字段后工作

  14. 14

    无法制作2个外键,“ errno:150”

  15. 15

    创建表时出现外键错误(errno 150)

  16. 16

    MYSQL外键,无法创建表(errno:150)

  17. 17

    以下SQL在MySQL中生成错误1005和errno 150

  18. 18

    无法使NotifyIcon加载高DPI资源以进行DPI缩放> = 150%

  19. 19

    统计数据框中的150个变量

  20. 20

    图像转换:(150,150) -> (150,150,3)

  21. 21

    [mysql]在小于150kb的数据库中存储小文件的最佳数据类型是什么

  22. 22

    MySQL-errno 150:“外键约束格式不正确”

  23. 23

    它继续显示“错误1005无法创建表注册。panepistimio(errno:150)

  24. 24

    错误 1005 (HY000): 无法创建表 'CBDB.Subsystem' (errno: 150)

  25. 25

    errno: 150 Laravel 迁移中的“外键约束形成不正确”

  26. 26

    pyPdf拆分大PDF在拆分150-152页PDF后失败

  27. 27

    为什么我的形状在每个新形状的左侧都会生成150px?

  28. 28

    ValueError:从数据框中提取值时,项目的长度长度错误为0,而不是150。

  29. 29

    使用150多个参数和数据不匹配访问INSERT查询。如何找到错误的参数?

热门标签

归档