Ваши данные аудита должны храниться отдельно для каждой таблицы, а не в одном месте. Что вам нужно сделать, это создать таблицу аудита для каждой из таблиц, которые вы хотите отслеживать, и создать триггеры для создания записи в таблице аудита для любой операции манипулирования данными в проверенной таблице.
Определенно желательно запретить DELETE
операции с таблицами items
и item_options
- добавьте флаги, такие как item_active
и item_option_active
, чтобы вы могли вместо них мягко удалить их. Это нормальная практика в ситуациях, когда вы делаете такие вещи, как хранение счетов-фактур, которые ссылаются на товары, заказанные в прошлом, и вам нужны данные для исторических отчетов, но не для повседневного использования.
Ваши таблицы аудита - это не то, что вы должны использовать для ссылки на старые данные, ваша обычная модель данных должна поддерживать простое «сокрытие» старых данных там, где есть вероятность, что они все еще будут использоваться, и хранение нескольких версий данных, которые могут измениться. со временем.
Для аудита также полезно сохранить имя пользователя последнего пользователя, изменившего данную запись - при использовании из веб-приложения вы не можете использовать функцию USER()
MySQL для получения какой-либо полезной информации о том, кто вошел в систему. Добавление столбца и его заполнение означает, что вы можете использовать эту информацию в своих триггерах аудита.
NB: Я предполагаю, что вы не позволите изменять идентификаторы элементов при нормальных условиях - это сделает вашу систему аудита более сложной.
Если вы добавите в таблицы активные флаги и данные с последним изменением, они будут выглядеть примерно так:
Таблица предметов:
mysql> desc items;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| item_id | int(11) | NO | PRI | NULL | auto_increment |
| item_name | varchar(100) | YES | | NULL | |
| item_description | text | YES | | NULL | |
| item_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
Таблица параметров товара:
mysql> desc item_options;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| option_id | int(11) | NO | PRI | NULL | auto_increment |
| item_id | int(11) | YES | MUL | NULL | |
| option_name | varchar(100) | YES | | NULL | |
| option_price | int(11) | YES | | NULL | |
| option_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
В ваших таблицах аудита должны храниться четыре дополнительных элемента информации:
- Идентификатор аудита - этот идентификатор уникален только для истории этой таблицы, это не глобальное значение
- Изменение сделано - пользователь базы данных, который внес изменение
- Изменить дату / время
- Тип действия -
INSERT
или UPDATE
(или DELETE
, если вы это разрешаете)
Ваши таблицы аудита должны выглядеть примерно так:
Таблица аудита товаров:
mysql> desc items_audit;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| audit_id | int(11) | NO | PRI | NULL | auto_increment |
| item_id | int(11) | YES | | NULL | |
| item_name | varchar(100) | YES | | NULL | |
| item_description | text | YES | | NULL | |
| item_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
| change_by | varchar(50) | YES | | NULL | |
| change_date | datetime | YES | | NULL | |
| action | varchar(10) | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
Таблица параметров проверки позиций:
mysql> desc item_options_audit;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| audit_id | int(11) | NO | PRI | NULL | auto_increment |
| option_id | int(11) | YES | | NULL | |
| item_id | int(11) | YES | | NULL | |
| option_name | varchar(100) | YES | | NULL | |
| option_price | int(11) | YES | | NULL | |
| option_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
| change_by | varchar(50) | YES | | NULL | |
| change_date | datetime | YES | | NULL | |
| action | varchar(10) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
Не используйте внешние ключи в ваших таблицах аудита; строки в таблицах аудита не являются дочерними строками записей, которые они проверяют, поэтому внешние ключи бесполезны.
Триггеры
Примечание: MySQL не поддерживает триггеры нескольких операторов, поэтому вам нужен один для каждого из INSERT
, UPDATE
и DELETE
(если применимо).
Ваши триггеры просто должны INSERT
ввести все значения NEW
в таблицу аудита. Определения триггера для таблицы items
могут быть:
/* Trigger for INSERT statements on the items table */
CREATE DEFINER=`root`@`localhost` TRIGGER trigger_items_insert_audit
AFTER INSERT ON items
FOR EACH ROW BEGIN
INSERT INTO items_audit (
item_id, item_name, item_description,
item_active, modified_by, change_by,
change_date, action
) VALUES (
NEW.item_id, NEW.item_name, NEW.item_description,
NEW.item_active, NEW.modified_by, USER(),
NOW(), 'INSERT'
);
END;
/* Trigger for UPDATE statements on the items table */
CREATE DEFINER=`root`@`localhost` TRIGGER trigger_items_update_audit
AFTER UPDATE ON items
FOR EACH ROW BEGIN
INSERT INTO items_audit (
item_id, item_name, item_description,
item_active, modified_by, change_by,
change_date, action
) VALUES (
NEW.item_id, NEW.item_name, NEW.item_description,
NEW.item_active, NEW.modified_by, USER(),
NOW(), 'UPDATE'
);
END;
Создайте похожие триггеры для таблицы item_options
.
Обновление: история данных в электронной коммерции
Аудит, который мы провели выше, позволит вам вести историю любой данной таблицы базы данных, но создает хранилище данных, которое не подходит для использования с данными, к которым необходимо регулярно обращаться.
В системе электронной коммерции важно сохранять пригодные для использования исторические данные, чтобы вы могли изменять атрибуты, сохраняя при этом старые значения в определенных ситуациях.
Это должно быть полностью отделено от вашего решения по аудиту
Лучший способ сохранить историю - создать таблицу истории для каждого атрибута , который должен храниться исторически. Этот вопрос Stackoverflow содержит полезную информацию о ведении истории данного атрибута .
В вашей ситуации, если вас интересуют только цена и заголовок, вы должны создать таблицу prices
и таблицу item_titles
.Каждый из них будет иметь внешний ключ либо к таблице item_options
, либо к таблице items
(главные таблицы будут по-прежнему хранить текущую цену или заголовок) и иметь цену или заголовок сего даты вступления в силу.Эти таблицы должны иметь детальные (возможно, основанные на столбцах) разрешения, чтобы избежать обновления дат effective_from
и фактических значений после вставки записи.
В этих таблицах также следует использовать вышеприведенное решение аудита.