Список вопросов
Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
898
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
951
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
941
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1726
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4398
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
MS SQL Server. T-SQL. Организация "истории изменений"
Просмотров: 264
 
Ответов: 2
Захотелось мне сделать так, чтобы любые изменения какой-либо записи в определенной таблице отслеживались и всегда можно было откатиться к более старой версии.
Поразмыслив я прикнул, что хорошо бы реализовать это на уровне БД, чтобы исключить какие-либо накладки в приложении.
Создаем mytable_history, с сигнатурой идентичной mytable, дополняем полями historyID и historyDate, вешаем на mytable триггеры, которые при вставке и изменении копируют соответствующую запись в history с новым historyID, и проставляют дату изменения.
Решение устраивает. Любое изменение всегда будет отражено, а старая версия сохранена даже если взломан сайт — доступа у аккаунта по кторому сайт ходит в БД к таблице _history нет.
И тогда захотелось большего, знать какой пользователь системы сделал то или иное изменение. Но на уровне базы данных это неизвестно. Идентификатор пользователя известен только на уровне приложения, для базы данных же они все «на одно лицо» и ходят под общим аккаунтом к sql серверу.
Первой мыслью было при коннекте создавать переменную с идентификатором пользователя и использовать её в триггерах. Но одно и тоже соединение могут использовать разные пользователи сайта — ASP.NET держит в пуле n-e количество соединений и выдает по необходимости, так что это не годится. Значит нужно передавать идентификатор в каждом запросе к БД.
Собственно вопросы:
1) правилен ли вообще такой дизайн? Может то что я хочу по-другому делают? Но не хочется всетаки выносить систему версий из БД.
2) как можно к запросу прикрепить переменную, так чтобы она не влияла на запрос, но была доступна триггеру AFTER UPDATE.
Используется linq2sql, т.е. теоретически можно сделать свой DataContext и сделать отправку идентификатора пользователя с каждым запросом. Вопрос только как это можно реализовать?
По первой части вопроса могу сказать — да, дизайн вполне нормальный. Я использую примерно такой же подход (СУБД Oracle).
По части отслеживания того, какой конкретно юзер сделал определенное изменение — это зависит от того, как вы храните информацию о юзерах. Если юзеры хранятся в базе в отдельной табличке, как я предполагаю, то можно делать так.
Добавьте колонку last_modified_by_user на таблицу mytable, и, соответственно, таблицу mytable_history.
Соответственно, когда какой-то пользователь выполняет операцию (insert / update / delete), вы выставляете ID-шник этого юзера, и при срабатывании вашего after-insert, after-update, after-delete row-level триггера этот айдишник перенесется в таблицу аудита.
А как вставлять айдишник пользователя изначально в таблицу mytable? Ну, создавать server-side user-context в котором хранится имя-id пользователя, ассоциированный с пользовательской сессий, и при выполнении запроса с уровня бизнес логики — заполнять это поле.
Как-то так.
Не надо изобретать велосипедов - на уровне MS SQL это уже реализовано https://msdn.microsoft.com/en-us/library/bb933994.aspx
Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться