Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何合并具有自动编号主键的表?_Sql Server_Database Design_Identity Column - Fatal编程技术网

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

Sql server 如何合并具有自动编号主键的表?,sql-server,database-design,identity-column,Sql Server,Database Design,Identity Column,我想每个人都会偶尔遇到这个问题:有两个表具有需要合并的自动编号主键。使用autonumber主键支持应用程序生成的键有很多原因,但与其他表合并肯定是最大的缺点之一 出现的一些问题是ID重叠和外键不同步。我想听听你解决这个问题的方法。我总是遇到问题,所以我很好奇是否有人有某种通用的解决方案 --编辑-- 作为对建议使用guid或其他非数字键的回答的回应,在某些情况下,提前使用自动编号键似乎是一个更好的主意(稍后您会后悔),或者您接管了其他人的项目,或者您得到了一些必须使用的遗留数据库。因此,我真的

我想每个人都会偶尔遇到这个问题:有两个表具有需要合并的自动编号主键。使用autonumber主键支持应用程序生成的键有很多原因,但与其他表合并肯定是最大的缺点之一

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

--编辑--

作为对建议使用guid或其他非数字键的回答的回应,在某些情况下,提前使用自动编号键似乎是一个更好的主意(稍后您会后悔),或者您接管了其他人的项目,或者您得到了一些必须使用的遗留数据库。因此,我真的在寻找一种解决方案,使您不再能够控制数据库设计。

解决方案包括:

  • 使用guid作为主键,而不是简单的标识字段。很有可能避免重叠,但guid更难使用,而且不能很好地处理聚集索引

  • 将主键转换为多列键,第二列通过标识合并数据的源来解析重叠值。可移植,可以更好地使用聚集索引,但开发人员讨厌多列键

  • 使用自然关键点而不是伪关键点

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


我不确定是否有一刀切的解决方案。根据具体情况选择其中一种方法。

其中一种标准方法(如果不是标准方法)是使用guid作为主键,而不是整数,因为可以保证不会遇到重叠


除非重新设计,tho',我认为您必须插入到表中,接受您将获得新的主键,并确保您维护从旧ID到新ID的映射,然后使用FK重新映射等插入引用数据。如果您的数据具有“业务密钥”,在插入后将保持唯一性,这将节省跟踪映射的时间。

如果您确信您只有两个这样的表,那么您可以在一个表中有偶数ID(0,2,4,6,…),在另一个表中有奇数ID(1,3,5,7,…)

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


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

Hm,我对我刚刚在AlexKuznetsov的答案中添加注释的想法有点热情,所以我将给出一个完整的答案

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

为什么不:

  • 删除表1和表2的所有外键约束
  • 对于引用表1的所有外键字段,执行更新表集id1=id1*2,对于引用表2的FK字段,执行更新表集id2=(id2)*2+1
  • 通过执行插入到表3中的
    来填充表3,选择id1*2作为id3。。。从表1中选择id2*2+1作为表2中的id3
  • 为表3创建新的外键约束

  • 它甚至可以处理3个或更多的表,只需使用更高的乘数。

    这个问题更多的是以一种通用的方式来解决,而不是在你事先知道会发生什么的地方(因为那时你可以使用guid)。不过,对于第一个表,计算new\u id=old\u id*2,计算new\u id=(old\u id*2)似乎是个主意第二张桌子+1。如果对所有涉及的表执行此操作,所有内容都将再次匹配,并且可以重新启用外键约束。