如何将表与自动编号主键合并?

时间:2010-09-29 18:19:31

标签: sql-server database-design identity-column

我想每个人偶尔遇到这个问题:你有两个表有自动编号需要合并的主键。使用自动编号主键有利于说应用程序生成的密钥有很多很好的理由,但与其他表合并必然是最大的缺点之一。

出现的一些问题是重复的ID和不同步的外键。我想听听你解决这个问题的方法。我总是遇到问题,所以如果有人有某种一般的解决方案,我会很好奇。

- 编辑 -

在回答建议使用guid或其他非数字键的答案时,有些情况事先提醒使用自动编号键(后来你后悔),或者你是在接管某人else的项目,或者你得到一些你必须使用的遗留数据库。所以我真的在寻找一种无法控制数据库设计的解决方案。

5 个答案:

答案 0 :(得分:4)

解决方案包括:

  • 使用GUID作为主键而不是更简单的标识字段。很可能避免重叠,但GUID更难以使用,并且不能很好地与聚簇索引一起使用。

  • 将主键设为多列键,第二列通过识别合并数据的来源来解析重叠值。便携式,适用于聚簇索引,但开发人员讨厌多列密钥。

  • 使用自然键代替伪。。

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

我不确定这是一个万能的解决方案。根据具体情况选择其中一种。

答案 1 :(得分: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
  4. 填写表格3
  5. 为table3创建新的外键约束
  6. 它甚至可以使用3个或更多表,只需使用更高的乘数。

答案 2 :(得分:1)

标准方法之一(如果不是 标准方法),你正在设计这种可能性,就是使用GUID作为主键而不是整数 - 合并然后相对无痛保证不会遇到重叠。

除非重新设计,否则,我认为你不得不插入表中,接受你将获得新的主键,并确保你保持从旧到新ID的映射 - 然后插入引用数据与FK重新映射等。如果您的数据有一个“业务键”,插入后将保持唯一,这将节省必须跟踪映射。

答案 3 :(得分:1)

如果你确定你只有两个这样的表,你可以在一个表(0,2,4,6,...)中使用偶数ID,在另一个表中使用奇数ID(1,3,5,7, ...)

答案 4 :(得分:1)

假设您在要合并的表中也有一个自然键,那么该过程并不困难。自然键用于重复数据删除和正确重新分配任何引用。您可以随时重新编号代理键值 - 这是首先使用代理项的主要优点之一。

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