在MySQL中,为什么我必须定义外键关系?

时间:2011-11-22 19:11:22

标签: mysql sql database relational-database

为什么我不能把这些关系留下来?

他们有什么意义?

我可以继续运行查询并将它们视为一种关系......

6 个答案:

答案 0 :(得分:7)

是的,您可以随时保留外键约束,但随后您将对数据的完整性负责。如果使用外键约束,则不必担心表之间的引用完整性。您可以从Wikipedia了解有关参照完整性的更多信息。我还将尝试用下面的例子来解释它。

想想购物车场景。您有三个表:itemshopping_cartshopping_cart_item。您可以选择不在这些表之间定义任何关系,这对任何SQL解决方案都适用。当用户开始购物时,您可以通过添加shopping_cart条目来创建购物车。当用户将商品添加到购物车时,您可以通过向shopping_cart_item表添加行来保存此信息。

此步骤可能会出现一个问题:如果您的错误代码将错误的shopping_cart_id分配给shopping_cart_item,那么您肯定会收到错误的数据!是的,如果分配的ID实际存在于shopping_cart表中,即使使用外键约束,也可以使用此案例。但是当外键存在时,这个错误将更容易被检测到,因为当外键约束失败时它不会插入shopping_cart_item记录。

让我们继续假设您的代码没有错误,并且您将没有第一种类型的引用完整性。然后突然用户想要停止购物并删除购物车,您选择通过删除shopping_cartshopping_cart_item条目来实现这种情况。然后,您将必须使用两个单独的查询删除两个表中的条目。如果在删除shopping_cart条目后出现问题,那么您将再次出现参照完整性问题:您将shopping_cart_item与任何shopping_cart无关。然后,您将不得不引入事务管理,尝试为您的业务逻辑提供有关数据访问层中发生的错误的有意义的数据等。

在这种类型的场景中,外键可以挽救生命。您可以定义一个外键约束,该约束将阻止插入任何类型的错误数据,您可以定义级联操作,这些操作将自动执行相关数据的删除。

如果有任何不清楚的地方,请发表评论,我可以改进答案。

答案 1 :(得分:2)

您可以创建FOREIGN KEY来指示数据库引擎确保您永远不会对创建无效记录的数据库执行操作。

因此,如果您在users.idvisits.userid之间创建FOREIGN KEY关系,引擎将拒绝执行导致useridvisits值的任何操作在users中不存在。这可能会向userid添加未知visits,从id中已存在的users中移除visits,或更新任一字段以“中断”关系。

这就是为什么PRIMARY和FOREIGN KEY被称为参照完整性约束。告诉数据库引擎如何保持数据正确。

答案 2 :(得分:2)

除了其他人所说的为什么你在技术上想要(实际上:需要)他们:
外键约束记录您的模型。

在查看没有FK约束的模型时,您不知道哪个表与哪个相关。但是,在FK约束的情况下,您可以立即看到事物是如何组合在一起的。

答案 3 :(得分:1)

它不允许您输入另一个表中不存在的ID,例如,如果您有产品并且您保留所有者ID,则通过创建外键来将所有者ID转换为所有者表的id字段,您不允许用户创建具有所有者表中不存在的所有者ID的对象记录。这类事情被称为referential intergrity.

enter image description here

答案 4 :(得分:0)

外键约束可帮助您确保参照完整性。

如果删除一个表中的一行,mysql可以通过外键自动删除已删除行引用的其他表中的所有行。您也可以拒绝删除命令。

此外,当您尝试插入行时,mysql可以自动在其他表中创建新行,因此外键不会引用任何内容。

这就是参照完整性的全部内容。

答案 5 :(得分:0)

数据库不仅仅受应用程序的影响。并非所有数据更改都通过应用程序进行,即使应该这样做。人们一直在数据库上直接更改内容。需要始终应用于所有数据的规则属于数据库。假设您可以更新您的股票价格。这对于更新个人价格非常有用。但是当老板决定将所有价格提高15%时会发生什么。没有人会通过GUI一次一个地改变10,000个价格,他们将编写一个快速的SQL脚本来进行更新。或者假设两个供应商联合起来拥有一家公司,并且您希望将所有项目更改为新公司。这些类型的更改每天都发生在数据库中,他们也需要遵循数据完整性规则。

新开发人员可能不知道外键关系应该存在的所有位置,从而导致错误导致数据不再有用。

没有外键约束的数据库几乎有100%的可能性存在不良数据。您是否真的想要订购无法识别客户的订单?

如果FKS阻止您删除具有订单的客户,或者如果您使用company_name的自然密钥并且名称发生更改,则必须通过密钥更改来更改所有相关记录。

或者假设您决定将新GUI放在一起并转储旧GUI,那么您可能必须再次弄清楚所有FK关系(因为您使用的是不同的数据层或ORM),您可能会错过一些。

不放入FK关系是极端不负责任的。你冒着公司业务的命脉,因为你觉得这很痛苦。如果您建议不使用FK,我会解雇您,因为我知道我无法相信我公司的数据给您。