跟踪数据库表更改

时间:2014-07-07 23:25:06

标签: mysql sql database-design

我尝试实现一种方法来跟踪对名为user的表格的更改以及另一个名为report_to的表格。以下是他们的定义:

CREATE TABLE `user` 
(
    `agent_eid` int(11) NOT NULL,
    `agent_id` int(11) DEFAULT NULL,
    `agent_pipkin_id` int(11) DEFAULT NULL,
    `first_name` varchar(45) NOT NULL,
    `last_name` varchar(45) NOT NULL,
    `team_id` int(11) NOT NULL,
    `hire_date` date NOT NULL,
    `active` bit(1) NOT NULL,
    `agent_id_req` bit(1) NOT NULL,
    `agent_eid_req` bit(1) NOT NULL,
    `agent_pipkin_req` bit(1) NOT NULL,
    PRIMARY KEY (`agent_eid`),
    UNIQUE KEY `agent_eid_UNIQUE` (`agent_eid`),
    UNIQUE KEY `agent_id_UNIQUE` (`agent_id`),
    UNIQUE KEY `agent_pipkin_id_UNIQUE` (`agent_pipkin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `report_to` 
(
    `agent_eid` int(11) NOT NULL,
    `report_to_eid` int(11) NOT NULL,
    PRIMARY KEY (`agent_eid`),
    UNIQUE KEY `agent_eid_UNIQUE` (`agent_eid`),
    KEY `report_to_report_fk_idx` (`report_to_eid`),
    CONSTRAINT `report_to_agent_fk` FOREIGN KEY (`agent_eid`) REFERENCES `user` (`agent_eid`) ON DELETE NO ACTION ON UPDATE NO ACTION,
    CONSTRAINT `report_to_report_fk` FOREIGN KEY (`report_to_eid`) REFERENCES `user` (`agent_eid`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

需要跟踪的更改内容包括user.team_iduser.activereport_to.report_to_eid。我目前实现的是通过user上跟踪团队变化的更新触发器填充的表格。该表定义为:

CREATE TABLE `user_team_changes` 
(
   `agent_id` int(11) NOT NULL,
   `date_changed` date NOT NULL,
   `old_team_id` int(11) NOT NULL,
   `begin_date` date NOT NULL,
   PRIMARY KEY (`agent_id`,`date_changed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

这适用于跟踪团队变化。我能够使用联接和联合来填充历史视图,以跟踪各个用户随时间的变化。当我尝试为其他两种变更类型实现跟踪时,复杂性问题就会出现。

我考虑创建类似于团队跟踪更改的其他表,但我担心由于需要加入而导致性能下降。

我考虑的另一种方法是创建一个类似于我所拥有的视图的表,详细说明当前用户状态(它从4个表中将所有必要的用户数据连接在一起),然后在更新时插入一个有效直到日期字段的记录添加。我对此的关注是这可能占用的空间量。

我们将使用用户更改历史记录,因为我们几乎每天都会使用它来运行YTD,MTD,PMTD和时间间隔报告。

在我考虑的两个选项中,哪一个对我的特定情况最好?

1 个答案:

答案 0 :(得分:2)

您提出的选项:

  1. 使用触发器填充事务日志表。
  2. 包括一个新表,其中包含架构中的有效日期列,并通过插入新行来跟踪更改。
  3. 其中任何一个都可以使用。您可以将记录触发器添加到其他表而不会造成任何麻烦。

    这两种选择的区别是什么?一旦调试了触发器,第一个就很简单。

    在我看来,第二个选择是它会创建非规范化的冗余数据。这永远不会好。我会选择不这样做。通过明智的视图组合和生效日期列,可以创建可作为系统当前状态查看的历史表。要了解RT Snodgrass教授关于开发面向时间的应用程序的优秀书籍。 http://www.cs.arizona.edu/~rts/publications.html如果你有时间在这个项目上做一个优秀的工程(过度工程?)工作,你可以考虑这种方法。

    您提到的数据量不会在任何现代服务器硬件平台上造成难以解决的性能问题。如果你确实减慢了JOIN操作,几乎可以肯定,只要你声明所有DATEDATETIMETIMESTAMP字段,添加适当的索引就会完全解决它们{1}}。 (NOT NULL值可能会使索引和搜索陷入混乱)。

    希望这有帮助。