【问题标题】:¿What i am doing wrong? [duplicate]¿我做错了什么? [复制]
【发布时间】:2019-12-21 09:11:22
【问题描述】:

我正在尝试使用此 sql 代码创建一个表:

CREATE TABLE IF NOT EXISTS `Proyecto2019`.`matricular` (
  `dni` INT(10) NOT NULL,
  `id_carrera` INT(4) NOT NULL,
  `id_año` INT(1) NOT NULL,
  `id_materia` INT(4) NOT NULL,
  `estado` VARCHAR(45) NULL,
  `id_login` VARCHAR(10) NULL,
  `fecha_login` VARCHAR(10) NULL,
  PRIMARY KEY (`dni`, `id_carrera`, `id_materia`, `id_año`),
  INDEX `id_carrera_idx` (`id_carrera` ASC),
  INDEX `id_materia_idx` (`id_materia` ASC),
  CONSTRAINT `fk_dni`
    FOREIGN KEY (`dni`)
    REFERENCES `Proyecto2019`.`dm_alumnos` (`dni`)
,
  CONSTRAINT `fk_id_carrera`
    FOREIGN KEY (`id_carrera`)
    REFERENCES `Proyecto2019`.`dm_carreras` (`id_carrera`)
,
  CONSTRAINT `fk_id_materia`
    FOREIGN KEY (`id_materia`)
    REFERENCES `Proyecto2019`.`dm_materias` (`id_materia`)
)
ENGINE = InnoDB

我收到以下错误:

1005 - 无法创建表 proyecto2019.matricular(错误号:121“写入或更新时重复键”)

什么是错误?没找到

【问题讨论】:

  • 为什么 CONSTRAINT fk_id_materia 列出了两次?看起来你只需要这个约束一次?
  • 也许我在这里忽略了一些东西(可能),但我看不到重复的命名索引、约束或列在哪里,cmets 和标记的重复都说是问题所在。我瞎了吗?
  • 我猜每个人都指的是约束名称与列名称不同,它不是表范围的。
  • 这意味着在同一个数据库中可能存在一个已经具有名称 fk_whatever 的约束并且 OP 再次尝试使用该名称?我以前没有遇到过这个错误,所以我假设这个问题对这里的每个人来说都很明显,以至于他们无法为像我这样的慢人拼出来?
  • @JNevill 没关系,这也不是我想到的第一件事;不过,我确定我之前遇到过它,因为这是我认为我用“thistable_referencedtable_fk”格式(冗余包含表名)命名我的 fk 约束的唯一原因。这是有道理的,因为约束确实存在于两个表之间,而不仅仅是一个表的属性(尤其是当您考虑 ON DELETE|UPDATE 属性时)。 在 CREATE TABLE 中声明它确实更方便语法。

标签: mysql sql


【解决方案1】:

当您已经有一个具有该名称的 FK 时,通常会发生这种情况。您对 FK 的命名策略看起来确实可能会导致冲突。当我命名 FK 时,我将表名和列名放入其中:

CONSTRAINT `fk_mattricular_id_carrera__dm_carreras_id_carrera`
FOREIGN KEY (`id_carrera`)
REFERENCES `Proyecto2019`.`dm_carreras` (`id_carrera`)

名称最长可达 64 个字符。在模式fk_a_b__c_d 中为 FK 和下划线添加 7 个字符意味着表/列名称(ab、cd)每个最多可以有 14 个字符(如果你想有一个“在 14 个字符处剪切”规则。你命名的方式是哪一种它们取决于你,我倾向于做 fk_childtab_childcol__parenttab_parentcol

我认为这个习惯是从旧的 SQLserver 中养成的;错误消息过去在“违反约束'fk_whatever'”方面非常无用-它没有说明哪个列引用了其他列导致了问题,但是将fk命名为提供了更多线索。它还有助于避免命名冲突,因为除非您有两个名称很长且仅在最后几个字符不同的表/列,否则重复的可能性很低

【讨论】:

  • 我在另一个同名的表中有一些 fk。向所有人致敬!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
  • 2021-12-03
  • 2016-03-22
  • 2016-06-02
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多