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

时间:2011-04-24 23:27:09

标签: mysql database database-design e-commerce relational-database

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

项目表:

item_id (PK)
item_name
item_description

注意:商品价格位于item_options表

item_options表:

option_id (PK)
item_id (FK)
option_name
option_price

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

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

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

item_optionsitems的审核日志记录/历史记录表应该是什么样的?

由于

2 个答案:

答案 0 :(得分:5)

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

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

您的审计表不是您应该用来引用旧数据的东西,您的普通数据模型应该支持简单地“隐藏”可能仍在使用它的旧数据,并存储将改变的多个数据版本随着时间的推移。

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

NB: 我会假设您不会在正常情况下更改项目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    |                |
+------------------+--------------+------+-----+---------+----------------+

项目选项表:

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    |                |
+---------------+--------------+------+-----+---------+----------------+

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

  • 审核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    |                |
+------------------+--------------+------+-----+---------+----------------+

项目选项审计表:

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    |                |
+---------------+--------------+------+-----+---------+----------------+

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

触发器

NB: MySQL不支持多语句类型的触发器,因此每个INSERTUPDATE和{{1}都需要一个触发器(如适用)。

您的触发器只需要将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; 表创建类似的触发器。

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

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

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

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

存储历史记录的最佳方法是为历史上需要存储的每个属性创建一个历史记录表。 This Stackoverflow question has some good information about keeping a history of a given attribute

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

您也应该在这些表格上使用上面的审核解决方案。

答案 1 :(得分:0)

如果您没有一堆约束 - 那么当您通过删除选项条目和visaversa孤立项目条目时,您的数据将会匆忙搞砸。

你要求的东西可以在触发器中完成,但这可能不是你想要的。

如果您有一个包含2个选项的项目,则

成像。

现在您更改项目名称,该项目被扣除(并移至历史记录) - 您有不可链接的选项...是您想要的吗?

参考物品的订单或其他东西怎么样?同样的问题。

相反,创建触发器逻辑以仅允许对项目进行“合理”编辑。如果需要,将记录的副本放入并行历史记录表中,但不要删除原始记录。

您还可以考虑在项目或某些日期范围中添加状态列,以便考虑此项目当前可用的想法或您可能需要的其他状态。