如何跟踪 MySQL 数据库中布尔列的更改?
Posted
技术标签:
【中文标题】如何跟踪 MySQL 数据库中布尔列的更改?【英文标题】:How to track changes to a boolean column in a MySQL database? 【发布时间】:2017-06-05 12:53:03 【问题描述】:我的应用程序为在线商店的客户提供服务。我的数据库中的一个表是“Product”,它有一列“In_Stock”。这是一个布尔 (bit(1)) 列。我的客户发送他们产品目录的数据提要,每个客户都有自己的表格版本。我想跟踪此 In Stock 列的更改,其效果是...
11/13/2016 true
12/26/2016 false
01/07/2017 true
只是这样当我进行一些审核时,我可以看到给定时间段内给定产品的状态。
我怎样才能做到最好?
创建一个单独的历史表并通过触发器仅针对一个布尔列更新它似乎有点过头了。历史专栏就足够了吗?我可以将数据保存在某种 JSON 字符串中。
【问题讨论】:
在 SO 上搜索“审计”或“审计跟踪”。或者只看右栏。 “历史”和“当前状态”最好作为两个单独的表来完成。 【参考方案1】:抱歉,任何可行的解决方案都需要第二张桌子。
一个这样的解决方案是版本范式 (vnf),它是 2nf 的一个特例。考虑包含布尔字段的表(假设它被正确规范化为至少 3nf)。现在您要跟踪对布尔字段所做的更改。一种方法是通过添加 EffectiveDate 列将行转换为版本,然后,而不是更新行,而是在日期字段中写入具有当前日期的新行(或者如果布尔字段未更改,则更新)。
这允许跟踪字段,每次更改字段时都会有一个新版本。但也有严重的缺点,尤其是行不再是实体,而是实体的一个版本。这使得无法使用该表的外键来引用实体。
但请仔细查看设计。在更改之前,您有一个没有跟踪更改的良好规范化表。添加 EffectiveDate 列后,发生了微妙的变化。除了布尔字段之外的所有字段都像以前一样仅依赖于 PK。布尔字段不仅取决于 PK,还取决于新的日期字段。它不再是 2nf。
规范化表格需要将布尔字段和日期字段移动到新表格:
create table NewTable(
EntityID int not null references OriginalTable( ID ),
EffDate date not null,
TrackedCol boolean,
constraint PK_NewTable primary key( EntityID, EffDate )
);
第一个版本是在将新行插入原始表时插入的。从那时起,仅当对原始表的更新更改布尔字段的值时,才会添加另一个版本。
Here 是先前的答案,其中包括用于获取版本化数据的当前值和任何过去值的查询。我在这里多次讨论过这个设计。
此外,还有一种方法可以构建设计,因此无需更改应用程序代码。也就是说,重新设计将对现有代码完全透明。上面链接的答案包含另一个指向更多文档的链接,以显示如何完成。
【讨论】:
【参考方案2】:我会做触发的事情。但不要复制整个列 - 采用唯一的列 ID、日志时间戳和布尔值。 有时拥有好的原木是无价的:)
【讨论】:
【参考方案3】:为此我写了一个audit trail module,它基本上复制了表格,在每一行添加了一些信息并保持原始数据表不变,除了触发器。
【讨论】:
以上是关于如何跟踪 MySQL 数据库中布尔列的更改?的主要内容,如果未能解决你的问题,请参考以下文章