【问题标题】:MySQL "many to many" relation errorMySQL“多对多”关系错误
【发布时间】:2018-09-09 20:52:05
【问题描述】:

我有 3 个处于“多对多”关系的表。

表 A:

CREATE TABLE IF NOT EXISTS tabA(
tabAcolA mediumint unsigned not null auto_increment,
tabAcolB text not null,
tabAcolC text null,
PRIMARY KEY keyA (tabAcolA)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

表 B:

CREATE TABLE IF NOT EXISTS tabB(
tabBcolA mediumint unsigned not null auto_increment,
tabBcolB text not null,
PRIMARY KEY keyB (tabBcolA)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

表 C(AB 关节):

CREATE TABLE IF NOT EXISTS tabC(
    tabCcolA int unsigned not null,
    tabCcolB int unsigned not null,
    PRIMARY KEY keyC (tabCcolA,tabCcolB),
    CONSTRAINT FkeyA FOREIGN KEY (tabCcolA) 
    REFERENCES tabA(tabAcolA) ON DELETE RESTRICT ON UPDATE RESTRICT,
    CONSTRAINT FkeyB FOREIGN KEY (tabCcolB) 
    REFERENCES tabB(tabBcolA) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE=InnoDB

它返回一个错误:

1215 Cannot add foreign key constraint

那里有什么问题?

【问题讨论】:

  • Mediumint vs int,引用时类型应该匹配

标签: mysql database-design foreign-keys many-to-many constraints


【解决方案1】:

问题是列的数据类型不匹配。

外键列的数据类型必须与引用列完全匹配。例如

 fkcol  INT UNSIGNED     ref -> pkcol  INT UNSIGNED

 fkcol  MEDIUMINT        ref -> pkcol  MEDIUMINT

如果我们尝试使用不同数据类型的列创建外键约束,InnoDB 会返回错误。 (OP观察到的行为。)

【讨论】:

  • 谢谢。不幸的是,修复此错误后,Indexes 表中只出现了一个索引 (FkeyB)。为什么?
  • 因为已经有适合其他外键使用的索引了。 PRIMARY KEY(集群索引)将tabCcolA 作为前导列。因此,另一个以tabCcolA 作为前导索引的索引将是多余的。 (InnoDB 将创建一个索引来支持外键如果它没有找到合适的现有索引。)并且不要求索引的名称与外键的名称匹配键。
  • 连接表中是否需要创建PRIMARY KEY?
  • 如果我们想要防止重复值,我们需要一个 UNIQUE KEY...在tabC 中的列上使用 NOT NULL 约束,这两个列上的 UNIQUE KEY 将等效于 PRIMARY KEY,并且 InnoDB 将使用 UNIQUE KEY 作为集群键。 (我个人的偏好是在 tabC 上有一个 PRIMARY KEY,正如问题所示。(但这不是 InnoDB 的严格要求。)
  • 连接/链接/关联表上是否需要有 PRIMARY KEY?不,对它没有严格的要求。但我会选择 not 有一个主键 only 如果那是解决某种问题。并且单例tabCcolA 列上没有不必要的索引不是问题。 (如果这是一个问题,我会添加一个索引,而不是删除 PRIMARY KEY。)
猜你喜欢
  • 2014-12-11
  • 2011-04-05
  • 2016-03-22
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 2020-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多