Мне нужно быстро реализовать базу данных только для чтения, содержащую данные, извлеченные из двух идентично структурированных живых баз данных.
Живые базы данных на самом деле являются корпоративными базами данных из системы учета Dynamics, поэтому я рад любым советам, связанным с Dynamics, но в основном это вопрос SQL. Это довольно старая версия Dynamics до того, как Microsoft приобрела Great Plains. Это на SQL Server 2000.
У нас есть отчеты и приложения, которые обращаются к данным Dynamics. Эти приложения предназначены для просмотра одной компании БД. Теперь нам нужно добавить еще один. Уместно, что большинство этих отчетов и приложений видят объединенные данные. Им действительно все равно, в какой компании существует заказ или счет. Они смотрят только на небольшое количество таблиц.
Мне кажется, что самое простое решение - создавать отчеты только по БД с объединенными данными. Предпочтительно, нам нужен эффективный способ обновления этой базы данных с изменениями несколько раз в день.
Я разработчик, а не эксперт по БД, но вот мой план:
Создайте объединенную базу данных отчетов с необходимыми таблицами первоначально с той же структурой таблиц, что и живые базы данных.
Кажется, что во всех таблицах Dynamics есть столбец int с именем DEX_ROW_ID. Я не уверен, для чего он используется (он не индексируется), но это кажется очевидным универсальным способом уникальной идентификации строк. На БД отчетности я изменю его на обычный int (не тождество). Я создам уникальный индекс для DEX_ROW_ID во всех базах данных.
В динамике нет меток времени, поэтому я добавлю столбец меток времени в таблицы в динамических БД и соответствующий двоичный столбец (8) в базе данных отчетов. Я предполагаю и надеюсь, что динамика не будет расстроена дополнительным индексом и столбцом.
Добавьте столбец int CompanyId в таблицы базы данных отчетов и добавьте его в конец любых уникальных индексов. Большинство данных будут уникальными даже без этого. т. е. номера заказов и счетов-фактур и т. д. будут различны для двух действующих БД Возможно, нам придется внести некоторые незначительные изменения в приложения, но я не собираюсь делать что-то еще, кроме как указать им новую базу данных отчетности.
Предполагая, что моя база данных отчетов называется «Отчеты», живые базы данных - «Live1» и «Live2», столбец отметки времени называется «TS», и все базы данных находятся на одном сервере ... вот моя первая попытка создания сценария обновления для копирования изменений в один из них. Таблица под названием MyTable в Live1 для базы данных отчетности.
USE Reports
CREATE TABLE #Changes
(
ReportId int,
LiveId int
)
/* Collect in a temp table the ids or rows which have been deleted or changed
in the live db L.DEX_ROW_ID will be null if the row has been deleted */
INSERT INTO #Changes
SELECT R.DEX_ROW_ID, L.DEX_ROW_ID
FROM MyTable R LEFT OUTER JOIN Live1.dbo.MyTable L ON L.DEX_ROW_ID = R.DEX_ROW_ID
WHERE R.CompanyId = 1 AND L.DEX_ROW_ID IS NULL OR L.TS <> R.TS
/* Delete rows that have been deleted or changed on the live db
I wonder if using join syntax would run better than the subquery. */
DELETE FROM MyTable
WHERE CompanyId = 1 AND DEX_ROW_ID IN (SELECT ReportId FROM #Changes)
/* Recopy rows that have changed in the live db */
INSERT INTO MyTable
SELECT 1 AS CompanyId, * FROM Live1.dbo.MyTable L
WHERE L.DEX_ROW_ID IN (SELECT ReportId FROM #Changes WHERE LiveId IS NOT NULL)
/* Copy the rows that are new in the live db */
INSERT INTO MyTable
SELECT 1 AS CompanyId, * FROM Live1.dbo.MyTable
WHERE DEX_ROW_ID > (SELECT MAX(DEX_ROW_ID) FROM MyTable WHERE CompanyId = 1)
Затем сделайте то же самое для Live2 db. Повторите для каждой таблицы в отчетах. Я знаю, что должен использовать параметр @CompanyId вместо литерала, но я не могу сделать это для живого имени БД, я мог бы сгенерировать их динамически с помощью программы на C # или чего-то еще.
Я ищу любые советы, предложения или критику в отношении того, что я делаю здесь. Я знаю, что это не будет атомным. Во время работы этого сценария на live db могут происходить события. Я думаю, что мы можем жить с этим. Мы, вероятно, сделаем полную копию либо ночью, либо еженедельно, когда ничего не происходит на живых БД.
Нам нужно отдавать предпочтение производительности, а не элегантности или совершенству. Некоторое первоначальное тестирование имеет первый запрос с сравнением TS, выполняемым примерно за 30 секунд для самой большой таблицы, поэтому я уверен, что это сработает, но я также хотел бы знать, пропускаю ли я что-то очевидное или не вижу лес за деревьями.
На самом деле мы не хотим иметь дело с файлами журналов в базе данных отчетов. Можем ли мы просто установить это для простой модели восстановления и забыть о журналах?
Спасибо