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