Хитрая задачка: интеграция таблиц клиентов из разных БД
От: michag  
Дата: 05.11.08 12:57
Оценка:
Перед нами стоит задача интегрирования нескольких баз данных, различных видов (Oracle, SQL Server) и имеющих различную структуру.

Ранее на форуме я задавал вопрос о том, имеются ли стандартные способы решения задачи такого рода, на что не получил достаточного количества ответов и отзывов. Один из ответивших сказал, что лучше реализовывать такой механизм вручную.

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

Преположим, что у нас есть 2 базы данных (Oracle, SQL Server 2000), в каждой из которых имеется таблица клиентов. Это разные таблицы, имеющие разную структуру данных, и сами данные (клиенты) в этих таблицах разные. Для наглядности можем считать, что в Oracle содержатся клиенты-юрлица (ClientsCompanies), а в SQL Server 2000 — клиенты-физлица (ClientsPeople).

Перед нами стоит задача разработка еще одной базы данных (на этот раз SQL Server 2005), в которой была бы таблица AllClients, в которой содержались бы данные из двух перечисленных выше таблиц.

Задача состоит в том, чтобы в таблице AllClients всегда находились актуальные данные из двух других таблиц — то есть данные должны быть синхронизированы в режиме real-time (или с совсем небольшой задержкой).

Вот такая задача. Как ее реализовать?

Я приведу решение, к которому я пришел — но т. к. я не специализируюсь на БД и на SQL, мое решение может оказаться не самым лучшим.

1) В БД SQL Server 2005 (главной БД, в которой таблица AllClients) создаются таблицы ClientsCompanies и ClientsPeople, имеющие в точности такие же структуры, как и соответствующие таблицы в двух исходных БД.

2) С помощью некоторого механизма (простого копирования, репликации и др.) данные из исходных таблиц переносятся в таблицы в SQL Server 2005.

3) В SQL Server 2005 я создаю дополнительную таблицу соответствий идентификаторов, имеющую следующую структуру.

а) SourceTable = "ClientsCompanies" | "ClientsPeople".
б) ExternalClientId — идентификатор клиента в таблице внешней БД (т. е. идентификатор клиента в таблице ClientsCompanies или ClientsPeople).
в) ClientId — идентификатор клиента в таблице "AllClients".

4) Делаю View, которое возвращает клиентов из таблиц ClientsCompanies и ClientsPeople, а идентификаторы берет из таблицы соответствий.

То есть в реальности таблицы AllClients не будет — будет виртуальная таблица / представление, которое будет содержать клиентов из двух внешних таблиц, при этом клиенты в таблице AllClients будут иметь уникальные идентификаторы.

5) При добавлении или удалении клиентов из таблиц ClientsCompanies и ClientsPeople обновляем таблицу соответствий идентификаторов.

Вот это хитрая часть — как раз хотел спросить, как лучше реализовать такое авообновление таблицы соответствий идентификаторов — напишу вопрос в виде отдельной темы.

Хмм... Понятно ли то, что я написал? Мне кажется, что не очень — хотя старался написать понятно )

В любом случае — кто может какие дать советы по решению данной задачи? Спасибо!
Re: Хитрая задачка: интеграция таблиц клиентов из разных БД
От: michag  
Дата: 05.11.08 14:28
Оценка:
Здравствуйте, michag, Вы писали:

M>Перед нами стоит задача интегрирования нескольких баз данных, различных видов (Oracle, SQL Server) и имеющих различную структуру.


Ответов нет... Неужели никто не решал подобную задачу? Мне кажется, что интеграция разных систем и баз данных — одна из самых типичных и распространенных задач. Неужели никто не занимался этим? Чем же тогда занимаются системные интеграторы, зарабатывающие миллионы долларов?
Re[2]: Хитрая задачка: интеграция таблиц клиентов из разных
От: ZAMUNDA Земля для жалоб и предложений
Дата: 05.11.08 16:10
Оценка:
Здравствуйте, michag, Вы писали:

M>Здравствуйте, michag, Вы писали:


M>>Перед нами стоит задача интегрирования нескольких баз данных, различных видов (Oracle, SQL Server) и имеющих различную структуру.


M>Ответов нет... Неужели никто не решал подобную задачу? Мне кажется, что интеграция разных систем и баз данных — одна из самых типичных и распространенных задач. Неужели никто не занимался этим? Чем же тогда занимаются системные интеграторы, зарабатывающие миллионы долларов?

раз все молчат...
Не вижу смысла в "виртуальной" таблице. Написать на DTS (в mssql05 он Integration Service) простенький перекидыватель данных из двух этих баз в реальную таблицу клиентов, дело 15 минут (или 1 дня если ниразу с DTS не сталкивался). Чтоб не ломать голову, лучше, конечно, две таблицы -- переходную и рабочую. В переходную сначала сливаются все записи по клиентам из обоих баз, а потом, запросом синхронизируются рабочая и основная таблицы. Запуск перекидывателя можно в Job'ы добавить, а можно и в триггере прописать.

Я подобное решение видел, но там синхронизация два-три раза в день требовалась... а тебе как часто?
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re: Хитрая задачка: интеграция таблиц клиентов из разных БД
От: andy.wu  
Дата: 05.11.08 17:06
Оценка:
Здравствуйте, michag, Вы писали:

M>Перед нами стоит задача интегрирования нескольких баз данных, различных видов (Oracle, SQL Server) и имеющих различную структуру.


А нельзя сделать ф-цию на .NET ? которая будет конентится и возвращать некий роусет ?
Re: Хитрая задачка: интеграция таблиц клиентов из разных БД
От: MasterZiv СССР  
Дата: 05.11.08 18:03
Оценка:
michag пишет:

> Задача состоит в том, чтобы в таблице AllClients всегда находились

> актуальные данные из двух других таблиц — то есть данные должны быть
> синхронизированы в режиме real-time (или с совсем небольшой задержкой).

В real-time почти ни одна СУБД не работает.
Так что вам не это надо, а в on-line.
Но подозреваю и это вам излишне.

>

> Вот такая *задача*. Как ее реализовать?

Если on-line — только распределёнными транзакциями.
Удолбаетесь реализовывать.

> *2)* С помощью некоторого механизма (простого копирования, репликации и

> др.) данные из исходных таблиц переносятся в таблицы в SQL Server 2005.

Репликация вам не даст ваш "Real-time". Репликации всегда
(ну или скажем — как правило) асинхронные. Это значит, изменение
данны в источнике и приёмнике разнесены во времени. Гарантируется
только, что приёмник будет в одном из последовательных согласованных
состояний, в которых находился какое-то время назад источник.

> Хмм... Понятно ли то, что я написал? Мне кажется, что не очень — хотя

> старался написать понятно )
>
> В любом случае — кто может какие дать советы по решению данной задачи?

Понятно. Вы не знаете, чего хотите, и изобретаете велосипед.
Деревянный.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Хитрая задачка: интеграция таблиц клиентов из разных
От: MasterZiv СССР  
Дата: 05.11.08 18:04
Оценка:
michag пишет:

> Ответов нет... Неужели никто не решал подобную задачу? Мне кажется, что

> интеграция разных систем и баз данных — одна из самых типичных и
> распространенных задач.

Это — одна из сложнейших задач в БД, на самом деле.

Неужели никто не занимался этим? Чем же тогда
> занимаются системные интеграторы, зарабатывающие миллионы долларов?


Вот этим и занимаются .... думаете им зря платят, что ли ?
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Хитрая задачка: интеграция таблиц клиентов из разных
От: MasterZiv СССР  
Дата: 05.11.08 18:05
Оценка:
andy.wu пишет:

> M>Перед нами стоит задача *интегрирования нескольких баз данных*,

> различных видов (Oracle, SQL Server) и имеющих различную структуру.
>
> А нельзя сделать ф-цию на .NET ? которая будет конентится и возвращать
> некий роусет ?
У него вроде как гетерогенная сеть из разных СУБД, или что?
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 06.11.08 08:56
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>В real-time почти ни одна СУБД не работает.

MZ>Так что вам не это надо, а в on-line.
MZ>Но подозреваю и это вам излишне.

Да, действительно, real-time синхронизация данных между БД — это я немного преувеличил. Если будет задержка несколько минут — это не так страшно.

>>

>> Вот такая *задача*. Как ее реализовать?

MZ>Если on-line — только распределёнными транзакциями.

MZ>Удолбаетесь реализовывать.

А что значит "распределенные транзакции"? Это на языке SQL пишется?

>> *2)* С помощью некоторого механизма (простого копирования, репликации и

>> др.) данные из исходных таблиц переносятся в таблицы в SQL Server 2005.

MZ>Понятно. Вы не знаете, чего хотите, и изобретаете велосипед.

MZ>Деревянный.
MZ>

Вот именно поэтому я и решил поинтересовать на форуме, как другие решали подобные задачи. Делать собственный, деревянный велосипед в данной ситуации мне совершенно не хочется — поэтому и спрашиваю, нет ли стандартных велосипедов для ситуаций подобного рода? Или хотя бы ясных и четких инструкций, как самому смастерить хороший велосипед? Где можно об этом почитать? Я что-то ничего не нашел на эту тему.
Re[3]: Хитрая задачка: интеграция таблиц клиентов из разных
От: MasterZiv СССР  
Дата: 06.11.08 13:39
Оценка:
michag пишет:

> Да, действительно, real-time синхронизация данных между БД — это я

> немного преувеличил. Если будет задержка несколько минут — это не так
> страшно.

Ну тогда вам просто репликация подходит. Но учтите,
что рассинхронизацию вам контролировать никак не удастся
(типа " чтобы была не менее Х минут")

> А что значит "распределенные транзакции"? Это на языке SQL пишется?


Почитайте в какой-нибудь *педии.

> Вот именно поэтому я и решил поинтересовать на форуме, как другие решали

> подобные задачи. Делать собственный, деревянный велосипед в данной
> ситуации мне совершенно не хочется — поэтому и спрашиваю, нет ли
> стандартных велосипедов для ситуаций подобного рода?

Есть. Очень дорогостоящие трансокеанские лайнеры.

Или хотя бы ясных и
> четких инструкций, как самому смастерить хороший велосипед? Где можно об
> этом почитать? Я что-то ничего не нашел на эту тему.

Не знаю.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 06.11.08 13:53
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

ZAM>Не вижу смысла в "виртуальной" таблице. Написать на DTS (в mssql05 он Integration Service) простенький перекидыватель данных из двух этих баз в реальную таблицу клиентов, дело 15 минут (или 1 дня если ниразу с DTS не сталкивался). Чтоб не ломать голову, лучше, конечно, две таблицы -- переходную и рабочую. В переходную сначала сливаются все записи по клиентам из обоих баз, а потом, запросом синхронизируются рабочая и основная таблицы. Запуск перекидывателя можно в Job'ы добавить, а можно и в триггере прописать.


А что, если данные в исходной таблице изменились? Например, в таблице 1 000 000 строк, и изменилась только одна строка в исходной таблице. Как обновить конечную таблицу? Удалить в ней все строки, а затем заново залить 1 000 000 срок? Это явно неэффективно. А view всегда будет возвращать актуальные данные — в этом я вижу достоинство подхода с виртуальной таблицей.
Re[4]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 07.11.08 00:06
Оценка:
Здравствуйте, michag, Вы писали:

M>А что, если данные в исходной таблице изменились? Например, в таблице 1 000 000 строк, и изменилась только одна строка в исходной таблице. Как обновить конечную таблицу? Удалить в ней все строки, а затем заново залить 1 000 000 срок? Это явно неэффективно. А view всегда будет возвращать актуальные данные — в этом я вижу достоинство подхода с виртуальной таблицей.


Для этого существует тип данных rowversion.
Re[3]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 17.11.08 13:50
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:

ZAM>Здравствуйте, michag, Вы писали:


M>>Здравствуйте, michag, Вы писали:


M>>>Перед нами стоит задача интегрирования нескольких баз данных, различных видов (Oracle, SQL Server) и имеющих различную структуру.


M>>Ответов нет... Неужели никто не решал подобную задачу? Мне кажется, что интеграция разных систем и баз данных — одна из самых типичных и распространенных задач. Неужели никто не занимался этим? Чем же тогда занимаются системные интеграторы, зарабатывающие миллионы долларов?

ZAM>раз все молчат...
ZAM>Не вижу смысла в "виртуальной" таблице. Написать на DTS (в mssql05 он Integration Service) простенький перекидыватель данных из двух этих баз в реальную таблицу клиентов, дело 15 минут (или 1 дня если ниразу с DTS не сталкивался).

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

Когда сделки будут копироваться в БД назначения, в таблице сделок будет создано поле ClientId, содержащее идентификатор клиента — при этом это будет идентификатор из таблицы AllClients, которая была создана в БД назначения.

Далее. Пусть нам нужно скопировать из Oracle некоторую сделки. В Oracle в строке сделки стоит свой идентификатор клиента, а не ClientId. Поэтому требуется еще установить соответствие между идентификаторами клиентов в Oracle и БД назначения (SQL Server), для чего требуется создать таблицу соответствия идентификаторов. И дальше — возникают вопросы, которые я задавал в http://www.rsdn.ru/forum/message/3163605.1.aspx
Автор: michag
Дата: 05.11.08
. В общем, мне кажется, что без таблицы соответствия идентификаторов тут не обойтись.

Или же здесь можно применить какой-то другой, более умный подход?
Re[4]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 17.11.08 22:56
Оценка:
Здравствуйте, michag, Вы писали:

M>Далее. Пусть нам нужно скопировать из Oracle некоторую сделки. В Oracle в строке сделки стоит свой идентификатор клиента, а не ClientId. Поэтому требуется еще установить соответствие между идентификаторами клиентов в Oracle и БД назначения (SQL Server), для чего требуется создать таблицу соответствия идентификаторов. И дальше — возникают вопросы, которые я задавал в http://www.rsdn.ru/forum/message/3163605.1.aspx
Автор: michag
Дата: 05.11.08
. В общем, мне кажется, что без таблицы соответствия идентификаторов тут не обойтись.


Можно и нужно обойтись.

M>Или же здесь можно применить какой-то другой, более умный подход?


В качестве идентификаторов используй GUID-ы.
Re[5]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 18.11.08 08:21
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>Здравствуйте, michag, Вы писали:


M>>Далее. Пусть нам нужно скопировать из Oracle некоторую сделки. В Oracle в строке сделки стоит свой идентификатор клиента, а не ClientId. Поэтому требуется еще установить соответствие между идентификаторами клиентов в Oracle и БД назначения (SQL Server), для чего требуется создать таблицу соответствия идентификаторов. И дальше — возникают вопросы, которые я задавал в http://www.rsdn.ru/forum/message/3163605.1.aspx
Автор: michag
Дата: 05.11.08
. В общем, мне кажется, что без таблицы соответствия идентификаторов тут не обойтись.


___>Можно и нужно обойтись.


M>>Или же здесь можно применить какой-то другой, более умный подход?


___>В качестве идентификаторов используй GUID-ы.


Не понял, а как это поможет?

Ситуация такая: таблицы в Oracle править точно никак нельзя, но и таблицы в SQL Server тоже очень нежелательно было бы менять — т. е. у нас исходная и конечная базы данных имеют заданную структуру, менять которую нельзя. Можно только добавлять новые вспомогательные таблицы, но не более того.

И куда мне вставлять эти GUID'ы? Расскажите на моем конкретном примере с клиентами.
Re[6]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 18.11.08 08:47
Оценка:
Здравствуйте, michag, Вы писали:

M>Ситуация такая: таблицы в Oracle править точно никак нельзя, но и таблицы в SQL Server тоже очень нежелательно было бы менять — т. е. у нас исходная и конечная базы данных имеют заданную структуру, менять которую нельзя. Можно только добавлять новые вспомогательные таблицы, но не более того.


M>И куда мне вставлять эти GUID'ы? Расскажите на моем конкретном примере с клиентами.


Если менять нельзя, то никуда.
Невозможно сделать репликацию изменений, если реплицируемые таблицы менять нельзя. Ну или в крайнем случае триггеры надо навесить на таблицы. Иначе никак.
Re[7]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 18.11.08 10:29
Оценка:
Здравствуйте, _d_m_, Вы писали:

M>>И куда мне вставлять эти GUID'ы? Расскажите на моем конкретном примере с клиентами.


___>Если менять нельзя, то никуда.

___>Невозможно сделать репликацию изменений, если реплицируемые таблицы менять нельзя. Ну или в крайнем случае триггеры надо навесить на таблицы. Иначе никак.

Триггеры добавить можно. Я имел в виду, что нельзя менять структуру таблиц.

Хорошо, а если представить, что менять структуру таблиц, добавляя туда новые столбцы, можно — как тогда GUID'ы могут помочь?
Re: Хитрая задачка: интеграция таблиц клиентов из разных БД
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.11.08 11:05
Оценка:
Здравствуйте, michag, Вы писали:

M>В любом случае — кто может какие дать советы по решению данной задачи? Спасибо!

Я бы для начала потренировался примерно так:
1. Придумал бы "общую" структуру для интегрированной таблицы; вместе с полем-признаком "происхождение данных".
2. Прицепил бы оба сервера как Linked Servers к главному серверу
3. Сделал бы view в главном сервере, который бы возвращал бы union данных из обеих исходных таблиц
4. Посмотрел бы на шустродействие решения
5. Если устраивает, попробовал бы сделать триггеры instead of update на это view.
В триггере проверял бы признак происхождения данных, и в зависимости от него выполнял бы update соответствующей исходной таблицы.
6. Реализовал бы полный комплект триггеров и наслаждался результатом.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 19.11.08 01:21
Оценка:
Здравствуйте, michag, Вы писали:

M>Здравствуйте, _d_m_, Вы писали:


M>>>И куда мне вставлять эти GUID'ы? Расскажите на моем конкретном примере с клиентами.


___>>Если менять нельзя, то никуда.

___>>Невозможно сделать репликацию изменений, если реплицируемые таблицы менять нельзя. Ну или в крайнем случае триггеры надо навесить на таблицы. Иначе никак.

M>Триггеры добавить можно. Я имел в виду, что нельзя менять структуру таблиц.


M>Хорошо, а если представить, что менять структуру таблиц, добавляя туда новые столбцы, можно — как тогда GUID'ы могут помочь?


Элементарно. Добавляешь в свои таблицы столбец типа uniqueidentifier, default = newid()
Все. Идентификатор уникальный глобально — не надо никакой таблицы соответствий. Реплицируй себе наздоровье.

Но для полноценной репликации изменения надо еще добавить столбец типа rowversion
Re[9]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 19.11.08 09:05
Оценка:
Здравствуйте, _d_m_, Вы писали:

M>>Хорошо, а если представить, что менять структуру таблиц, добавляя туда новые столбцы, можно — как тогда GUID'ы могут помочь?


___>Элементарно. Добавляешь в свои таблицы столбец типа uniqueidentifier, default = newid()

___>Все. Идентификатор уникальный глобально — не надо никакой таблицы соответствий. Реплицируй себе наздоровье.

___>Но для полноценной репликации изменения надо еще добавить столбец типа rowversion


Блин, то ли я туплю, то ли неясно излагаю свои мысли, в результате чего между нами возникает неполное понимание.

Нам нужно не только таблицу клиентов импортировать, но и связанные с клиентами данные — например, Orders (заказы, сделанные клиентами).

Представим себе: мы проимпортировал таблицу клиентов, из двух источников. В единой таблице в БД назначения у нас есть поле ClientGuid (как вы говорите).

Затем, нам нужно импортировать заказы. Вот берем первую запись из таблицы OrdersFromOracle — там стоит ClientId = 13245 (это идентификатор клиента в одной из БД-источников, но в БД назначения у нас этого идентификатора нет). А нам в БД назначения нужно, чтобы Orders ссылались на Clients.ClientGuid. То есть нам нужно из ClientId получить ClientGuid. И сделать это никак, кроме как через таблицу, хранящую соответствие между этими идентификаторами, по-моему, нельзя.
Re[9]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 19.11.08 09:11
Оценка:
Здравствуйте, _d_m_, Вы писали:

M>>Хорошо, а если представить, что менять структуру таблиц, добавляя туда новые столбцы, можно — как тогда GUID'ы могут помочь?


___>Элементарно. Добавляешь в свои таблицы столбец типа uniqueidentifier, default = newid()

___>Все. Идентификатор уникальный глобально — не надо никакой таблицы соответствий. Реплицируй себе наздоровье.

___>Но для полноценной репликации изменения надо еще добавить столбец типа rowversion


Блин, то ли я туплю, то ли неясно излагаю свои мысли, в результате чего между нами возникает неполное понимание.

Нам нужно не только таблицу клиентов импортировать, но и связанные с клиентами данные — например, Orders (заказы, сделанные клиентами).

Представим себе: мы проимпортировал таблицу клиентов, из двух источников. В единой таблице в БД назначения у нас есть поле ClientGuid (как вы говорите).

Затем, нам нужно импортировать заказы. Вот берем первую запись из таблицы OrdersFromOracle — там стоит ClientId = 13245 (это идентификатор клиента в одной из БД-источников, но в БД назначения у нас этого идентификатора нет). А нам в БД назначения нужно, чтобы Orders ссылались на Clients.ClientGuid. То есть нам нужно из ClientId получить ClientGuid. И сделать это никак, кроме как через таблицу, хранящую соответствие между этими идентификаторами, по-моему, нельзя.
Re[10]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 20.11.08 01:54
Оценка:
Здравствуйте, michag, Вы писали:

M>Блин, то ли я туплю, то ли неясно излагаю свои мысли, в результате чего между нами возникает неполное понимание.


M>Нам нужно не только таблицу клиентов импортировать, но и связанные с клиентами данные — например, Orders (заказы, сделанные клиентами).


M>Представим себе: мы проимпортировал таблицу клиентов, из двух источников. В единой таблице в БД назначения у нас есть поле ClientGuid (как вы говорите).


M>Затем, нам нужно импортировать заказы. Вот берем первую запись из таблицы OrdersFromOracle — там стоит ClientId = 13245 (это идентификатор клиента в одной из БД-источников, но в БД назначения у нас этого идентификатора нет). А нам в БД назначения нужно, чтобы Orders ссылались на Clients.ClientGuid. То есть нам нужно из ClientId получить ClientGuid. И сделать это никак, кроме как через таблицу, хранящую соответствие между этими идентификаторами, по-моему, нельзя.


Все вам разжуй и в рот положи. Дарю.
CREATE TABLE dbo.Clients
    (
    ClientId int NOT NULL IDENTITY (1, 1),
    Name nvarchar(50) NOT NULL,
    ClientGuid uniqueidentifier NOT NULL ROWGUIDCOL,
    Ver timestamp NOT NULL -- это синоним типа rowversion, просто дизайнер SSMS его не понимает
    )
GO
ALTER TABLE dbo.Clients ADD CONSTRAINT
    DF_Clients_ClientGuid DEFAULT newid() FOR ClientGuid
GO
ALTER TABLE dbo.Clients ADD CONSTRAINT
    PK_Clients_ClientId PRIMARY KEY CLUSTERED 
    (
    ClientId
    )

GO
ALTER TABLE dbo.Clients ADD CONSTRAINT
    IX_Clients_ClientGuid UNIQUE NONCLUSTERED 
    (
    ClientGuid
    )

GO
CREATE NONCLUSTERED INDEX IX_Clients_Ver ON dbo.Clients
    (
    Ver
    )
GO


CREATE TABLE dbo.Orders
    (
    OrderId int NOT NULL IDENTITY (1, 1),
    ClientId int NOT NULL,
    OrderGuid uniqueidentifier NOT NULL ROWGUIDCOL,
    Ver timestamp NOT NULL
    )
GO
ALTER TABLE dbo.Orders ADD CONSTRAINT
    DF_Orders_OrderGuid DEFAULT newid() FOR OrderGuid
GO
ALTER TABLE dbo.Orders ADD CONSTRAINT
    PK_Orders_OrderId PRIMARY KEY CLUSTERED 
    (
    OrderId
    )

GO
CREATE NONCLUSTERED INDEX IX_Orders_ClientId ON dbo.Orders
    (
    ClientId
    )
GO
ALTER TABLE dbo.Orders ADD CONSTRAINT
    IX_Orders_OrderGuid UNIQUE NONCLUSTERED 
    (
    OrderGuid
    )

GO
CREATE NONCLUSTERED INDEX IX_Orders_Ver ON dbo.Orders
    (
    Ver
    )
GO
ALTER TABLE dbo.Orders ADD CONSTRAINT
    FK_Orders_Clients1 FOREIGN KEY
    (
    OrderId
    ) REFERENCES dbo.Clients
    (
    ClientId
    )
GO

Сервер с консолидироваными данными:
CREATE TABLE dbo.ClientsGlobal
    (
    Name nvarchar(50) NOT NULL,
    ClientGuid uniqueidentifier NOT NULL ROWGUIDCOL
    )
GO
ALTER TABLE dbo.ClientsGlobal ADD CONSTRAINT
    DF_ClientsGlobal_ClientGuid DEFAULT newid() FOR ClientGuid
GO
ALTER TABLE dbo.ClientsGlobal ADD CONSTRAINT
    PK_ClientsGlobal_ClientGuid PRIMARY KEY CLUSTERED 
    (
    ClientGuid
    )
GO


CREATE TABLE dbo.OrdersGlobal
    (
    ClientGuid uniqueidentifier NOT NULL,
    OrderGuid uniqueidentifier NOT NULL ROWGUIDCOL
    )
GO
ALTER TABLE dbo.OrdersGlobal ADD CONSTRAINT
    DF_OrdersGlobal_OrderGuid DEFAULT newid() FOR OrderGuid
GO
ALTER TABLE dbo.OrdersGlobal ADD CONSTRAINT
    PK_OrdersGlobal_OrderGuid PRIMARY KEY CLUSTERED 
    (
    OrderGuid
    )

GO
CREATE NONCLUSTERED INDEX IX_OrdersGlobal_ClientGuid ON dbo.OrdersGlobal
    (
    ClientGuid
    )
GO
ALTER TABLE dbo.OrdersGlobal ADD CONSTRAINT
    FK_OrdersGlobal_ClientsGlobal FOREIGN KEY
    (
    OrderGuid
    ) REFERENCES dbo.Clients
    (
    ClientGuid
    )
GO

Вставка тестовых данных:
insert Clients([Name]) values(N'Пупкин Василий');
insert Clients([Name]) values(N'Клитов Евгений');
insert Clients([Name]) values(N'Затрищенко Агропена');

insert Orders(ClientId) values(1);
insert Orders(ClientId) values(2);
insert Orders(ClientId) values(3);

Запросы используемые, например, для передачи данных через объект класса SqlBulkCopy
select
    [Name],
    ClientGuid,
    Ver
from
    Clients
where
    Ver > 0x00000000000007D2 -- [1]
compute
    max(Ver) -- [2]
;
/*
[1] - здесь должно быть значение [2] из предыдущего такого успешно реплицированного выполненного запроса.
Для репликации всей таблицы достаточно [1] = 0
*/

select
    (select
        ClientGuid
    from
        Clients c
    where
        c.ClientId = o.ClientId
    ) as ClientGuid,
    o.OrderGuid,
    o.Ver
from
    Orders o
where
    Ver > 0x00000000000007D4
compute
    max(Ver)
;
Re[11]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 20.11.08 02:45
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>Здравствуйте, michag, Вы писали:


Помедитируй еще над этим http://rsdn.ru/Forum/Message.aspx?mid=3179962&amp;only=1
Автор: _d_m_
Дата: 19.11.08
Re[11]: Хитрая задачка: интеграция таблиц клиентов из разных
От: michag  
Дата: 20.11.08 08:31
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>Все вам разжуй и в рот положи. Дарю.


Только что прочел ваш ответ — сразу скажу спасибо большое за подарок Буду изучать и размышлять.
Re: Хитрая задачка: интеграция таблиц клиентов из разных БД
От: megascalper Россия http://lazy-coder.livejournal.com
Дата: 25.11.08 16:15
Оценка:
Здравствуйте, michag, Вы писали:

M>Перед нами стоит задача интегрирования нескольких баз данных, различных видов (Oracle, SQL Server) и имеющих различную структуру.


Похоже, без репликаций не обойтись. Что-то конкретное посоветовать сложно, потому что задача имеет много вариантов решения. Какой из них устроит — сложно сказать, поэтому выскажу лишь общие соображения.
Не обязательно создавать 2 таблицы, можно использовать и одну, атрибуты которой будут объединенияем множеств атрибутов физиков и юриков. Разумеется, на это следует идти только при полной уверенности, что пустые значения атрибутов не такая большая проблема. Этот подход сэкономит нервы при написании приложения. С другой стороны, использование 2-х таблиц экономит место на диске, но не экономит нервы, если потребуется дополнять или модифицировать объединенную таблицу клиентов.
Общая идея при репликации — использование специального суррогатного репликационного ключа.
Помимо этой задачи, следует еще решить вопросы сериализации/десериализации при передаче по каналу, а также вопрос функции преобразования при использовании разноструктурных таблиц. Будет время — напишу статью. Пока есть лишь первоначальные наработки для случая двух одноструктурных баз, так что показывать нечего.
Да, и еще: скорее всего, придется написать менеджер репликаций с поддержкой распределенных транзакций.

Иными словами, будет желание — обращайтесь. Чем смогу — помогу.
Re[2]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 25.11.08 23:44
Оценка:
Здравствуйте, megascalper, Вы писали:

M>Помимо этой задачи, следует еще решить вопросы сериализации/десериализации при передаче по каналу,


Зачем?

M>а также вопрос функции преобразования при использовании разноструктурных таблиц.


Представления с замещающим триггером.

M>Будет время — напишу статью. Пока есть лишь первоначальные наработки для случая двух одноструктурных баз, так что показывать нечего.


А у меня есть чего. См. мои сообщения. Уже два года промышленной эксплуатации.

M>Да, и еще: скорее всего, придется написать менеджер репликаций с поддержкой распределенных транзакций.


Зачем?
Re[3]: Хитрая задачка: интеграция таблиц клиентов из разных
От: megascalper Россия http://lazy-coder.livejournal.com
Дата: 26.11.08 09:07
Оценка:
Здравствуйте, _d_m_, Вы писали:

M>>Помимо этой задачи, следует еще решить вопросы сериализации/десериализации при передаче по каналу,

___>Зачем?
В общем случае. Кто его знает, где эти базы находятся? Через инет гонять прямые подключения? Нафиг-нафиг!

M>>а также вопрос функции преобразования при использовании разноструктурных таблиц.

___>Представления с замещающим триггером.
Угу. Но такиж преобразующая функция, нихт вар?

M>>Будет время — напишу статью. Пока есть лишь первоначальные наработки для случая двух одноструктурных баз, так что показывать нечего.

___>А у меня есть чего. См. мои сообщения. Уже два года промышленной эксплуатации.
Два года — уважаю. Смотрел. Много букавак, но читал. Проникся. Гуид как ключ для репликации — сильно. MS SQL timestamp как версия строки — сильно (по крайней мере, для MS SQL). Увидел простой случай построения реплики в случае внесения или обновления записи. Специально попробовал — на разных серверах сработает, только если на одном из них разрешать исключительно выборку данных. Вывод: хорошая и надежная система, при условии, что технические ограничения не мешают реальному использованию.

M>>Да, и еще: скорее всего, придется написать менеджер репликаций с поддержкой распределенных транзакций.

___>Зачем?

Затем, что все равно придется решать вопрос "кто прав — кто не прав". В простом случае разрешение этих вопросов переваливается на один из серверов. Если функциональности хватит. А транзакции все равно нужны, потому что либо придется выгонять всех юзверей на время репликации, либо молиться на Богдыхара, чтобы они чего не изменили за время переноса данных. Впрочем, учитывая предыдущий абзац, весь менеджер вырождается в 3 оператора.
Re[4]: Хитрая задачка: интеграция таблиц клиентов из разных
От: _d_m_  
Дата: 27.11.08 02:55
Оценка:
Здравствуйте, megascalper, Вы писали:

M>Здравствуйте, _d_m_, Вы писали:


M>>>Помимо этой задачи, следует еще решить вопросы сериализации/десериализации при передаче по каналу,

___>>Зачем?
M>В общем случае. Кто его знает, где эти базы находятся? Через инет гонять прямые подключения? Нафиг-нафиг!

Вобще MS SQL поддерживает шифрование на уровне соединения, но мы пользуемся VPN.

M>>>а также вопрос функции преобразования при использовании разноструктурных таблиц.

___>>Представления с замещающим триггером.
M>Угу. Но такиж преобразующая функция, нихт вар?

Да.

M>>>Будет время — напишу статью. Пока есть лишь первоначальные наработки для случая двух одноструктурных баз, так что показывать нечего.

___>>А у меня есть чего. См. мои сообщения. Уже два года промышленной эксплуатации.
M>Два года — уважаю. Смотрел. Много букавак, но читал. Проникся. Гуид как ключ для репликации — сильно. MS SQL timestamp как версия строки — сильно (по крайней мере, для MS SQL). Увидел простой случай построения реплики в случае внесения или обновления записи. Специально попробовал — на разных серверах сработает, только если на одном из них разрешать исключительно выборку данных. Вывод: хорошая и надежная система, при условии, что технические ограничения не мешают реальному использованию.

На самом деле система несколько сложнее. Поддерживается двухсторонняя репликация. Т.е. для реплицируемой таблицы есть еще вспогат. две таблицы: ключи удаленных строк [1], ключи реплицир. строк [2]. Плюс триггер на удаление — для заполнения таблицы [1]. Плюс триггер на обновление на реплицир. таблицу — для удаления из таблицы [2].
При реализации я использовал все MS-овские заделы для поддержки родной репликации:
— столбцы rowversion (ака timestamp, хотя к времени не имеют никакого отношения);
— использование опций для триггеров и констрэйнтов not for replication.

M>>>Да, и еще: скорее всего, придется написать менеджер репликаций с поддержкой распределенных транзакций.

___>>Зачем?

Я имел ввиду, что поддержка распределенных транзакций не нужна.

M>Затем, что все равно придется решать вопрос "кто прав — кто не прав". В простом случае разрешение этих вопросов переваливается на один из серверов. Если функциональности хватит. А транзакции все равно нужны, потому что либо придется выгонять всех юзверей на время репликации, либо молиться на Богдыхара, чтобы они чего не изменили за время переноса данных. Впрочем, учитывая предыдущий абзац, весь менеджер вырождается в 3 оператора.


Менеджер у нас есть, у него такой функционал:
— удаление данных через bulk copy API;
— заливка данных в транзакции пакетами максимального указанного в конфиге размера (обычно 20000 строк) через bulk copy API;
— если есть конфликт — локализация конфликта до 1 строки и запись данных конфликта репликации [1];
— запись максимальной реплицированной версии [2].

Так если возникнет ошибка в случае [1], то конфликт будет записан в следующем сеансе репликации;
Если возникнет ошибка в случае [2], то просто эти данные будут переданы повторно.
Вобщем нет нужды в распределенных транзакциях.

И опять же я упрощаю, система еще несколько сложнее, но влом писать — просто задавай вопросы — отвечу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.