跟踪数据库更改或使用时间戳区分记录?

Track database changes or differentiate records with timestamp?

对很多人来说,跟踪数据库的变化肯定是一个大问题,但似乎知名人士都有这方面的软件。

我的问题是一个小型 SQL 数据库,有 10 个 table,每个 <10 列,使用连接创建一个 "master" junction table: 每年更新几次,增加行数(有很多重复信息),然后取MAX id (PK)到在网站上生成并 post 表格形式的最新数据(摘自 "master")?这 与更新记录相比, 我将在特定时刻丢失有关值的信息。

教师联系信息的典型行包括 fName、lName、schoolName、[address & phone info];曲目或试听信息:年份、乐器、作品、作曲家、publisher/edition.

其他人询问过有关跟踪数据库更改的问题,但最近只有一个,而且没有很多 votes/details: How to track data changes in a database table Keeping history of data revisions - best practice? How to track data changes in a database table

这个轻量级解决方案看起来很有前途,但我不知道它没有获得投票是因为它没有帮助,还是因为人们不感兴趣。 How to keep track of changes to data in a table?

如果需要更多背景信息: 我是一名音乐老师(即业余程序员),为我们的组织维护 Joomla 网站。我正在使用一个名为 Sourcerer 的 Joomla 插件来创建动态内容(PHP/SQL 到 Joomla 数据库),以便更轻松地传达更改(日期、人员、规则、曲目等)。多年来,这是通过需要几天时间更新的静态页面(和纸质手册)。

但是,我也希望能够回顾并查看特定时间的数据库状态:谁教过什么地方,列出了哪些试听曲目等等,就像我们可以使用纸质版本一样。注意:我没有跟踪 HTML 更改,只跟踪从数据库提供的信息。

感谢您的帮助! (我关注 SO 多年,但这是我的第一个问题。)

我现在用来生成 "master junction table." 的代码我会将其修改为 "INSERT into" 我的新行并通过 Sourcerer 从中查询 post 在线信息。

CREATE TABLE 011people_to_schools_junction 
AS (
   SELECT * 
   FROM (
       SELECT a.peopleID, a.districtID, a.firstName, a.lastName, a.statusID, c.schoolName 
       FROM 01People a 
       INNER JOIN ( 
           SELECT districtID, MAX(peopleID) peopleID 
           FROM 01People 
           GROUP BY districtID 
            ) b 
       ON a.districtID = b.districtID 
       AND a.peopleID = b.peopleID 

       INNER JOIN (
           SELECT schoolID, MAX(peopleID) peopleID
           FROM 01people_to_schools_junction ab
           GROUP BY schoolID
           ) z
        ON z.peopleID = a.peopleID 

        LEFT JOIN 01Schools c 
        ON c.schoolID = z.schoolID 
        WHERE z.schoolID IS NOT NULL
        OR z.peopleID IS NOT NULL
        ORDER BY c.schoolName
    ) t1 
);

#Add a primary key as the first column
ALTER TABLE 011people_to_schools_junction
ADD COLUMN 011people_to_schoolsID INT NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (011people_to_schoolsID);

按顺序回答您的问题:

有缺点吗?

当然,这与性能有关。如果每年增加一百万条记录,就会损害性能;并在磁盘上占用 space。

链接问题中的建议在哪里不好或不受欢迎?

问答都不错;但正确的答案取决于您的具体用例:您是否出于法律原因这样做,您希望能够以多快的速度访问数据,您拥有多少数据和更新,您希望您的历史记录功能在没有更改的情况下持续多久... 只有满足您的用例,您才会投票。

根据经验,历史应该走向不同的 table,这将提供几个优势:

  • 您当前的 table 没有变化,因此您的代码无需更改,除了将当前版本也存储在历史记录中;
  • 您的应用程序不会变慢;
  • 如果您的历史 table 增长了,您可以轻松地将它们移动到不同的服务器;

为了选择是拥有单个历史记录 table 还是多个(每个备份一个 table)取决于您计划如何检索数据以及您希望如何处理数据:

  • 如果您镜像每个 table 添加时间戳和用户 ID,您的代码几乎不需要修改;但是您最终会得到两倍的 table,并且任何结构更改都需要在历史 table 中复制;

  • 如果您使用时间戳、用户 ID、table 名称和记录的 json 表示来构建单个历史记录 table,您将构建它更轻松,而为了检索它,您应该使用每行一个对象访问数据,即使用 Joomla 的 dbo getObjectList(),然后对象将与您存储在历史记录 table 和更改中的格式相同会有相当容易的。但是查询特定 tables/fields 中的更改会困难得多。

请记住,如果不能正确检索数据,拥有数据将毫无用处。


既然你提到一年推送到网站几次,查询的开销应该不是问题(如果你每月更新,等待 5 分钟可能不是问题)。

您应该根据这些数据的其他用途寻求最佳解决方案:为了使它对任何人都有用,您将必须实施一个系统来检索历史数据。如果 phpmyadmin 足够了,那就别再看了。


我希望这吓到你了。无论哪种方式,这都是很多艰苦的工作。

如果您只想查找旧数据,您可以不时存储一份 markup/output 的副本,并将其保存到网络服务器上的不同文件夹中。这将需要几分钟的时间来设置,并且非常可靠。
当然,编写代码更有趣。但是你真的确定你需要它吗?您可以保留数据库转储,以防有一天您改变主意。