Vin*_*rat 38

人们普遍认为主键应该是不可变的(或者尽可能稳定,因为不能在DB中强制执行不变性).虽然没有任何东西可以阻止您更新主键(完整性约束除外),但这可能不是一个好主意:

从性能的角度来看:

  • 您将需要更新引用更新密钥的所有外键.单个更新可能导致更新可能的大量表/行.
  • 如果外键未编入索引(!!),则必须在子表上保持锁定以确保完整性.甲骨文只会在很短的时间内锁定,但这仍然很可怕.
  • 如果您的外键被索引(因为它们应该是),更新将导致更新索引(删除+插入索引结构),这通常比基表的实际更新更昂贵.
  • 在ORGANIZATION INDEX表中(在其他RDBMS中,请参阅聚簇主键),行按主键进行物理排序.逻辑更新将导致物理删除+插入(更昂贵)

其他考虑:

  • 如果在任何外部系统(应用程序缓存,另一个数据库,导出...)中引用此密钥,则更新时将引用该引用.
  • 另外,一些RDBMS不支持CASCADE UPDATE,特别是Oracle.

总之,在设计过程中,使用代理键代替应该不会改变的自然主键通常更安全 - 但最终可能需要更新,因为需求更改甚至数据输入错误.

如果您必须使用子表更新主键,请参阅Tom Kyte的这篇文章以获得解决方案.

  • 我会说稳定性更常被认为是PK的理想属性而不是不变性.[实施例](http://stackoverflow.com/questions/3632726/what-are-the-design-criteria-for-primary-keys/3668234#3668234) (5认同)
  • @Martin:我理解这种区别,但我认为*物理* 主键(即您在数据库中定义的那个)应该是不可变的。*概念数据模型*的主键应该具有您提供的链接的答案中给出的属性,但可能与最终的物理主键不同(例如,熟悉度不是 IMO 实际表主键的标准)。我的回答与物理模型的主键有关。 (2认同)

nvo*_*gel 10

主键属性与表的任何其他属性一样可更新.稳定性通常是关键的理想属性,但绝对不是绝对要求.如果从业务角度更新密钥是有意义的,那么没有根本原因你不应该这样做.


Ric*_*ard 6

你可以只要

  • 价值是独一无二的
  • 没有违反现有外键


小智 6

从关系数据库理论的角度来看,更新表的主键绝对没有问题,前提是主键之间没有重复,并且您不尝试在任何主键中放置 NULL 值关键列。


Man*_*dan 2

简短的回答:是的,可以。当然,您必须确保新值与任何现有值都不匹配,并且满足其他约束(废话)。

你到底想做什么?