【问题标题】:what is the problem with my tables in mysql?我在mysql中的表有什么问题?
【发布时间】:2020-05-05 16:26:09
【问题描述】:

我要创建 3 个表。表“post”和“taxonomy”通过主键和外键连接到“taxonomy_relationship”表,但我不知道为什么会出现此错误:

1005 - 无法创建表taxonomy_relationship (errno: 150 "外键约束格式不正确")

CREATE TABLE `post`(
    id int not null AUTO_INCREMENT,
    title varchar(255) not null,
    content TEXT not null,
    PRIMARY KEY(id)
);

CREATE TABLE `taxonomy`(
    id int not null AUTO_INCREMENT,
    tax_title varchar(255) not null,
    type varchar(255) not null,
    PRIMARY KEY(id, tax_title)
);

CREATE TABLE taxonomy_relationship(
    id INT AUTO_INCREMENT,
    post_id int not null,
    title varchar(255) not null,
    PRIMARY KEY(id),
    FOREIGN KEY (post_id) 
        REFERENCES post(id) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE
    FOREIGN KEY (title) 
        REFERENCES taxonomy(tax_title) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE
);


当我使用“SHOW ENGINE INNODB STATUS”来显示它返回的错误详细信息时:

> 2020-01-19 16:08:31 0x2fb8 表 blog.taxonomy_relationship:
的外键约束错误 外键(标题)
参考分类(tax_title)
删除级联
更新级联
):
在引用的表中找不到索引 引用的列显示为第一列或列类型 表中和引用表中的约束不匹配。 注意 ENUM 和 SET 的内部存储类型在 使用 >= InnoDB-4.1.12 创建的表,以及旧表中的此类列 不能被新表中的此类列引用。 请参阅https://mariadb.com/kb/en/library/foreign-keys/ 了解正确的外键定义。 使用外键约束创建表 blog.taxonomy_relationship 失败。引用的表中没有索引,其中引用的列显示为 'FOREIGN KEY (title)
附近的第一列 参考分类(tax_title)
删除级联
更新级联
)'。

【问题讨论】:

  • 错误信息说明了一切——您需要有一个索引,其中tax_title 是taxonomy 中的第一列
  • 可以帮我解决这个问题。我只是不知道我现在该怎么办!
  • 只需在表定义中添加INDEX (tax_title)
  • 一种常见的做法是引用taxonomy(id) 而不是taxonomy(tax_title)。将tax_title 作为主键的一部分也可能没有意义。

标签: mysql foreign-keys


【解决方案1】:

您应该在taxonomy 表上添加索引KEY title_idx (tax_title):

CREATE TABLE `taxonomy` (
   `id` int NOT NULL AUTO_INCREMENT,
   `tax_title` varchar(255) NOT NULL,
   `type` varchar(255) NOT NULL,
   PRIMARY KEY (`id`),
   KEY `title_idx` (`tax_title`)
);

创建外键后:

CREATE TABLE taxonomy_relationship(
    id INT AUTO_INCREMENT,
    post_id int not null,
    title varchar(255) not null,
    PRIMARY KEY(id),
    FOREIGN KEY (post_id) 
        REFERENCES post(id) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE,
    FOREIGN KEY (title) 
        REFERENCES taxonomy(tax_title) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE
);

另一种方法可以在taxonomy_relationship 中复制title,但通过id 字段链接它:

CREATE TABLE taxonomy_relationship(
    id INT AUTO_INCREMENT,
    post_id int not null,
    taxonomy_id int not null,
    PRIMARY KEY(id),
    FOREIGN KEY (post_id) 
        REFERENCES post(id) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE,
    FOREIGN KEY (taxonomy_id) 
        REFERENCES taxonomy(id) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE
);

【讨论】:

  • 谢谢你!我只想知道为什么要使用密钥?我可以在一个表中有多少个“键”或索引?
  • 引用非唯一列(或元组)是一种奇怪的做法。
  • 我必须在父表上创建索引,因为FOREIGN KEY 构造定义了子表键和父表键之间的关系。每个表上的索引数量不受限制,但您需要记住每个索引都会延迟 INSERT/UPDATE 操作并占用磁盘容量
  • 参见FOREIGN KEY Constraint Differences:“对于 UPDATE 或 DELETE CASCADE 等操作,对非唯一键或包含 NULL 值的键的外键引用的处理没有明确定义。建议您使用符合以下条件的外键仅引用 UNIQUE(包括 PRIMARY)和 NOT NULL 键。”
  • @Paul Spiegel 你绝对正确,我提供了带有 PRIMAY KEY 参考的第二个解决方案。
猜你喜欢
  • 2012-07-30
  • 2010-09-29
  • 2016-05-25
  • 2018-02-27
  • 2013-07-21
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
相关资源
最近更新 更多