索引FK和索引列

时间:2017-10-02 11:38:27

标签: mysql sql mysql-workbench

我正在设计一些表,使用MySQL WorkBench,并在某些列上设置外键,以遵循一些"更正"设计模式。然后,我的老板问我为什么使用FK,因为他们" 只会导致问题"。

在创建新的FK时,看看MySQL WorkBench是什么,它会创建关系,并在其上创建索引。像这样:

CREATE TABLE `smx_portales-des`.`A1` (
  `idA1` INT NOT NULL,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`idA1`));

CREATE TABLE `smx_portales-des`.`A2` (
  `idA2` INT NOT NULL,
  `price` DECIMAL(10,2) NULL,
  `fkA1` INT NULL,
  PRIMARY KEY (`idA2`),
  INDEX `fk_A2_A1_idx` (`fkA1` ASC),
      CONSTRAINT `fk_A2_A1`
  FOREIGN KEY (`fkA1`)
      REFERENCES `smx_portales-des`.`A1` (`idA1`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION);

我的老板告诉我创建表A2如下:

  CREATE TABLE `smx_portales-des`.`A2` (
      `idA2` INT NOT NULL,
      `price` DECIMAL(10,2) NULL,
      `fkA1` INT NULL,
      PRIMARY KEY (`idA2`),
      INDEX fk_A2_A1(fkA1));

因此,除了FK的明显限制之外,只允许其他表格或NULL s上的值,是否有其他表现,造型师或这些模型中的任何差异?

编辑:我知道FK有助于数据库数据的完整性,并且有一些级联选项可以帮助删除/更新子级。另外,不同之处在于,在第二个模型中,我使用" 模拟"中的索引。 FK专栏。我想知道更多关于这两个模型的合理差异,如效率,尺寸......

3 个答案:

答案 0 :(得分:4)

你的老板错了。并随时向他们展示这个答案。

关系数据库中的一个关键功能是维护数据完整性。数据完整性的关键部分是确保外键关系正确。

在您的数据库中,这可以保证a2.fka1始终引用a1中的有效列(或具有NULL值)。这对于理解数据的人来说很重要,因为人们编写查询(因此行不会在连接中无意中丢失),并且可能对于优化器而言。

维护此功能的正确位置在数据库中。您可以尝试从应用程序执行此操作,但无论数据修改操作如何,数据库都可确保数据正确无误。

最后,外键非常灵活。你(和你的老板)应该了解级联约束。它们通常实现应用程序所需的功能。

答案 1 :(得分:0)

我目前也在不使用外键而不强制使用外键的地方工作。但是,我强烈建议使用它们。看起来你的嘘声告诉你只需在外键列上放一个索引,而不是实际创建一个与两个表之间的键的关系。

第二个查询可能会运行得更快,但如果没有外键关系,您很可能会丢失数据完整性并增加孤立行的可能性,这是我亲眼看到的。通过不使用密钥,它实现起来更快,并且可能运行得更快,但从长远来看,它将为数据库带来更多问题。我的建议是创建密钥然后再使用索引

答案 2 :(得分:0)

所有设计决策都是权衡取舍。交易的显而易见的事情是性能(时间)和空间效率 - 但您也需要担心可维护性和弹性。

从绩效和空间效率的角度来看,您的选择之间没有可衡量的差异。

@gordonLinoff已经回复了有关数据完整性的问题,这是恢复能力的一个关键方面 - 您的应用程序设计是否更难以抵御错误?

最后,从可维护性的角度来看,拥有外键会在代码库中创建一个显式的伪像,说数据实体a与数据实体b相关。这意味着未来的开发人员不必担心命名约定,或者数据是否一致 - 他们可以对您的数据做出简单的假设。

这确实需要很小的成本 - 您的客户端代码需要处理特定类型的错误消息,并且您需要围绕级联逻辑,有些人发现一些苦差事。我个人认为这是一个很小的代价。