如何合并具有自动编号主键的表格?

8
我想每个人都会偶尔遇到这样的问题:你有两个具有自动编号主键的表需要合并。使用自动编号主键而不是应用程序生成的键有很多好处,但与其他表合并必须是最大的缺点之一。
一些问题会出现重叠的ID和不同步的外键。我想听听您解决此问题的方法。我总是遇到问题,所以我非常好奇是否有人有某种通用解决方案。
--编辑--
针对建议使用guid或其他非数字键的答案,有时提前使用自动编号键似乎是更好的选择(并且后悔了),或者你正在接管别人的项目,或者你得到一些要处理的旧数据库。因此,我真正寻求的是在没有对数据库设计进行控制的情况下的解决方案。
5个回答

4
解决方案包括:
  • 使用GUID作为主键,而不是更简单的标识字段。这很可能避免重叠,但GUID更难使用,并且与聚集索引不兼容。

  • 将主键变成多列键,第二列通过识别合并数据源来解决重叠值。可移植,与聚集索引配合得更好,但开发人员不喜欢多列键。

  • 使用自然键而不是伪键。

  • 为合并表中的一个分配新的主键值,并将这些更改级联到任何相关行。这将把合并操作转换为ETL操作。如果无法更改数据库设计,则这是您可以用于遗留数据的唯一解决方案。

我不确定是否有适合所有情况的解决方案。根据情况选择其中之一。


3

嗯,我对在AlexKuznetsov的答案中发表评论的想法感到热情,所以我将就此做出完整的回答。

考虑将表命名为table1和table2,id1和id2作为自动编号主键。它们将合并到带有id3(非自动编号主键)的table3中。

为什么不:

  1. 删除所有对table1和table2的外键约束
  2. 对于所有指向table1的外键字段,执行UPDATE table SET id1 = id1 * 2,对于指向table2的FK字段,执行UPDATE table SET id2 = (id2) * 2 + 1
  3. 通过执行INSERT INTO table3 SELECT id1 * 2 AS id3, ... FROM table1 UNION ALL SELECT id2 * 2 + 1 AS id3 FROM table2来填充table3
  4. 创建新的对table3的外键约束

甚至可以通过使用更高的乘数处理3个或更多个表。


1

如果你在设计时考虑到这种情况,其中一个标准方法(如果不是唯一的标准方法)就是使用GUID作为主键而不是整数——合并数据就相对容易,因为你保证不会遇到重叠。

除非重新设计,否则我认为你只能将数据插入表中,接受新的主键,并确保你维护旧ID到新ID的映射,然后插入引用数据并重新映射外键等等。如果你的数据有一个“业务键”,在插入后仍然保持唯一,这将节省跟踪映射的工作。


1

如果您确定只有这两个表,您可以将偶数ID放在一个表中(0、2、4、6、...),将奇数ID放在另一个表中(1、3、5、7、...)


这个问题更多地是以一种通用的方式提出的,而不是你事先知道会发生什么(因为那样的话,你可以使用 GUID)。 - Carvellis
在编程中,似乎有一个不错的想法,对于第一个表计算新的ID = 旧的ID * 2,对于第二个表计算新的ID = (旧的ID * 2) + 1。如果你对所有相关的表都这样处理,那么所有的匹配关系将会重新恢复,你可以重新启用外键约束。 - littlegreen

1

假设您在要合并的表中也有自然键,则该过程并不困难。自然键用于去重和正确重新分配任何引用。您可以随时重新编号代理键值 - 这是使用代理键的主要优势之一。

因此,我认为代理键并不是问题 - 前提是您始终强制执行自然键(实际上,我更喜欢术语“业务键”)。如果这些表没有业务键,那么现在可能是重新设计以正确实施所有必要键的好时机。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接