Аудит журнала для данных о продуктах? - PullRequest
2 голосов
/ 25 апреля 2011

Когда сотрудники меняют информацию о названии продукта, названии опции или цене. Он должен вставить данные в журнал истории и кто это сделал.

таблица предметов:

item_id (PK)
item_name
item_description

Примечание: цены указаны в таблице item_options

Таблица item_options:

option_id (PK)
item_id (FK)
option_name
option_price

У предмета может быть 1 или более вариантов.

Если я хочу изменить имя items.item_name, следует скопировать текущую запись в таблицу истории, удалить текущую запись из таблицы items, а затем вставить новую запись с новой информацией в таблицу items?

А как насчет item_options, как это будет работать? Если есть несколько опций из конкретного item_id, значит ли это, что мне нужно дублировать опции в таблицу истории?

Как должны выглядеть таблицы журнала / истории аудита для items и item_options?

Спасибо

Ответы [ 2 ]

5 голосов
/ 25 апреля 2011

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

Определенно желательно запретить 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 и фактических значений после вставки записи.

В этих таблицах также следует использовать вышеприведенное решение аудита.

0 голосов
/ 25 апреля 2011

если у вас нет кучки ограничений - тогда ваши данные будут испорчены в спешке, когда вы осиротите записи элемента, удалив записи опций и visaversa.

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

изображения, если у вас есть элемент с 2 вариантами.

теперь вы измените имя элемента, этот элемент будет удален (и перемещен в историю) - у вас есть несвязанные варианты ... это то, что вы намереваетесь?

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

Вместо этого создайте логику триггера, чтобы разрешить только «разумное» редактирование элемента.при желании поместите копию записи в параллельную таблицу истории, но НЕ удаляйте оригинал.

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

...