首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >产品数据的审核日志记录?

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

Stack Overflow用户
提问于 2011-04-25 07:27:09
回答 2查看 2.3K关注 0票数 2

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

项目表:

代码语言:javascript
复制
item_id (PK)
item_name
item_description

注意:项目价格在item_options表中

item_options表:

代码语言:javascript
复制
option_id (PK)
item_id (FK)
option_name
option_price

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

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

那么item_options又是如何工作的呢?如果有来自特定item_id的多个选项,这是否意味着我需要将选项复制到历史表?

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

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-25 10:25:29

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

不允许对itemsitem_options表执行DELETE操作绝对是明智之举-添加像item_activeitem_option_active这样的标志,这样你就可以软删除它们。在某些情况下,这是正常的做法,比如存储引用过去订购的产品的发票,并需要这些数据用于历史报告目的,而不是用于日常使用。

您的审计表不应该用于引用旧数据,您的常规数据模型应该支持简单地将旧数据“隐藏”在可能仍将使用的地方,并存储随时间变化的多个版本的数据。

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

NB:我假设您不会允许在正常情况下更改项目IDs这会使您的审计系统更加复杂。

如果将活动标志和最后修改者数据添加到表中,它们将如下所示:

项目表:

代码语言:javascript
复制
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    |                |
+------------------+--------------+------+-----+---------+----------------+

项目选项表:

代码语言:javascript
复制
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仅在此表的历史记录中是唯一的,它不是创建change
  • Change date/time
  • Action类型的数据库用户所做的
  • 更改的全局值- INSERTUPDATE (如果允许,则为DELETE )

您的审核表应该如下所示:

项目审核表:

代码语言:javascript
复制
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    |                |
+------------------+--------------+------+-----+---------+----------------+

项目选项审核表:

代码语言:javascript
复制
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不支持多语句类型的触发器,因此INSERT__、UPDATEDELETE (如果适用)都需要一个触发器。

您的触发器只需将所有NEWINSERT到审计表中。items表的触发器定义可能是:

代码语言:javascript
复制
/* 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表创建类似的触发器。

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

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

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

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

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

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

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

票数 5
EN

Stack Overflow用户

发布于 2011-04-25 07:44:31

如果你没有一堆约束-那么当你通过删除选项条目和visaversa来孤立项目条目时,你的数据会在匆忙中变得混乱。

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

如果你有一个有两个选项的物品,那就成像吧。

现在您更改了项目名称,该项目将被开发(并移动到历史记录中)-您有不可链接的选项...这就是你想要的吗?

那么order或其他引用这些项目的东西呢?同样的问题。

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5773922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档