我有一个相当庞大的数据库,其主表包含单个列GUID(自定义GUID,如算法)作为主键,8个子表与此GUID列具有外键关系。所有表格都有大约3-8百万条记录。这些表中没有任何一个具有任何BLOB / CLOB / TEXT或任何其他奇特的数据类型,只是普通数字,变量,日期和时间戳(每个表中大约15-45列)。除主键和外键之外没有分区或其他索引。
现在,自定义GUID算法已更改,虽然没有冲突,但我希望迁移所有旧数据以使用使用新算法生成的GUID。不需要更改其他列。第一优先级是数据完整性,性能是次要的。
我能想到的一些可能的解决方案(因为你可能会注意到它们都只围绕一个想法)
on update cascade
我的问题是:
如果你到目前为止和我在一起,谢谢,并希望你可以提供帮助:)
答案 0 :(得分:2)
你的想法应该有效。第一个可能是我会用的方式。这样做时需要考虑的一些注意事项和事项:
除非您有当前备份,否则请勿这样做
我会在主表中留下这两个值。这样,如果你必须从一些旧的文书工作中找出你需要访问的记录,你就可以做到。
执行此操作时,请将数据库关闭以进行维护,并将其置于单用户模式。在做这样的事情时,你需要的最后一件事是用户在你处于中游时尝试进行更改。当然,单用户模式下的第一个动作是上述备份。当使用率最轻时,您可能应该将停机时间安排一段时间。
首先测试开发!这也应该让您了解需要多长时间才能完成生产。此外,您可以尝试几种方法来查看哪种方法最快
请务必提前告知用户数据库将在预定的维护时间内停止运行以及何时可以再次使用。确保时机正常。当他们计划延迟运行季度报告并且数据库不可用而且他们不知道时,这真的让人很生气。
有相当多的记录,您可能希望批量运行子表的更新(不使用级联更新的一个原因)。这比尝试通过一次更新更新500万条记录要快得多。但是,不要尝试一次更新一条记录,否则明年你仍然会在这里完成这项任务
删除所有表中GUID字段的索引,并在完成后重新创建。这应该会改善变化的表现。
答案 1 :(得分:0)
创建一个包含旧pk值和新pk值的新表。在两列上放置唯一约束,以确保您到目前为止没有破坏任何内容。
禁用约束。
对所有表运行更新,将旧值修改为新值。
启用PK,然后启用FK。
答案 2 :(得分:0)
很难说“最佳”或“最合适”的方法是什么,因为您没有在解决方案中描述您正在寻找的内容。例如,在迁移到新ID时,表是否需要可用于查询?他们是否需要同时进行修改?尽可能快地完成迁移很重要吗?最小化用于迁移的空间是否重要?
话虽如此,如果他们都符合您的要求,我宁愿选择#1优于其他想法。
任何涉及更新子表的触发器的事情似乎容易出错并且过于复杂,并且可能不会像#1那样表现良好。
假设新ID永远不会与旧ID冲突,这是否安全?如果没有,基于一次更新一个ID的解决方案将不得不担心碰撞 - 这将匆忙变得混乱。
您是否考虑过使用CREATE TABLE AS SELECT
(CTAS)使用新ID填充新表?您将复制现有表,这将需要额外的空间,但它可能比更新现有表更快。这个想法是:(i)使用CTAS创建新表,用新ID代替旧表,(ii)根据新表创建索引和约束,(iii)删除旧表,(iv)重命名新表旧表名称。
答案 3 :(得分:0)
实际上,它取决于您的RDBMS。
使用Oracle,最简单的选择是使所有外键约束“延迟”(检查提交),在单个事务中执行更新,然后提交。