11

两个数据库具有相同的架构,但它们可能会与某些表中的主键发生冲突。所以我希望他们忽略重复的行,并继续进一步合并。

4

6 回答 6

10

首先,密钥冲突表明您当前使用的任何进程都是一个糟糕的进程。

要正确合并使用自动生成 (non_GUID) 键的两个数据库,您需要采取几个步骤。首先向父表添加一个新的自动生成的键,然后从两个表中导入所有数据,将旧的旧文件重命名为 ID_old,并将新文件重命名为旧的 id 名称。此时,您可以继续移动子表。您需要通过加入父表并将新的 id 字段作为外键的值而不是现有表中的值来复制到子表。您将需要对每个外键表重复此过程,如果该表也是父表,则需要在复制任何数据之前将 conversionid 字段添加到表中,以便您可以一直工作. 要正确地做到这一点,需要大量的数据库结构知识和大量计划。如果没有对两个源数据库进行良好备份,请不要考虑这样做。如果两个数据库都处于单用户模式时,该过程也可以发生,这也是最好的。

如果您使用自然键并且有重复项,那么您的问题就大不相同了。所有重复的关键记录都应该首先移动到一个单独的表中,并确定哪个是更正确的数据。在某些情况下,您会发现自然键实际上不是唯一的(它们很少是唯一的,这就是我几乎从不使用它们的原因)并且合并的数据库将需要使用某种类型的自动生成的键。这将涉及代码更改以及数据库更改,因此这是最后的选择。

使用自然键经常发现的是,每个键的数据都不同但相似(地址中的圣副街)在这种情况下标记要插入的记录之一,然后在分两步进行插入时,首先是记录没有重复项,然后是重复表中标记为插入的记录。请记住,您必须检查所有外键表中的所有记录,以确定保留哪些和不保留哪些。仅仅丢弃任何重复项是一个坏主意,这样您将丢失数据,可能是关键数据(例如客户的订单)。这是一个冗长乏味的过程,需要具有数据专业知识的人来做出决定。作为程序员,您应该为他们提供一个重复数据删除工具,让他们检查每组重复项的所有数据,并选择要保留的内容和要删除的内容,然后标记所有内容,它将运行一个插入记录的过程。请记住,在您的设计中,对于真正的重复项,将有一些子表(例如 orders )需要将两者的记录发送到数据库以选择要输入的记录(orders 是一个示例),对于其他表您将要选择哪个是正确的(例如地址)。所以你可以看到这是一个复杂的过程,需要对数据库有透彻的了解。将有一些子表(例如 orders )需要将两者的记录发送到数据库以选择要输入的记录(orders 是一个例子),对于其他表,您将要选择哪个是正确的(地址例如)。所以你可以看到这是一个复杂的过程,需要对数据库有透彻的了解。将有一些子表(例如 orders )需要将两者的记录发送到数据库以选择要输入的记录(orders 是一个例子),对于其他表,您将要选择哪个是正确的(地址例如)。所以你可以看到这是一个复杂的过程,需要对数据库有透彻的了解。

如果你有很多重复,他们可能会清理并添加几个月的数据,所以一个工具真的很重要。这样做的人很可能是系统用户,而不是数据库专家或程序员,因为他们是唯一能够真正判断要保留哪些记录的人。在任何情况下您都可能需要做一些类似的事情,因为即使您拥有自动生成的密钥,也可能存在重复的记录。他们只是更难找到。

没有简单的方法可以合并两个数据库(即使使用 GUIDS,自然键也会出现重复的问题)。

于 2009-05-26T13:58:07.677 回答
7

我知道这是一个老话题,但我必须评论我在许多帖子中看到的一般方法,即尝试使用 SQL 查询本地完成所有事情。这些解决方案的共同点是在应用查询之前需要花费大量时间来创建和测试查询。

所以是的——您可以使用相对复杂的查询本地合并两个数据库,但您可以节省大量时间并免费使用第三方工具(大多数或全部都有功能齐全的免费试用版)。

市场上有很多这样的东西。Red Gate,已经在其他帖子中提到,是最好的之一,但您也可以尝试ApexSQL Data DiffdbForgeSQL 比较工具集和许多其他工具。

于 2013-07-24T11:25:58.570 回答
4

最好的选择可能是使用第 3 方应用程序,例如RedGate SQL Data Compare。花费一些钱,但编写该脚本 IMO 是值得的。

于 2009-05-26T08:22:30.893 回答
3

这是我近年来两次这样做的方式:http: //byalexblog.net/merge-sql-databases

于 2016-05-27T08:57:01.967 回答
1

因为如果你有主键作为 IDENTITY 这是我的建议(不应该需要修改架构)。

  1. 设置所有外键,以便ON UPDATE CASCADE设置
  2. 更新父表中的主键/标识字段,并添加您要合并到的相应表的字段的最大值(然后 FK 会将值级联到子表)
  3. 对子表中的 PK / IDENTITY 字段执行相同操作
  4. 按照这个论坛答案的建议,在插入每个表的任一侧使用SET IDENTITY_INSERTON / OFF,从父表开始,然后转到子表
于 2010-04-27T17:34:05.107 回答
0

您可以在合并数据库中的所有表中添加一个附加字段(例如称为 DatabaseID),并将其添加到主键中。这样,您可以保留原始键,同时在合并数据库中拥有唯一键 - 并且您可以判断该行来自哪个数据库。这就是SQL-Hub所做的 - 如果它只是一项临时工作,您可以通过免费试用来做到这一点。

于 2016-02-11T10:28:46.697 回答