【问题标题】:In MySQL, will changing the schema of a primary key affect the schema of foreign keys in other tables?在 MySQL 中,更改主键的架构会影响其他表中外键的架构吗?
【发布时间】:2013-11-19 13:59:23
【问题描述】:
我们正在尝试清理数据库并讨论是否在我们的表上设置外键约束。如果更改一个表中的主键架构会影响其他表中外键的架构,那么使用它们将是一个非常有说服力的论据。但真的是这样吗?
例如,假设我有一个主键为 id 的 USER 表,而我还有另一个表 BLOGGERS,其 blogger_id 是与 id。假设 id 最初被声明为 SMALLINT,但后来我有大量用户注册,我们需要增加 id 的可用范围。如果我将 id 更改为 INT,是否会自动将 BLOGGER 表中的 blogger_id 更改为 INT?
不管我的主要问题的答案如何,除了限制可以放置在该字段中的数据之外,有没有人知道正式声明外键约束的任何令人信服的理由?谢谢!
【问题讨论】:
标签:
mysql
foreign-keys
schema
constraints
【解决方案1】:
不,如果您更改父表中的数据类型,MySQL 不会更改子表中的数据类型。
我必须帮助我的一位咨询客户,他们的Users 表中的 INT 值已达到最大值。但是您可以想象,还有 30 个其他表引用了 Users。在我们可以更改 Users 表中的主键数据类型之前,我们必须在其他 30 个表中的每一个上 ALTER TABLE,因为如果子表无法引用新用户 ID,它将无法工作。
至于您关于外键的问题,是的,我确实推荐它们以确保数据完整性。在我分析过的每个尝试不使用外键的数据库中,它们在子表中都有很多孤立的行,没有自动检测它们的方法。
也就是说,网站放弃外键是很常见的,假设他们会在应用程序代码中“做正确的事”以避免孤立数据。
反对外键的一个论据是,外键的存在会产生一些您可能没有预料到的锁定情况。如果我更新子行,您希望它在事务期间锁定该行。但是如果你有一个外键,这个也会锁定外键引用的表中的父行。
示例:假设您有一个父表ShoppingCart 和一个子表LineItems。如果您更新LineItems 中的一行的数量,您的事务会在该行上创建一个排他锁(X 锁)。但它也会在ShoppingCart 的父行上创建一个共享锁(S 锁)。例如,当您正在处理引用它的行之一时,您不希望删除您所依赖的行是有道理的。
这是一个共享锁,所以多个事务可以同时拥有这种锁,但是如果你需要直接更新父行,而一个或多个客户端拥有那些隐式共享锁,你被挡住了。