正如 Jon 所提到的,我会使用 GUID 来解决合并任务。而且我看到了两种需要 GUID 的不同解决方案:
1) 永久更改您的数据库架构以使用 GUID 而不是 INTEGER (IDENTITY) 作为主键。
一般来说这是一个很好的解决方案,但是如果您有很多非 SQL 代码以某种方式绑定到您的标识符的工作方式,则可能需要进行相当多的代码更改。 可能由于您合并数据库,您可能无论如何都需要更新您的应用程序,以便它仅根据登录用户等处理一个区域数据。
2) 临时添加 GUID 仅用于迁移目的,数据迁移后删除:
这个有点棘手,但是一旦你编写了这个迁移脚本,你可以(重新)多次运行它来再次合并数据库,以防你第一次搞砸了。这是一个例子:
Table: PERSON (ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL)
Table: ADDRESS (ID INT PRIMARY KEY, City VARCHAR(100) NOT NULL, PERSON_ID INT)
您的更改脚本是(请注意,对于所有 PK,我们会自动生成 GUID):
ALTER TABLE PERSON ADD UID UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWID())
ALTER TABLE ADDRESS ADD UID UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWID())
ALTER TABLE ADDRESS ADD PERSON_UID UNIQUEIDENTIFIER NULL
然后您将 FK 更新为与 INTEGER 一致:
--// set ADDRESS.PERSON_UID
UPDATE ADDRESS
SET ADDRESS.PERSON_UID = PERSON.UID
FROM ADDRESS
INNER JOIN PERSON
ON ADDRESS.PERSON_ID = PERSON.ID
您为所有 PK(自动生成 GUID)和 FK(如上所示更新)执行此操作。
现在您创建目标数据库。在此目标数据库中,您还可以为所有 PK 和 FK 添加 UID 列。同时禁用所有 FK 约束。
现在您从每个源数据库插入目标数据库(注意:我们不插入 PK 和整数 FK):
INSERT INTO TARGET_DB.dbo.PERSON (UID, NAME)
SELECT UID, NAME FROM SOURCE_DB1.dbo.PERSON
INSERT INTO TARGET_DB.dbo.ADDRESS (UID, CITY, PERSON_UID)
SELECT UID, CITY, PERSON_UID FROM SOURCE_DB1.dbo.ADDRESS
从所有数据库中插入数据后,运行与原始代码相反的代码以使整数 FK 与目标数据库上的 GUID 一致:
--// set ADDRESS.PERSON_ID
UPDATE ADDRESS
SET ADDRESS.PERSON_ID = PERSON.ID
FROM ADDRESS
INNER JOIN PERSON
ON ADDRESS.PERSON_UID = PERSON.UID
现在您可以删除所有 UID 列:
ALTER TABLE PERSON DROP 列 UID
更改表地址删除列 UID
ALTER TABLE ADDRESS DROP COLUMN PERSON_UID
所以最后你应该得到一个相当长的迁移脚本,它应该可以为你完成这项工作。关键是 - 这是可行的
注意:这里写的都没有经过测试。