使用MySQL Workbench在已经索引的列上创建外键

4

我正在使用Workbench创建数据库模型,并创建了以下表格:

CREATE  TABLE IF NOT EXISTS `Database`.`table1` (
  `idtable1` INT NOT NULL ,
  `uniquecolumn` INT NOT NULL ,
  PRIMARY KEY (`idtable1`) ,
  UNIQUE INDEX `UniqueIndex` (`uniquecolumn` ASC) )
ENGINE = InnoDB

它有一个主键和一个唯一键在我的第二列。

当我在它们上面创建外键约束时,Workbench会自动添加两个索引:

CREATE  TABLE IF NOT EXISTS `Database`.`table1` (
  `idtable1` INT NOT NULL ,
  `uniquecolumn` INT NOT NULL ,
  PRIMARY KEY (`idtable1`) ,
  UNIQUE INDEX `UniqueIndex` (`uniquecolumn` ASC) ,
  INDEX `FKOne` (`idtable1` ASC) ,                   //here
  INDEX `FKTwo` (`uniquecolumn` ASC) ,               //(I don't want this!)
  CONSTRAINT `FKOne`
    FOREIGN KEY (`idtable1` )
    REFERENCES `Database`.`table2` (`idtable2` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `FKTwo`
    FOREIGN KEY (`uniquecolumn` )
    REFERENCES `Database`.`table2` (`idtable2` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB

在将外键添加到我的模型后,上述内容是前向生成的脚本。

我现在有四个索引。

MySQL参考手册中指出:

在引用表中,必须存在一个索引,其中包含外键列,并以相同顺序作为第一列。如果不存在此类索引,则会自动在引用表上创建此类索引。

因此,我理解不需要创建索引 FKOneFKTwo,因为已经在同一列和相同顺序上有一个主键和唯一索引。然而,MySQL Workbench不允许我删除索引 FKOneFKTwo。我认为我应该能够这样做:

CREATE  TABLE IF NOT EXISTS `Database`.`table1` (
  `idtable1` INT NOT NULL ,
  `uniquecolumn` INT NOT NULL ,
  PRIMARY KEY (`idtable1`) ,
  UNIQUE INDEX `UniqueIndex` (`uniquecolumn` ASC) ,
  CONSTRAINT `FKOne`
    FOREIGN KEY (`idtable1` )
    REFERENCES `Database`.`table2` (`idtable2` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `FKTwo`
    FOREIGN KEY (`uniquecolumn` )
    REFERENCES `Database`.`table2` (`idtable2` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB

我说的对吗?这段代码能用吗?有没有办法在Workbench中完成它?(除了在正向工程之前最后一刻删除那两行代码)。

或者也许MySQL足够聪明,不会创建完全冗余的索引,我不必担心它...?


这两列是否实际上引用了同一张表中的同一列 - 还是打错字了? - ypercubeᵀᴹ
是的,它们引用同一张表中的同一列,这迫使我在更新引用列之前删除该行!不过,这与本问题无关。也许我应该选择另一个例子。 - Dil
不,没关系。有两列引用同一个列是很常见的,比如在定义父子层次结构时。唯一约束让我有点困惑了一会儿。(顺便说一下,我在Workbench上也遇到了同样的问题)。 - ypercubeᵀᴹ
1个回答

2
(我假设这是定义模型时的情况。)请参见Bug 53277,其中提到以下晦涩的解决方法:您从外键及其对应的生成索引开始,想要摆脱它们。确保该键(至少暂时)位于单个非唯一列上。在索引选项卡中,将类型更改为UNIQUE。然后转到列选项卡,在那里UQ现在被选中,请取消选择它。不需要的索引就被消除了!

是的,就是这样!非常感谢!!我一直在尝试创建外键,而不先创建任何其他索引,然后将生成的索引更改为唯一和主键。更改为唯一是可能的,但更改为主键则不行。然而,您的解决方案适应任何情况,因为它完全删除了生成的索引。令人惊讶的是,它似乎基于另一个错误,因为人们会期望取消选中UQ列会导致该列上的任何唯一索引返回到INDEX,而不是消失。 - Dil
现在我可以维护一个精确的数据库模型,不用再编辑正向工程脚本了。 - Dil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接