审核产品数据的日志记录?

use*_*378 2 mysql database database-design relational-database e-commerce

当员工更改产品名称,选项名称或价格的信息时.它应该将数据插入历史记录日志以及完成它的人员.

物品表:

item_id (PK)
item_name
item_description
Run Code Online (Sandbox Code Playgroud)

注意:商品价格位于item_options表中

item_options表:

option_id (PK)
item_id (FK)
option_name
option_price
Run Code Online (Sandbox Code Playgroud)

一个项目可以有一个或多个选项.

如果我想更改名称items.item_name,它应该将当前记录复制到历史记录表,从items表中删除当前记录,然后在表中插入带有新信息的新记录items

怎么样item_options,那会怎么样?如果特定item_id有多个选项,那么这是否意味着我需要将选项复制到历史表中?

日志/历史记录表应该是什么样审计为itemsitem_options

谢谢

Sim*_*mon 5

您的审计数据应按表存储,而不是全部存储在一个位置.您要做的是为要跟踪的每个表创建一个审计表,并创建触发器以在审计表中为审计表上的任何数据操作操作创建记录.

绝对建议不要DELETEitemsitem_options表进行操作- 添加标记等item_active,item_option_active以便您可以软删除它们.在您执行的操作中,例如存储参考过去订购的产品的发票,并且需要数据用于历史报告目的,而不是用于日常使用.

您的审计表不应该用于引用旧数据,您的普通数据模型应该支持简单地"隐藏"可能仍在使用的旧数据,并存储随时间变化的多个数据版本.

对于审计,存储最后一个用户的用户名以修改给定记录也很有用 - 当从Web应用程序使用时,您无法使用MySQL的USER()功能获取有关谁登录的任何有用信息.添加列并填充它意味着您可以在审计触发器中使用该信息.

注意: 我假设您不允许在正常情况下更改项目ID - 这会使您的审核系统更加复杂.

如果您将活动标志和最后修改过的数据添加到表中,它们将类似于:

物品表:

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    |                |
+------------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

物品选项表:

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    |                |
+---------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

您的审计表需要存储四条额外的信息:

  • 审核ID - 此ID仅对此表的历史记录是唯一的,它不是全局值
  • 由进行更改的数据库用户所做的更改
  • 更改日期/时间
  • 动作类型 - INSERTUPDATE(或者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    |                |
+------------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

项目选项审计表:

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    |                |
+---------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

不要在审计表上使用外键; 审计表中的行不是他们审计的记录的子行,因此外键没有任何用处.

触发器

注意: 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;
Run Code Online (Sandbox Code Playgroud)

item_options表创建类似的触发器.

更新:电子商务中的数据历史记录

我们上面所做的审计将允许您保留任何给定数据库表的历史记录,但创建的数据存储不适合用于需要定期访问的数据.

在电子商务系统中,保留可用的历史数据非常重要,这样您就可以在某些情况下仍然显示旧值时更改属性.

这应该与审核解决方案完全分开

存储历史记录的最佳方法是为需要历史存储的每个属性创建历史记录表.此Stackoverflow问题有一些关于保留给定属性的历史记录的良好信息.

在您的情况下,如果您只关心价格和头衔,则需要创建一个prices表格和一个item_titles表格.每个人都有一个item_options表或items表的外键(主表仍然存储当前价格或标题),并且具有价格或标题及其生效日期.这些表应具有细粒度(可能是基于列的)权限,以避免更新effective_from日期,以及插入记录后的实际值.

您还应该在这些表上使用上面的审核解决方案.