一尘不染

是否有MySQL选项/功能来跟踪记录更改的历史记录?

mysql

有人问我是否可以跟踪MySQL数据库中记录的更改。因此,更改字段后,可以使用旧的还是新的字段以及日期。有没有功能或通用技术可以做到这一点?

如果是这样,我正在考虑做这样的事情。创建一个名为的表changes。它包含与 表相同的字段,但以新旧为前缀,但仅适用于那些实际更改的字段和a
TIMESTAMP。它将以索引ID。这样,SELECT可以运行报告以显示每个记录的历史记录。这是个好方法吗?谢谢!


阅读 671

收藏
2020-05-17

共1个答案

一尘不染

真微妙

如果业务要求是“我想审核数据的更改-
谁做了什么以及何时做?”,则通常可以使用审核表(按照Keethanjan发布的触发器示例)。我不是触发器的忠实拥护者,但是它具有实施起来相对轻松的巨大好处-
您现有的代码不需要了解触发器和审计内容。

如果业务需求是“告诉我过去某个给定日期的数据状态是什么”,则意味着随时间变化的方面已进入您的解决方案。尽管您可以仅通过查看审计表来重建数据库的状态,但它既困难又容易出错,并且对于任何复杂的数据库逻辑而言,它都变得笨拙。例如,如果企业想知道“查找本月应该发送给在月初第一天有未付发票的客户的信件的地址”,则您可能不得不拖拉六个审计表。

相反,您可以将随时间变化的概念引入架构设计中(这是Keethanjan建议的第二种选择)。这绝对是在业务逻辑和持久性级别对您的应用程序进行的更改,因此这并非易事。

例如,如果您有一个这样的表:

CUSTOMER
---------
CUSTOMER_ID PK
CUSTOMER_NAME
CUSTOMER_ADDRESS

并且您想随时间推移进行跟踪,可以对其进行如下修改:

CUSTOMER
------------
CUSTOMER_ID            PK
CUSTOMER_VALID_FROM    PK
CUSTOMER_VALID_UNTIL   PK
CUSTOMER_STATUS
CUSTOMER_USER
CUSTOMER_NAME
CUSTOMER_ADDRESS

每次您想要更改客户记录而不是更新记录时,都将当前记录上的VALID_UNTIL设置为NOW(),并插入一个新记录,其中包含VALID_FROM(现在)和空VALID_UNTIL。您将“
CUSTOMER_USER”状态设置为当前用户的登录ID(如果需要保留该状态)。如果需要删除客户,则使用CUSTOMER_STATUS标志来表明这一点-
您永远都不能从该表中删除记录。

这样,您始终可以找到给定日期的客户表状态-
地址是什么?他们有改名字吗?通过联接到具有相似有效日期和有效日期的其他表,您可以历史重构整个图片。要查找当前状态,请搜索日期为VALID_UNTIL的记录。

它很笨拙(严格来说,您不需要valid_from,但是它使查询更容易一些)。它使您的设计和数据库访问变得复杂。但这使重建世界变得容易得多。

2020-05-17