更改 Oracle 中的主键
Changing Primary Key in Oracle
我正在更新一个 table 原本设计不佳的。 table 当前有一个主键,它是供应商的名称。这用作许多其他 table 的外键。这导致最初输入供应商名称不正确或需要修复拼写错误的问题。因为它是关系的外键,所以这比它的价值更复杂。
当前架构:
Vendor_name(pk)Vendor_contact 评论
所需架构:
id(pk) Vendor_name Vendor_contact 评论
我想将主键更新为自动生成的数字键。供应商名称字段需要保留但不再是关键。我还需要更新其他 tables 和加入 tables.
上的外键值
最好的方法是在我的供应商 table 上创建一个新的数字 id 列,将 id 横穿到供应商名称并添加一个新的外键,并将新的 id 作为外键,删除table 上的供应商名称的外键(每个 this post),然后以某种方式将 id 标记为主键并取消标记供应商名称?
或者是否有更简化的方法来完成此操作?
请务必注意,只有 5 个用户可以访问此 table,因此在进行这些更新时我可以轻松地将他们关闭一段时间 - 这不是问题。
我正在使用 SQLDeveloper 和 Python/Django。
我会这样做:
- 创建新序列
- 创建 table temp as select your_sequence.nextval、vendor_name、vendor_contact,来自供应商的评论。
- 将原来的 table 重命名为 vendor_old
- 将主键和其他约束添加到新的 table
- 将新 table 重命名为旧名称
测试是必不可少的,您必须确保测试完成后除了您之外没有人在处理数据库。
您遇到的最大问题是所有引用 VENDOR_NAME 从属 table 的应用程序代码。不只是用它来加入父table,还依赖它来显示名称而不加入VENDOR。
因此,尽管将自然键作为外键是一个 PITN,但改变这种情况可能会产生大量工作,整体收益微乎其微。在开始之前一定要得到所有利益相关者的支持。
我的处理方式是这样的:
- 进行真正彻底的影响分析
- 确保您对依赖供应商数据的所有功能进行了完整的回归测试
- 创建 VENDOR_ID 作为 VENDOR
上的唯一键
- 将VENDOR_ID添加到所有依赖table
- 在所有引用 VENDOR_ID
的依赖 table 上创建第二个外来对象
- 确保在 VENDOR_NAME 存在时填充 VENDOR_ID。
最后一点可以通过修复相关 table 上的插入和更新语句或使用触发器来解决。您采用哪种方法将决定您的应用程序设计以及所涉及的 table 的数量。显然,如果可以的话,您希望避免所有这些触发器的性能下降。
此时您拥有一个支持新主键但仍使用旧主键的基础结构。你为什么想做这个?因为您可以像这样进入生产环境而无需更改应用程序代码。它使您可以选择移动应用程序代码以在更广泛的时间范围内使用 VENDOR_ID。显然,如果开发人员一直热衷于编码 SELECT * FROM
,您就会遇到需要立即解决的问题。
一旦你修复了所有代码,你就可以从所有依赖的 table 中删除 VENDOR_NAME,并将 VENDOR_NAME 切换为唯一键,将 VENDOR_ID 切换为主键主键 table.
如果您使用的是 11g,则应查看基于版本的重新定义。它旨在使这种练习变得非常容易。 Find out more.
我正在更新一个 table 原本设计不佳的。 table 当前有一个主键,它是供应商的名称。这用作许多其他 table 的外键。这导致最初输入供应商名称不正确或需要修复拼写错误的问题。因为它是关系的外键,所以这比它的价值更复杂。
当前架构: Vendor_name(pk)Vendor_contact 评论
所需架构: id(pk) Vendor_name Vendor_contact 评论
我想将主键更新为自动生成的数字键。供应商名称字段需要保留但不再是关键。我还需要更新其他 tables 和加入 tables.
上的外键值最好的方法是在我的供应商 table 上创建一个新的数字 id 列,将 id 横穿到供应商名称并添加一个新的外键,并将新的 id 作为外键,删除table 上的供应商名称的外键(每个 this post),然后以某种方式将 id 标记为主键并取消标记供应商名称?
或者是否有更简化的方法来完成此操作?
请务必注意,只有 5 个用户可以访问此 table,因此在进行这些更新时我可以轻松地将他们关闭一段时间 - 这不是问题。
我正在使用 SQLDeveloper 和 Python/Django。
我会这样做:
- 创建新序列
- 创建 table temp as select your_sequence.nextval、vendor_name、vendor_contact,来自供应商的评论。
- 将原来的 table 重命名为 vendor_old
- 将主键和其他约束添加到新的 table
- 将新 table 重命名为旧名称
测试是必不可少的,您必须确保测试完成后除了您之外没有人在处理数据库。
您遇到的最大问题是所有引用 VENDOR_NAME 从属 table 的应用程序代码。不只是用它来加入父table,还依赖它来显示名称而不加入VENDOR。
因此,尽管将自然键作为外键是一个 PITN,但改变这种情况可能会产生大量工作,整体收益微乎其微。在开始之前一定要得到所有利益相关者的支持。
我的处理方式是这样的:
- 进行真正彻底的影响分析
- 确保您对依赖供应商数据的所有功能进行了完整的回归测试
- 创建 VENDOR_ID 作为 VENDOR 上的唯一键
- 将VENDOR_ID添加到所有依赖table
- 在所有引用 VENDOR_ID 的依赖 table 上创建第二个外来对象
- 确保在 VENDOR_NAME 存在时填充 VENDOR_ID。
最后一点可以通过修复相关 table 上的插入和更新语句或使用触发器来解决。您采用哪种方法将决定您的应用程序设计以及所涉及的 table 的数量。显然,如果可以的话,您希望避免所有这些触发器的性能下降。
此时您拥有一个支持新主键但仍使用旧主键的基础结构。你为什么想做这个?因为您可以像这样进入生产环境而无需更改应用程序代码。它使您可以选择移动应用程序代码以在更广泛的时间范围内使用 VENDOR_ID。显然,如果开发人员一直热衷于编码 SELECT * FROM
,您就会遇到需要立即解决的问题。
一旦你修复了所有代码,你就可以从所有依赖的 table 中删除 VENDOR_NAME,并将 VENDOR_NAME 切换为唯一键,将 VENDOR_ID 切换为主键主键 table.
如果您使用的是 11g,则应查看基于版本的重新定义。它旨在使这种练习变得非常容易。 Find out more.