Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Журналирование действий пользователей / 11 сообщений из 11, страница 1 из 1
29.11.2010, 21:13
    #36984644
SeZuka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
Разрабатываю базу на Firebird, решил добавить в нее контроль за действиями пользователей с возможностью откатов этих действий.
Ко всем таблицам добавить по 3 поля: пользователь, действие и время. Пример:
IDUSERACTIONDATETIMEDATA11A10-01-2010 10:00AAAAA пользователь 1 добавил запись 112M10-01-2010 10:05BBBBB пользователь 2 изменил запись 122A10-01-2010 11:00QWERTY пользователь 2 добавил запись 221D10-01-2010 12:00QWERY пользователь 1 удалил запись 2
Первичный ключ будет по 4 полям ID, USER, ACTION, DATETIME. Со внешними проблема, т.к. ID уже не уникален.
Доступ пользователей и работа с таблицами будет происходить только через представления и хранимые процедуры.
Собственно вопросы.
1. Оптимальный запрос для представления, чтобы отражались только актуальные данные, а также запрос на определенную дату/время?
2. Объединение таких таблиц один ко многим, как?
3. Какие индексы создавать для ускорения п. 1 и 2?
4. Стоит ли вообще над этим заморачиваться или тут минусов больше чем плюсов?
...
Рейтинг: 0 / 0
30.11.2010, 03:02
    #36984974
SERG1257
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
Обычное лобовое решение для аудита/истории - создание таблицы с историей
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table my_table_audit 
(
id int primary key,
action_date datetime,
affected_record_id int,
action char( 1 ) check action in ('U','D'),
user,
data_in_table
)
Где action удалено или обновлено, первое поле необязательно, в качестве первичного ключа вполне может быть action_date, affected_record_id
Таблица заполняется триггером на удаление/обновление.
Насчет отката тут все не так просто, ибо данные редко бывают нужны сами по себе, не завязанные на другие таблицы.

Если вам нужна именно состояние на дату, то вышеуказанная структура не совсем оптимальна, поле action_date лучше заменить двумя полями dfrom и dto. Пошерстите по форуму, эта тема появляется с завидной регулярностью.
...
Рейтинг: 0 / 0
30.11.2010, 05:59
    #36985011
SeZuka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
Такой метод я уже использовал ранее.
Может не совсем ясно выразил мысль. Журнал хранится не в отдельной таблице, а к каждой информационной таблице добавляются поля с пользователем, действием и датой. При добавлении новой записи добавляется запись с новым ID, кодом пользователя, действием A, временем и собственно данными таблицы. При изменении записи с этим ID, она не изменяется, а добавляется новая запись с этим же ID, текущим пользователем, временем, действием М и новыми данными. При удалении ничего не удаляется, а добавляется новая запись с указанным ID, действием D, текущим пользователем, временем и данными. При желании "удаленную" запись можно восстановить, добавится новая запись с действием R.
Для просмотра используется представление которое возвращает для каждого ID последнюю запись, за исключением тех, где последняя с действием D "удалена".
Конечно получается огромная избыточность, но для базы где будет модифицироваться не более сотни записей в день это не критично.
...
Рейтинг: 0 / 0
30.11.2010, 09:12
    #36985116
Senya_L
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
автор...решил добавить в нее контроль за действиями пользователейЕсли решается исключительно задача протоколирования изменений, то решение явно избыточное. Хотя бы потому, что протокол "поднимать" придется очень редко, а запросы к текущим идут ежедневно. Есть и другие подходы . Другое дело, когда необходима "историчность" данных требуется учесть, например, в отчетах и
SeZukaСобственно вопросы.
1. Оптимальный запрос для представления, чтобы отражались только актуальные данные, а также запрос на определенную дату/время?
2. Объединение таких таблиц один ко многим, как?
3. Какие индексы создавать для ускорения п. 1 и 2?
4. Стоит ли вообще над этим заморачиваться или тут минусов больше чем плюсов?1. Оптимально добавить еще и поле "Дата окончания действия записи". Для актуальной записи в это поле задаем некое значение "бесконечности", например, '3000-01-01 00:00:00'. Выборка актуальных данных:
Код: plaintext
select * from DataTable where vt_end = '3000-01-01 00:00:00'
Тогда и вопросы 2 и 3 отпадут.
4. Да кто же его знает "стоит над этим заморачиваться" или нет. Если просто "шоб было", то нет, не стОит, а если этого требует заказчик и ТЗ, то "это" быть обязано. А как еще иначе?
...
Рейтинг: 0 / 0
30.11.2010, 11:41
    #36985536
ENO
ENO
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
SeZuka,

первичный ключ какой в твоих таблицах будет?
...
Рейтинг: 0 / 0
30.11.2010, 15:08
    #36986289
SeZuka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
ENO,
Первичный ключ будет по 4 полям ID, USER, ACTION, DATETIME.
...
Рейтинг: 0 / 0
30.11.2010, 15:36
    #36986401
SERG1257
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
SeZuka Оптимальный запрос для представления, чтобы отражались только актуальные данные, а также запрос на определенную дату/время?добавте в каждый запрос and :query_date between dfrom and dto
Первичным ключом будет id, dto (можно id, dfrom но последние записи будут запрашиваться чаще первых)
Проблемы - невозможность декларативно обеспечить непересекаемость и неразрывность. Придется регулярно (по триггеру, или для всех) выполнять запрос типа дай все записи (кроме самой первой) где у этого id нет предыдущей записи и дай все записи (кроме последней) где нет последующей. И не надо надеятся что приложение это отследит.

SeZuka 4. Стоит ли вообще над этим заморачиваться или тут минусов больше чем плюсов?ОЧЕНЬ сильно зависит от требований приложения. В ПОДАВЛЯЮЩЕМ случае всех интересует текущие данные, а история/аудит постольку поскольку. Хотите перебирать эти записи при ЛЮБОМ обращении к таблице - вперед с песней.
Имеет смысл для таблиц типа тариф на дату.

SeZuka Первичный ключ будет по 4 полям ID, USER, ACTION, DATETIME.У вас одну и туже запись могут несколько пользователей задевать? Шустрый юзер может делать несколько РАЗНЫХ апдейтов в секунду над одной записью?
...
Рейтинг: 0 / 0
30.11.2010, 17:13
    #36986776
SeZuka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
Senya_LЕсть и другие подходы .
Похоже метод "таблиц двойников" проще в реализации и по скорости доступа к актуальным данным мой даже рядом не стоял... Возьму его за основу.
...
Рейтинг: 0 / 0
01.12.2010, 11:15
    #36988115
zenk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
SeZuka, несколько замечаний.

1. Создавайте таблицы "двойников" только на те таблицы, в которые у пользователей есть возможность ручного ввода данных. Если таблица заполняется процедурами, то необходимость в такой таблице отпадает (ну если только на этапе отладки может помочь).

2. Создание таблиц аудито просто заскриптовать:
копируем всю структуру таблицы в таблицу аудита, но не забываем поменять автоматически заполняемые типы (Serial и т.п.) на аналогичные им простые типы. После добавляем поля для хранения информации об изменениях. Аналогичным образом проектируем сами тела тригеров. Нажали где-то кнопочку - приложение создало таблицу аудита и тригера. Индексы для таблиц аудита практически не нужны.

3. Таблицы аудита имеет смысл создавать в отдельной базе данных, а в исходной создавать синонимы. Это немного увеличивает стойкость системы аудита ко взлому. Но основной плюс - отдельные подходы к размещению пространств БД на физических устройствах и архивирования для основной базы и журнальной.
...
Рейтинг: 0 / 0
01.12.2010, 11:20
    #36988137
zenk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
SeZuka,

и ещё: используйте не коды "A", "M", "D", а более понятные "I", "U", "D" - поскольку они представляют собой просто первые буквы от соответствующих операторов SQL.
...
Рейтинг: 0 / 0
01.12.2010, 18:25
    #36989778
SeZuka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Журналирование действий пользователей
zenk,

Спасибо за советы, учту.
...
Рейтинг: 0 / 0
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Журналирование действий пользователей / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]