SQL Azure Альтернатива Service Broker - PullRequest
1 голос
/ 01 июля 2019

Наше программное обеспечение представляет собой набор приложений Windows, которые подключаются к базе данных SQL.В настоящее время все наши клиентские сайты имеют свой собственный сервер и базу данных SQL Server, однако я работаю над тем, чтобы наше программное обеспечение работало с базами данных, размещенными в Azure.

Я столкнулся с одной проблемой, и пока что нетнашел что-то особенно полезное во время поиска в Google.

Текущая версия SQL Server включает в себя написанную мной систему аудита базы данных, которая выполняет следующие функции: -

Приложения C # включают в строку подключения информацию о том, какиепрограмма и версия, и какой пользователь в данный момент вошел в систему.

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

Затем компонент Service Broker проходит через очередь и записывает сведения об изменении в отдельную таблицу AuditLog.

Эти данные включают: -

Таблица, PK строки, измененной, Поле, Старое значение, Новое значение, было ли это Обновлением или Удалить, дата / время изменения, UserID пользователя, вошедшего в наше программное обеспечение, и какая программа и версия сделалиизменить.

Все это работает очень хорошо, и я надеялся сохранить систему как есть для версии Azure, но, к сожалению, в SQL Azure нет Service Broker.

Итак, мне нужноискать альтернативу, которая, как я упоминал, оказывается проблематичной.

Существует управляемые экземпляры SQL Azure, в которых есть Service Broker, однако они слишком дороги, чтобы мы их даже не рассматривали.Ни один из наших клиентов не заплатил бы столько в месяц.

Кажется, что-то еще, на что я смотрел, не имеет всего, что мне нужно.В частности, регистрация, какая программа, версия и идентификатор пользователя.Обратите внимание, что это не идентификатор пользователя для входа в SQL, который будет одинаковым для всех, это идентификатор из таблицы пользователей, с которой они входят в наше программное обеспечение, и передается в строке подключения.

Итак, в идеале я бы хотел что-то похожее на то, что у меня есть, просто с чем-то другим вместо Service Broker: -

Приложения C # включают в строку подключения информацию о том, какая это программа и версия,и какой пользователь в настоящий момент вошел в систему.

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

Что-то потомпроходит через очередь вне обычного потока программы и записывает подробности изменения в отдельную таблицу AuditLog.

Важна асинхронная очередь и обработка вне обычного потока программы.Очевидно, я мог бы очень легко сделать так, чтобы триггеры Update и Delete делали всю обработку и добавляли записи в таблицу AuditLog, фактически это была v1.0 системы, но проблема в том, что SQL будет ждать, пока триггеры не завершатся, прежде чемвозвращаясь к программе C #.Это приводит к значительному замедлению работы программы на C #, когда происходит несколько обновлений или удалений.

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

Итак, есть ли какие-либо предложения по альтернативе Service Broker для SQL Azure, пожалуйста?ТИА!

1 Ответ

0 голосов
/ 01 июля 2019

Хорошо, похоже, у меня есть потенциальное решение: временные таблицы

Временные таблицы работают в Azure и записывают новую строку в таблицу истории при каждом изменении: -

CREATE TABLE dbo.LMSTemporalTest   
(    
  [EmployeeID] INT NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] NVARCHAR(100) NOT NULL  
  , [Position] NVARCHAR(100) NOT NULL   
  , [Department] NVARCHAR(100) NOT NULL  
  , [Address] NVARCHAR(1024) NOT NULL  
  , [AnnualSalary] DECIMAL (10,2) NOT NULL  
  , [UpdatedBy] UniqueIdentifier NOT NULL
  , [UpdatedDate] DateTime NOT NULL
  , [ValidFrom] DateTime2 (2) GENERATED ALWAYS AS ROW START HIDDEN
  , [ValidTo] DateTime2 (2) GENERATED ALWAYS AS ROW END HIDDEN
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
)    
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.LMSTemporalTestHistory));  
GO

Затем я могу вставить запись в таблицу ...

INSERT INTO LMSTemporalTest(EmployeeID,Name,Position,Department,Address,AnnualSalary, UpdatedBy, UpdatedDate)
VALUES(1, 'Bob', 'Builder', 'Fixers','Oops I forgot', 1, '0D7F5584-C79B-4044-87BD-034A770C4985', GetDate())
GO

Обновить строку ...

UPDATE LMSTemporalTest SET 
Address = 'Sunflower Valley, Bobsville',
UpdatedBy = '2C62290B-61A9-4B75-AACF-02B7A5EBFB80',
UpdatedDate = GetDate()
WHERE EmployeeID = 1
GO

Обновить строку еще раз ...

UPDATE LMSTemporalTest SET 
AnnualSalary = 420.69,
UpdatedBy = '47F25135-35ED-4855-8050-046CD73E5A7D',
UpdatedDate = GetDate()WHERE EmployeeID = 1
GO

А затем проверьте результаты: -

SELECT * FROM LMSTemporalTest
GO

EmployeeID  Name    Position    Department  Address AnnualSalary    UpdatedBy   UpdatedDate
1   Bob Builder Fixers  Sunflower Valley, Bobsville 420.69  47F25135-35ED-4855-8050-046CD73E5A7D    2019-07-01 16:20:00.230

Примечание. Поскольку я установил их как Скрытые, Действительные с и Действительные, чтобы не отображаться

Проверьте изменения на дату/ диапазон времени: -

SELECT * FROM LMSTemporalTest  
FOR SYSTEM_TIME BETWEEN '2019-Jul-01 14:00' AND '2019-Jul-01 17:10'   
WHERE EmployeeID = 1
ORDER BY ValidFrom;
GO

EmployeeID  Name    Position    Department  Address AnnualSalary    UpdatedBy   UpdatedDate
1   Bob Builder Fixers  Oops I forgot   1.00    0D7F5584-C79B-4044-87BD-034A770C4985    2019-07-01 16:20:00.163
1   Bob Builder Fixers  Sunflower Valley, Bobsville 1.00    2C62290B-61A9-4B75-AACF-02B7A5EBFB80    2019-07-01 16:20:00.197
1   Bob Builder Fixers  Sunflower Valley, Bobsville 420.69  47F25135-35ED-4855-8050-046CD73E5A7D    2019-07-01 16:20:00.230

И я даже могу просмотреть таблицу истории

SELECT * FROM LMSTemporalTestHistory
GO

EmployeeID  Name    Position    Department  Address AnnualSalary    UpdatedBy   UpdatedDate ValidFrom   ValidTo
1   Bob Builder Fixers  Oops I forgot   1.00    0D7F5584-C79B-4044-87BD-034A770C4985    2019-07-01 16:20:00.163 2019-07-01 16:20:00.16  2019-07-01 16:20:00.19
1   Bob Builder Fixers  Sunflower Valley, Bobsville 1.00    2C62290B-61A9-4B75-AACF-02B7A5EBFB80    2019-07-01 16:20:00.197 2019-07-01 16:20:00.19  2019-07-01 16:20:00.22

Примечание: текущая строка не отображается, поскольку она по-прежнему действительна

Все наши важные таблицы уже имеют CreatedBy, CreatedDate, updatedBy и updatedDate, поэтому я могу использовать их для регистрации идентификаторов пользователей.Не существует очевидного способа обработки Программы и Версии как стандартного, но я всегда могу добавить другое скрытое поле и использовать Триггеры, чтобы установить это.

РЕДАКТИРОВАТЬ: Фактически протестировано

Первое препятствие было: можетвы фактически изменяете существующую таблицу во временную таблицу, и ответ был: да!

ALTER TABLE Clients ADD 
    [ValidFrom] DateTime2 (2) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL DEFAULT '1753-01-01 00:00:00.000',
    [ValidTo] DateTime2 (2) GENERATED ALWAYS AS ROW END HIDDEN NOT NULL DEFAULT '9999-12-31 23:59:59.997',
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
GO

ALTER TABLE Clients SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.ClientsHistory))
GO

Важным битом выше являются значения по умолчанию для полей ValidFrom и ValidTo.Это работает только в том случае, если ValidTo является максимальным значением, которое может иметь DateTime2, следовательно, «9999-12-31 23: 59: 59.997».ValidFrom, кажется, не имеет значения, поэтому я установил его на минимум, чтобы охватить все.

Хорошо, поэтому я преобразовал таблицу, но теперь у нее есть два дополнительных поля, которые не в таблице не Azure.Это теоретически скрыто, но будет ли на них жаловаться наше программное обеспечение?

Кажется, нет.Запустил программное обеспечение, отредактировал запись в таблице «Клиенты» и сохранил ее, и программа вообще не жаловалась.

Проверено таблицы «Клиенты и истории клиентов»: -

SELECT * FROM Clients  
FOR SYSTEM_TIME BETWEEN '1753-01-01 00:00:00.000' AND '9999-12-31 23:59:59.997'   
WHERE sCAccountNo = '0001064'
ORDER BY ValidFrom

Показываетдве записи, исходная и отредактированная, а также существующие поля updatedUser и updatedDate отображаются правильно, поэтому я знаю, кто и когда внес изменения.

SELECT * FROM ClientsHistory

Показывает исходную запись с ValidTo, установленным на датуизменение,

Все кажется хорошим, теперь мне просто нужно убедиться, что он по-прежнему возвращает только текущую запись в запросах и нашему программному обеспечению: -

SELECT * FROM Clients  
WHERE sCAccountNo = '0001064'

Просто вернул одну запись,и не отображает скрытые поля ValidFrom и ValidTo.

Выполнил поиск в нашем программном обеспечении для клиента 0001064, и снова он просто возвратил одну запись и не пожаловался на два дополнительных поля.

Еще нужно настроить несколько триггеров и добавить еще одно поле HIDDEN для записи программы и версии из строки подключения, но это выглядит как TemporalТаблицы дают мне жизнеспособную опцию аудита.

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

...