我正在设计一些表,使用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专栏。我想知道更多关于这两个模型的合理差异,如效率,尺寸......
答案 0 :(得分:4)
你的老板错了。并随时向他们展示这个答案。
关系数据库中的一个关键功能是维护数据完整性。数据完整性的关键部分是确保外键关系正确。
在您的数据库中,这可以保证a2.fka1
始终引用a1
中的有效列(或具有NULL
值)。这对于理解数据的人来说很重要,因为人们编写查询(因此行不会在连接中无意中丢失),并且可能对于优化器而言。
维护此功能的正确位置在数据库中。您可以尝试从应用程序执行此操作,但无论数据修改操作如何,数据库都可确保数据正确无误。
最后,外键非常灵活。你(和你的老板)应该了解级联约束。它们通常实现应用程序所需的功能。
答案 1 :(得分:0)
我目前也在不使用外键而不强制使用外键的地方工作。但是,我强烈建议使用它们。看起来你的嘘声告诉你只需在外键列上放一个索引,而不是实际创建一个与两个表之间的键的关系。
第二个查询可能会运行得更快,但如果没有外键关系,您很可能会丢失数据完整性并增加孤立行的可能性,这是我亲眼看到的。通过不使用密钥,它实现起来更快,并且可能运行得更快,但从长远来看,它将为数据库带来更多问题。我的建议是创建密钥然后再使用索引
答案 2 :(得分:0)
所有设计决策都是权衡取舍。交易的显而易见的事情是性能(时间)和空间效率 - 但您也需要担心可维护性和弹性。
从绩效和空间效率的角度来看,您的选择之间没有可衡量的差异。
@gordonLinoff已经回复了有关数据完整性的问题,这是恢复能力的一个关键方面 - 您的应用程序设计是否更难以抵御错误?
最后,从可维护性的角度来看,拥有外键会在代码库中创建一个显式的伪像,说数据实体a与数据实体b相关。这意味着未来的开发人员不必担心命名约定,或者数据是否一致 - 他们可以对您的数据做出简单的假设。
这确实需要很小的成本 - 您的客户端代码需要处理特定类型的错误消息,并且您需要围绕级联逻辑,有些人发现一些苦差事。我个人认为这是一个很小的代价。