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

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

这是创建表线程上的另一个错误1005,错误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)已经尽力搜索了,但是答案仍然在那里。在这种情况下,很抱歉。

也许它与旧表(Tips)中已经有数据的事实有关。同步一个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

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

来自分类Dev

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

来自分类Dev

添加数据库关系信息以在Java数据库中进行映射?

来自分类Dev

通过从具有不同结构的旧数据库中进行多条件选择来填充新的DataFrame

来自分类Dev

从 postgresql 数据库错误中进行条件选择

来自分类Dev

使用EntityFramework.CodeTemplates对现有数据库进行反向工程会产生错误

来自分类Dev

关系数据库查询失败

来自分类Dev

mysql正向工程错误

来自分类Dev

在视图中进行hstore比较转储和还原PostgreSQL数据库失败

来自分类Dev

尝试通过获取数据库错误错误号来添加新客户:1054

来自分类Dev

Android ListView:如何避免在bindView()中进行数据库查询?需要获取一对多关系数据

来自分类Dev

为什么关系数据库不支持从存储过程中进行选择?

来自分类Dev

pg_restore 错误:“关系不存在”并创建新数据库

来自分类Dev

数据库连接失败错误

来自分类Dev

在Rails中进行数据库备份4

来自分类Dev

如何在Meteor中进行简单的数据库查询

来自分类Dev

通过Hibernate从PostgreSQL数据库中进行随机SELECT

来自分类Dev

如何在Oracle数据库中进行小时划分

来自分类Dev

如何设置不同的数据库以在pyramida中进行测试?

来自分类Dev

在数据库中进行异步多次更新

来自分类Dev

如何在Meteor中进行简单的数据库查询

来自分类Dev

使用已部署的数据库在localhost中进行调试

来自分类Dev

设置数据库以在Flask中进行测试

来自分类Dev

值未在MySQL数据库中进行编辑

来自分类Dev

如何在JavaFX中进行异步数据库

来自分类Dev

通过Hibernate从PostgreSQL数据库中进行随机SELECT

来自分类Dev

数据库关系

来自分类Dev

发生数据库错误,错误号-1054

来自分类Dev

Codeigniter 发生数据库错误错误号:1064

Related 相关文章

  1. 1

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

  2. 2

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

  3. 3

    添加数据库关系信息以在Java数据库中进行映射?

  4. 4

    通过从具有不同结构的旧数据库中进行多条件选择来填充新的DataFrame

  5. 5

    从 postgresql 数据库错误中进行条件选择

  6. 6

    使用EntityFramework.CodeTemplates对现有数据库进行反向工程会产生错误

  7. 7

    关系数据库查询失败

  8. 8

    mysql正向工程错误

  9. 9

    在视图中进行hstore比较转储和还原PostgreSQL数据库失败

  10. 10

    尝试通过获取数据库错误错误号来添加新客户:1054

  11. 11

    Android ListView:如何避免在bindView()中进行数据库查询?需要获取一对多关系数据

  12. 12

    为什么关系数据库不支持从存储过程中进行选择?

  13. 13

    pg_restore 错误:“关系不存在”并创建新数据库

  14. 14

    数据库连接失败错误

  15. 15

    在Rails中进行数据库备份4

  16. 16

    如何在Meteor中进行简单的数据库查询

  17. 17

    通过Hibernate从PostgreSQL数据库中进行随机SELECT

  18. 18

    如何在Oracle数据库中进行小时划分

  19. 19

    如何设置不同的数据库以在pyramida中进行测试?

  20. 20

    在数据库中进行异步多次更新

  21. 21

    如何在Meteor中进行简单的数据库查询

  22. 22

    使用已部署的数据库在localhost中进行调试

  23. 23

    设置数据库以在Flask中进行测试

  24. 24

    值未在MySQL数据库中进行编辑

  25. 25

    如何在JavaFX中进行异步数据库

  26. 26

    通过Hibernate从PostgreSQL数据库中进行随机SELECT

  27. 27

    数据库关系

  28. 28

    发生数据库错误,错误号-1054

  29. 29

    Codeigniter 发生数据库错误错误号:1064

热门标签

归档