我们正在尝试清理数据库并讨论是否在我们的表上设置外键约束。如果在一个表中更改主键的模式会影响其他表中的外键模式,那么使用它们将是一个非常有说服力的论据。但情况确实如此吗?
例如,假设我有一个主表 id 的USER表,我有另一个表BLOGGERS,其 blogger_id 是与 id <绑定的外键/ strong>即可。假设 id 最初被声明为SMALLINT,但随后我有大量用户注册,我们需要增加可用于ID的范围。如果我将 id 改为和INT,那么它会自动将BLOGGER表中的 blogger_id 改为INT吗?
无论我的主要问题的答案是什么,有没有人知道正式声明外键约束的任何令人信服的理由,除了限制可以放在该字段中的数据?谢谢!
答案 0 :(得分:1)
不,如果更改父表中的数据类型,MySQL不会更改子表中的数据类型。
我必须帮助一位在Users
表中达到最大INT值的咨询客户。但正如您可以想象的那样,有30个其他表引用了Users
。在我们更改ALTER TABLE
表中的主键数据类型之前,我们必须在其他30个表中的每一个上Users
,因为如果孩子无法引用新的用户ID,它将无法工作表。
至于你关于外键的问题,是的,为了强制执行数据完整性,我建议使用它们。在我分析的每个数据库中,如果没有外键,它们在子表中有很多孤立的行,没有自动检测它们的方法。
也就是说,网站放弃外键是很常见的,假设他们会在应用程序代码中“做正确的事”以避免孤立的数据。
反对外键的一个参数是外键的存在会产生一些你可能没想到的锁定情况。如果我更新子行,您希望它在您的事务持续期间锁定该行。但是如果你有一个外键,这个也会锁定外键引用的表中的父行。
示例:假设您有父表ShoppingCart
和子表LineItems
。如果更新LineItems
中的行数,则事务会在该行上进行独占锁定(X锁定)。但它也在ShoppingCart
的父行上进行共享锁(S锁)。例如,当你正在处理引用它的行之一时,你不希望你所依赖的行被删除是有道理的。
这是共享锁,因此多个事务可以同时具有此类锁定,但是如果您需要直接更新父行,而一个或多个客户端具有这些隐式共享锁,你被阻止了。