Слияние баз данных, как обработать дублирующийся PK

Другой хороший вариант проверка lxml , который я нахожу довольно приятными использовать.

А простой пример, взятый от lxml сайта:

from StringIO import StringIO

from lxml import etree

dtd = etree.DTD(StringIO(""""""))
root = etree.XML("")
print(dtd.validate(root))
# True

root = etree.XML("bar")
print(dtd.validate(root))
# False
print(dtd.error_log.filter_from_errors())
# :1:0:ERROR:VALID:DTD_NOT_EMPTY: Element foo was declared EMPTY this one has content

7
задан Brian Tompsett - 汤莱恩 29 September 2016 в 20:53
поделиться

6 ответов

У меня нет личного опыта с этим, но мне кажется, что вы должны иметь возможность однозначно сопоставить 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 (при условии, что, как и я, данные на каждом сервере изолированы). Удачи.

3
ответ дан 7 December 2019 в 12:24
поделиться

BEST: add a column for RegionCode, and include it on your PKs, but you don't want to do all the leg work.

HACK: if your IDs are INTs, a quick fix would be to add a fixed value based on region to each key on import. INTs can be as large as: 2,147,483,647

local server data:

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

add 100000000 to LA's IDs
add 200000000 to SF's IDs
add 300000000 to NY's IDs

combined server data:

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
1
ответ дан 7 December 2019 в 12:24
поделиться

Я сделал это и говорю, измените ваши ключи (выберите метод) вместо того, чтобы изменять ваш код. Вы неизменно либо пропустите хранимую процедуру, либо внесете ошибку. При изменении данных довольно легко писать тесты для поиска потерянных записей или проверки правильности сопоставления. При изменении кода, особенно кода, который работает правильно, слишком легко что-то упустить.

1
ответ дан 7 December 2019 в 12:24
поделиться

One thing you could do is set up the tables with regional data to use GUID's. That way, the primary keys in each region are unique, and you can mix and match data (import data from one region to another). For the tables which have shared data (like type tables), you can keep the primary keys the way they are (since they should be the same everywhere).

Here is some information about GUID's: http://www.sqlteam.com/article/uniqueidentifier-vs-identity

Maybe SQL Server Management Studio lets you convert columns to use GUID's easily. I hope so!

Best of luck.

0
ответ дан 7 December 2019 в 12:24
поделиться

what i have done in a situation like this is this:

  1. create a new db with the same schema but only tables. no pk fk, checks etc.
  2. transfer data from DB1 to this source db
  3. for each table in target database find the top number for the PK
  4. for each table in the source database update their pk, fk etc starting with the (top number + 1) from the target db
  5. for each table in target database set identity insert to on
  6. import data from source db to target db
  7. for each table in target database отключить вставку идентификатора
  8. очистить исходную базу данных
  9. повторить для DB2
0
ответ дан 7 December 2019 в 12:24
поделиться

Как сказал Джон, я бы использовал 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 (обновите, как показано выше).

Теперь вы создаете свою целевую базу данных. В этой целевой базе данных вы также добавляете столбцы UID для всех PK и FK. Также отключите все ограничения 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 PERSON_UID

Итак, в конце вы должны получить довольно длинный сценарий миграции, который должен сделать всю работу за вас. Дело в том, что - ЭТО ВЫПОЛНЕНО

ПРИМЕЧАНИЕ: все написанное здесь не проверено.

0
ответ дан 7 December 2019 в 12:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: