为什么当一切都是 innodb 时建表会失败,而当一张表是 MyIsam 时却不会失败?

发布于 2024-11-17 14:01:50 字数 2390 浏览 6 评论 0原文

当我尝试设计数据库结构时,我发现 innodb 相当烦人,至少与 MyIsam 相比,它似乎限制较少

比如说,如果我想创建一个简单的库系统。 我有四张桌子。

1、表book_item,记录了书名、作者、出版时间等图书的基本信息。

2、表book,表示图书项的具体真实对象。因此,一个 book_item 对象可以与许多书籍对象相关。

3、tabletag,它代表一本书的标签。比如科学、文学、建筑等等。

4、表tag_book_item_relation,它将标签与book_items相关联。

因此,关系如下。

1、我们有一个book itembook一对多关系

2、book_item >标签多对多关系。

这里注意,表的引擎都是innodb 如果我尝试创建表,它将失败:

Error:
Executing SQL script in server
ERROR: Error 1005: Can't create table 'yet_another_test.book' (errno: 121)

但是,如果我将 booktag_book_item_relation 的引擎更改为 MyISAM,一切都会正常美好的。

所以,我想知道如果我对表booktag_book_item_relation使用引擎innodb会出现什么问题

SQL脚本在这里(MySQL中的正向工程)工作台):

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`tag` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`book_item` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`tag_book_item_relation` (
  `book_item_id` INT NOT NULL ,
  `tag_id` INT NOT NULL ,
  PRIMARY KEY (`book_item_id`, `tag_id`) ,
  INDEX `fk_tag` (`tag_id` ASC) ,
  INDEX `fk_book_item` (`book_item_id` ASC) ,
  CONSTRAINT `fk_tag`
    FOREIGN KEY (`tag_id` )
    REFERENCES `yet_another_test`.`tag` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_book_item`
    FOREIGN KEY (`book_item_id` )
    REFERENCES `yet_another_test`.`book_item` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`book` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `book_item_id` INT NOT NULL ,
  PRIMARY KEY (`id`, `book_item_id`) ,
  INDEX `fk_book_item` (`book_item_id` ASC) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  CONSTRAINT `fk_book_item`
    FOREIGN KEY (`book_item_id` )
    REFERENCES `yet_another_test`.`book_item` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

I find innodb quite annoying when I try to design a db structure, at least compared with MyIsam, which seems to have less limitations

Say, if I want to create a simple library system.
And I have four tables.

1,table book_item, which records the book_name, author, publish time and those basic information about books

2, table book, which represents a specific real object of the book item. So a book_item object can relate to many book objects.

3, table tag, which represents a book tag. Like science, literature, architecture and so on.

4, table tag_book_item_relation, which relates tags to book_items.

So, the relations are as below.

1,we have a book item to book is one-to-many relationship

2,book_item to tag is many-to-many relationship.

Note here, engine for the table are all innodb
If I try to create the tables, it will fail:

Error:
Executing SQL script in server
ERROR: Error 1005: Can't create table 'yet_another_test.book' (errno: 121)

However, if I change the engine of book or tag_book_item_relation to MyISAM, everything will be fine.

So, I am wondering what is going wrong if I use engine innodb for tablebook and tag_book_item_relation

The sql script is here(forward engineering in MySQL workbench):

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`tag` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`book_item` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`tag_book_item_relation` (
  `book_item_id` INT NOT NULL ,
  `tag_id` INT NOT NULL ,
  PRIMARY KEY (`book_item_id`, `tag_id`) ,
  INDEX `fk_tag` (`tag_id` ASC) ,
  INDEX `fk_book_item` (`book_item_id` ASC) ,
  CONSTRAINT `fk_tag`
    FOREIGN KEY (`tag_id` )
    REFERENCES `yet_another_test`.`tag` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_book_item`
    FOREIGN KEY (`book_item_id` )
    REFERENCES `yet_another_test`.`book_item` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`book` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `book_item_id` INT NOT NULL ,
  PRIMARY KEY (`id`, `book_item_id`) ,
  INDEX `fk_book_item` (`book_item_id` ASC) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  CONSTRAINT `fk_book_item`
    FOREIGN KEY (`book_item_id` )
    REFERENCES `yet_another_test`.`book_item` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无法回应 2024-11-24 14:01:50

“CREATE TABLE book”似乎存在问题,即外键约束 fk_book_itemtag_book_item_relation 中的约束具有相同的名称。尝试在 book 中为约束使用另一个名称,CREATE TABLE 应该可以正常工作。

这在 MyISAM 中不是问题,因为它们没有外键的概念,因此 FK 约束被忽略。

希望这有帮助!

It seems there is an issue with the "CREATE TABLE book" that the foreign key constraint fk_book_item has the same name as the constraint in tag_book_item_relation. Try using another name for the constraint in book and the CREATE TABLE should work fine.

This isn't a problem in MyISAM because they have no concept of foreign-keys and so the FK constraints are ignored.

Hope this helps!

娇妻 2024-11-24 14:01:50

创建没有外键约束的表。尽管相同的语句适用于 MyISAM 引擎,但约束会被默默地忽略 - 这就是您没有收到错误的原因。如果您确实需要这些约束,请正确创建它们。然而,我通常倾向于避免 FK 约束并在应用程序级别实现约束。

我立即发现的一个问题是约束的符号在数据库级别必须是唯一的,并且在 tag_book_item_relation 表和 book 上都有 fk_book_item代码>表

Create your tables without the Foreign Key constraints. Although the same statements work with MyISAM engine, the constraints are silently ignored there - that is why you are not getting the errors. If you really need those constraints, then create them correctly. However, I generally tend to avoid FK constraints and implement the constraints at application level.

One problem I spot right away are the symbols of your constraints which have to be unique at DB level and you have fk_book_item both on tag_book_item_relation table and on book table

香草可樂 2024-11-24 14:01:50

ERROR 121 表示“表创建失败,因为外键约束格式不正确。如果错误消息引用错误 –1,则表创建可能失败,因为该表包含与内部 InnoDB 表的名称相匹配的列名。”

链接

索引名称和约束名称可能是同样,更改尝试创建表。

ERROR 121 says "Table creation failed because a foreign key constraint was not correctly formed. If the error message refers to error –1, table creation probably failed because the table includes a column name that matched the name of an internal InnoDB table."

Link

The Index Name and Constraint Name may be same, change that try creating the table.

も让我眼熟你 2024-11-24 14:01:50

此错误消息表明某处存在重复的键。它可能是由外键约束中的名称冲突引起的;您不能在不同的表中使用相同的外键名称。 (我不知道你的数据库中可能还有哪些其他表。)

通常,错误是由 InnoDB 内部字典中已经存在的表引起的,即使 .frm 文件已经消失了。如果是这种情况,那么最简单的方法就是对数据进行 sql 转储,删除数据库,重新创建它,然后从转储中加载数据。

This error message is saying that there is a duplicate key somewhere. It can be caused by a name conflict in a foreign key constraint; you cannot use the same foreign key name in different tables. (I don't know what other tables might be in your data base.)

Often, the error is caused by the table already existing in InnoDB's internal dictionary, even though the .frm file is gone. If that's the case, then the easiest thing to do is to do an sql dump of the data, drop the data base, recreate it, and then load the data from the dump.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文