1

我们正在尝试清理数据库并争论是否在我们的表上放置外键约束。如果更改一个表中主键的架构会影响其他表中外键的架构,那么使用它们将是一个非常有说服力的论据。但情况是这样吗?

例如,假设我有一个带有主键id的 USER 表,而我有另一个表 BLOGGERS ,其blogger_id是与id绑定的外键。假设id最初被声明为 SMALLINT,但后来我有大量用户注册,我们需要增加 id 的可用范围。如果我将id更改为和 INT,是否会自动将 BLOGGER 表中的blogger_id也更改为 INT?

无论我的主要问题的答案如何,除了限制可以放置在该字段中的数据之外,是否有人知道正式声明外键约束的任何令人信服的理由?谢谢!

4

1 回答 1

1

不,如果您更改父表中的数据类型,MySQL 不会更改子表中的数据类型。

我必须帮助我的一位咨询客户,他们的Users表中 INT 值已达到最大值。但您可以想象,还有 30 个其他表引用了Users. 在更改表中的主键数据类型之前,我们必须ALTER TABLE对其他 30 个表中的每一个进行更改Users,因为如果子表无法引用新用户 ID,它将无法工作。

至于您关于外键的问题,是的,我确实推荐它们以确保数据完整性。在我分析过的每个试图不使用外键的数据库中,它们在子表中都有很多孤立的行,没有自动检测它们的方法。

也就是说,网站放弃外键的情况出人意料地普遍,假设他们会在应用程序代码中“做正确的事”以避免孤立数据。

反对外键的论据之一是外键的存在会产生一些您可能不会预料到的锁定情况。如果我更新子行,您希望它在事务期间锁定该行。但是,如果您有外键,这也会锁定外键引用的表中的父行。

示例:假设您有一个父表ShoppingCart和一个子表LineItems。如果您 UPDATE 中的一行的数量LineItems,您的事务会在该行上创建一个排他锁(X 锁)。但它也在ShoppingCart. 例如,当您正在处理引用它的行之一时,您不希望删除您所依赖的行是有道理的。

这是一个共享锁,因此多个事务可以同时拥有这种锁,但是如果您需要直接更新父行,而一个或多个客户端拥有这些隐式共享锁,您将被阻塞。

于 2013-11-07T18:59:04.923 回答