Проектирование базы данных для ведения журнала аудита


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

некоторые вопросы уже спрашивали здесь об этом, но я не согласен, что существует один лучший подход для всех сценариев:

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

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

  • зрелость схемы базы данных
  • как будут запрашиваться журналы
  • вероятность того, что потребуется воссоздать записи
  • что более важно: написать или прочитать производительность
  • характера тех ценностей, которые в настоящее время регистрируется (строки, числа, большие двоичные объекты)
  • место для хранения доступно

подходы, которые я знаю:

1. Добавить столбцы для даты создания и изменения и пользователя

таблица пример:

  • id
  • значение_1
  • значение_2
  • value_3
  • created_date
  • modifed_date
  • created_by
  • modified_by

основные минусы: мы теряем историю изменений. Не могу откатиться после совершения.

2. Вставить только таблицы

пример таблицы:

  • id
  • значение_1
  • значение_2
  • value_3
  • С
  • до
  • deleted (boolean)
  • пользователей

основные минусы: Как сохранить внешние ключи в курсе? Требуется огромное пространство

3. Создайте отдельную таблицу истории для каждого таблица

история таблицы пример:

  • id
  • значение_1
  • значение_2
  • value_3
  • value_4
  • пользователей
  • deleted (boolean)
  • метка

основные минусы: необходимо дублировать все проверенные таблицы. Если схема изменится, это будет необходимо для переноса всех журналов тоже.

4. Создание сводной таблицы истории для всех Таблицы

история таблицы пример:

  • имя_таблицы
  • поле
  • пользователей
  • новое_значение
  • deleted (boolean)
  • метка

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

5 125

5 ответов:

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

Так, например, если у вас есть таблица под названием возможности для отслеживания сделок купли-продажи, вы бы на самом деле создать два отдельных таблицы:

возможности
Opportunities_Content (или что-то в этом роде)

The возможности таблица будет содержать информацию, которую вы будете использовать для уникальной идентификации записи, и будет содержать первичный ключ, на который вы ссылаетесь для своих отношений внешнего ключа. Элемент Opportunities_Content таблица будет содержать все поля, которые ваши пользователи могут изменить и для которых вы хотите сохранить журнал аудита. Каждая запись в контент таблица будет включать свой собственный PK и измененные и измененные данные даты. Элемент возможности таблица будет содержать ссылку на текущую версию, а также информацию о том, когда основная запись изначально была создана и кем.

вот простой пример:

CREATE TABLE dbo.Page(  
    ID int PRIMARY KEY,  
    Name nvarchar(200) NOT NULL,  
    CreatedByName nvarchar(100) NOT NULL, 
    CurrentRevision int NOT NULL, 
    CreatedDateTime datetime NOT NULL

и содержание:

CREATE TABLE dbo.PageContent(
    PageID int NOT NULL,
    Revision int NOT NULL,
    Title nvarchar(200) NOT NULL,
    User nvarchar(100) NOT NULL,
    LastModified datetime NOT NULL,
    Comment nvarchar(300) NULL,
    Content nvarchar(max) NOT NULL,
    Description nvarchar(200) NULL

Я бы, вероятно, сделал PK таблицы содержимого многоколоночным ключом из PageID и ревизии, предоставленной ревизией был тип личности. Вы бы использовали столбец Revision в качестве FK. Затем вы вытаскиваете консолидированную запись, присоединяясь следующим образом:

SELECT * FROM Page
JOIN PageContent ON CurrentRevision = Revision AND ID = PageID

там могут быть некоторые ошибки там...это у меня в голове не укладывается. Однако это должно дать вам представление об альтернативном шаблоне.

Джош

Если вы используете SQL Server 2008, вы, вероятно, следует рассмотреть возможность отслеживания измененных данных. Это новое для 2008 года и может сэкономить вам значительный объем работы.

Я не знаю никакой ссылки, но я уверен, что кто-то что-то написал.

однако, если цель состоит в том, чтобы просто иметь запись о том, что произошло-наиболее типичное использование журнала аудита-то почему бы просто не сохранить все:

timestamp
username
ip_address
procedureName (if called from a stored procedure)
database
table
field
accesstype (insert, delete, modify)
oldvalue
newvalue

предположительно это поддерживается триггером.

Я думаю, что нет ничего лучше дерева решений. Поскольку некоторые из плюсов и минусов (или требований) на самом деле не являются счетными. Как вы измеряете зрелость, например?

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

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

мы создадим небольшой пример базы данных для приложения блоги. Требуются две таблицы:

blog: сохраняет уникальный идентификатор записи, заголовок, содержимое и удаленный флаг. audit: сохраняет базовый набор исторических изменений с идентификатором записи, идентификатором записи в блоге, типом изменения (новое, редактирование или удаление) и датой/временем этого изменения. Следующий SQL-создает blog и индексирует удаленный столбец:

CREATE TABLE `blog` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
    `title` text,
    `content` text,
    `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    KEY `ix_deleted` (`deleted`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Blog posts';

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

CREATE TABLE `audit` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
    `blog_id` mediumint(8) unsigned NOT NULL,
    `changetype` enum('NEW','EDIT','DELETE') NOT NULL,
    `changetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `ix_blog_id` (`blog_id`),
    KEY `ix_changetype` (`changetype`),
    KEY `ix_changetime` (`changetime`),
    CONSTRAINT `FK_audit_blog_id` FOREIGN KEY (`blog_id`) REFERENCES `blog` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;