Фон
Я пишу много больших отчетов и, как правило, веду большую базу данных о работоспособности (пишу SP, функции, задания и т. Д.). Исходная схема и программное обеспечение, которое ее использует, принадлежат другому поставщику, поэтому я не могу многое изменить в этом структурно. Есть много записей, которые требуют отслеживания, таких как лаборатории, процедуры, вакцины и т. Д., И они разбросаны по десяткам таблиц, многие из которых раздуты и плохо проиндексированы (я смог это исправить).
Проблема
Проблема заключается в том, что, поскольку у нас мало контроля над БД, и поскольку она может отличаться от любого данного обновления или исправления, это делает написание и ведение этих отчетов трудным и утомительным, особенно при большом количестве совпадений. Все, что нужно, это один патч, и я застрял, переписывая большие части десятка отчетов. Кроме того, запросы быстро становятся запутанными и медленными, поскольку объединения, вложенные выборки и применения накапливаются.
Мое "решение"
Мой план состоял в том, чтобы записать все эти записи в одну таблицу «всеохватывающего» и записать триггеры в исходные таблицы для ведения записей в этой сводной таблице. Конечно, я должен был убедиться, что мои триггеры не были повреждены после обновлений, но это было бы намного проще с точки зрения удобства сопровождения и просто ссылки на данные.
Таблица будет тонкой и длинной, хранящей только необходимые данные, что-то вроде этого:
CREATE TABLE dbo.HCM_Event_Log (
id INT IDENTITY,
type_id INT NULL,
orig_id VARCHAR(36) NULL,
patient_id UNIQUEIDENTIFIER NOT NULL,
visit_id UNIQUEIDENTIFIER NULL,
lookup_id VARCHAR(50) NULL,
status VARCHAR(15) NULL,
ordered_datetime DATETIME NULL,
completed_datetime DATETIME NULL,
CONSTRAINT PK_HCM_Event_Log PRIMARY KEY CLUSTERED (id)
)
Тогда у меня были бы различные реляционные таблицы для таких вещей, как type_id и группировка элементов.
Я начинаю вторую догадываться об этой идее, так как некоторые из этих таблиц написаны довольно много, SP и отчеты, которые я буду писать, также будут ссылаться на данные. Поэтому я обеспокоен тем, что эта таблица станет кошмаром для блокировки записей и производительности с таким большим количеством операций ввода-вывода.
Мой вопрос
Это плохая или хорошая идея? Я понимаю, что в SQL Server (Standard r2 Standard Edition BTW) и в правилах «иногда» каждая ситуация различна, но я просто ищу общие советы.
Я начал рассматривать возможность использования сервисного брокера, но я буду выполнять только простые обновления / вставки ( см. Альтернативу принятому ответу ). Во многих случаях данные должны быть в реальном времени, поэтому использование резервной БД не будет работать. Производительность уже является для нас проблемой, но в основном это связано с аппаратным обеспечением, которое скоро будет решено.
источник
Ответы:
Если я вас правильно понял,
Я хотел бы подойти к этому так:
В этом случае вы можете точно настроить структуру и индексы вашей базы данных, чтобы повысить производительность ваших отчетов, не затрагивая стороннюю систему. Если исходная структура данных не претерпит существенных изменений, логика ваших запросов к отчетам не изменится при изменении сторонней базы данных. Вам придется настроить только процесс синхронизации.
Процесс синхронизации по сути является процессом преобразования - вы конвертируете данные из сторонней базы данных в нужную вам структуру. Частью этого процесса преобразования может быть устранение любых проблем нормализации, которые могут возникнуть у исходной сторонней базы данных. Только эта часть системы должна знать и зависеть от внутренней структуры сторонней системы. Ваши основные отчеты и основные запросы будут зависеть только от вашей базы данных.
Итак, главное - отделить и ограничить ту часть вашей системы, которая зависит от внутренних компонентов сторонней системы.
Обновить
Относительно требований в реальном времени. Кстати, я всегда думал, что определение «в реальном времени» - это «гарантированное время отклика», а не «небольшое время отклика». Конечно, это зависит от вашего приложения. В моей практике достаточно, чтобы я синхронизировал две базы данных в течение минуты обнаруженного изменения. Если пользователь видит отчет на экране и некоторые изменения основных данных, отчет должен быть как-то повторно выполнен, чтобы отразить это изменение. Вы можете опросить изменения или прослушать какое-либо событие / сообщение, но запрос отчета должен быть выполнен снова, чтобы показать последние изменения.
Вы уже намереваетесь написать триггеры для захвата изменений в исходных таблицах и записи этих изменений в одну общую таблицу. Таким образом, сохраняйте изменения, как вы предполагали, но записывайте их в правильно нормализованные таблицы, а не в одну.
Таким образом, это крайний случай - преобразование сторонней структуры данных во внутреннюю структуру данных выполняется в триггерах, запускающих
INSERT/UPDATE/DELETE
сторонние таблицы. Это может быть сложно. Код триггеров будет зависеть от внутренней структуры обеих систем. Если преобразование нетривиально, оно может задержать оригиналINSERT/UPDATE/DELETE
до точки их отказа. Если в вашем триггере есть ошибка, это может повлиять на исходную транзакцию вплоть до ее отказа. Если сторонняя система изменится, это может сломать ваш триггер, что приведет к сбою транзакций сторонней системы.Менее крайний случай. Чтобы сделать код ваших триггеров более простым и менее подверженным ошибкам, запишите все зафиксированные изменения в некоторые таблицы подготовки / аудита / сравнения, установите некоторые флажки / отправьте сообщение об ожидающих изменениях и запустите основной процесс преобразования, который будет через эти промежуточные таблицы и выполнить преобразование. Главное здесь заключается в том, что потенциально тяжелый процесс преобразования должен происходить за пределами исходной транзакции.
На второй взгляд это выглядит как ваше первоначальное предложение в вопросе. Но разница в том, что таблицы захвата всех данных содержат данные только временно; объем данных невелик - только то, что изменилось; это не должен быть единственный стол; в конечном итоге данные будут храниться в отдельных должным образом нормализованных постоянных таблицах, которые вы полностью контролируете, которые независимы от сторонней системы и которые вы можете настроить для своих запросов.
источник
Во что бы то ни стало поместите его в стандартизированный набор таблиц, чтобы вы могли настроить этап импорта, а не изменять сложные отчеты и запросы. Но данные все равно должны быть нормализованы, что потребует таблиц с кратными значениями (но с хорошими показателями).
Как уже упоминали другие, не используйте триггеры, синхронизируйте в пакетном режиме.
Не беспокойтесь о множестве объединений, когда данные нормализуются и индексируются должным образом, это не добавляет значительных затрат или затрат на управление.
Время денормализации во что-то вроде хранилища данных - это когда вам нужно иметь возможность делать множество различных типов запросов к данным, которые вы не можете предсказать. Он имеет свои недостатки и накладные расходы и должен использоваться там, где это уместно, а не для обсуждения.
источник
В прошлом я работал с очень похожей ситуацией в производственной компании 24x7 и, наконец, решил использовать репликацию транзакций. Можно настроить репликацию DDL таким образом, чтобы вы могли распространять любые изменения, вносимые подписчику. Очевидно, что у каждого есть свои плюсы и минусы, и вам нужно взвесить их, чтобы определить, что вы можете поддержать, а что лучше всего подходит для компании.
С положительной стороны:
Хотя есть и минусы:
источник
Триггеры имеют так много проблем, что вы должны избегать их:
Лучшим вариантом является задание, которое периодически копирует данные в новую таблицу. Ваши отчеты могут работать копии. Задание, которое копирует строки, легко написать и поддерживать, и нет риска, что это повлияет на работу стороннего приложения.
источник
NOCOUNT
? 4. В таблице назначения не было бы никаких триггеров, и я мог бы гарантировать то же самое для остальных.