我们有三个按地区分开的数据库,一个在LA,SF和NY。所有数据库共享相同的模式,但包含特定于其区域的数据。我们希望将这些数据库合并为一个并对其进行镜像。我们需要保留每个区域的数据,但是将它们合并到一个db中。这给我们带来了很多问题,例如我们肯定会有重复的主键,外键可能会无效。
我希望找到一个有过这样一个任务经验的人,他可以提供一些关于我们如何完成合并的技巧,策略和经验。
例如,一个想法是创建复合键,然后更改我们的代码和sprocs以通过复合键(region / original pk)查找数据。但这要求我们改变所有代码和代码。
另一个想法是只导入数据并让它生成新的PK,然后更新所有对新PK的FK引用。这样我们就不必更改任何代码。
欢迎任何经验!
答案 0 :(得分:3)
我没有这方面的第一手经验,但在我看来,你应该能够独特地映射PK - >每个服务器的新PK。例如,生成新的PK,使得来自LA服务器的数据具有PK%3 == 2,SF具有PK%3 == 1,并且NY具有PK%3 == 0.并且因为,正如我理解您的问题,无论如何服务器只将FK关系存储到自己的数据中,您可以以相同的方式更新FK。
NewLA = OldLA*3-1
NewSF = OldLA*3-2
NewNY = OldLA*3
然后您可以合并这些并且没有重复的PK。正如您已经说过的,这基本上只是生成新的PK,但是以这种方式构造它可以让您轻松更新您的FK(假设,正如我所做的那样,每个服务器上的数据都是隔离的)。祝你好运。
答案 1 :(得分:1)
BEST:为RegionCode添加一个列,并将其包含在您的PK中,但您不想完成所有的工作。
HACK:如果您的ID是INT,快速解决方法是在导入时为每个键添加基于区域的固定值。 INT可以大到:2,147,483,647
本地服务器数据:
LA IDs: 1,2,3,4,5,6
SF IDs: 1,2,3,4,5
NY IDs: 1,2,3,4,5,6,7,9
向LA的ID添加100000000 将200000000添加到SF的ID中 添加300000000到NY的ID
组合服务器数据:
LA IDs: 100000001,100000002,100000003,100000004,100000005,100000006
SF IDs: 200000001,200000002,200000003,200000004,200000005
NY IDs: 300000001,300000002,300000003,300000004,300000005,300000006,300000007,300000009
答案 2 :(得分:1)
我已经这样做了,我说改变你的密钥(选择方法)而不是改变你的代码。您总是会错过存储过程或引入错误。通过更改数据,编写测试以查找孤立记录或验证事物是否正确匹配非常容易。随着代码更改,特别是正常运行的代码,很容易错过。
答案 3 :(得分:0)
您可以做的一件事是使用区域数据设置表以使用GUID。这样,每个区域中的主键都是唯一的,您可以混合和匹配数据(将数据从一个区域导入另一个区域)。对于具有共享数据的表(如类型表),您可以保持主键的方式(因为它们应该在任何地方都相同)。
以下是有关GUID的一些信息: http://www.sqlteam.com/article/uniqueidentifier-vs-identity
也许SQL Server Management Studio允许您将列转换为轻松使用GUID。我希望如此!
祝你好运。
答案 4 :(得分:0)
我在这种情况下所做的是:
答案 5 :(得分:0)
正如Jon所说,我会使用GUID来解决合并任务。我看到两种不同的解决方案需要GUID:
这通常是一个很好的解决方案,但如果你有很多非SQL代码以某种方式绑定到你的标识符的工作方式,它可能需要相当多的代码更改。 可能因为您合并数据库,您可能无论如何都需要更新您的应用程序,以便它仅使用基于登录用户的一个区域数据等。
这个有点棘手,但是一旦你编写了这个迁移脚本,你可以(重新)多次运行它来再次合并数据库,以防你第一次搞砸它。这是一个例子:
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 COLUMN UID ALTER TABLE ADDRESS DROP COLUMN UID ALTER TABLE ADDRESS DROP COLUMN PERSON_UID
所以最后你应该得到一个相当长的迁移脚本,它应该为你完成这项工作。重点是 - 可行
注意:此处所有内容均未经过测试。