1

我有一个 Web 项目,它使用数据库来存储用于生成任务的数据,这些任务将为远程机器处理以更改记录并存储新数据。我的问题是我必须将所有更改存储在每个表上,但我不需要所有这些信息。例如,表 A 可能有 5 个字段,但出于历史目的我只需要 2 个字段。另一个表 B 可能有 3 个,我必须添加另一个表(例如日期)。另外,我不需要在日常任务生成期间进行更改,只需要最近的一个。

维护变更历史的最佳方式是什么?有人告诉我,一个好主意是有两个表,A (B) 表和另一个名为 A_history (B_history) 的表,其中包含所需的字段。这实际上是我正在做的,使用触发器插入历史表,但我对这种方法感到不舒服。我的项目使用 Spring(Spring-data、Hibernate 和 JPA),如果我更改数据库(当前是 MySQL),我必须迁移触发器。有没有管理历史记录的好方法?可以使用 Hibernate/JPA 注释生成表。

如果我保持两个表的方法,我可以向存储库添加一个方法来一次从当前表和历史表中获取行吗?

4

2 回答 2

1

我不是数据库专家。我所看到的他们所做的归结为几种方法。

1) 他们向事务表添加了一个触发器,该触发器将插入和更新复制到历史表但不删除。这意味着任何需要包含历史的查询都可以从历史表中完成,因为所有当前信息也都在那里。

  • a) 他们可以用时间和日期标记历史表中的每个条目,并跟踪原始记录的所有状态。
  • b) 他们只能跟踪原始记录的当前状态,然后在删除原始记录时解决。

2)他们有一个周期性的任务,将标记为可删除的数据复制到历史表中。然后它从事务表中删除数据。事务表中的任何查询都必须确保忽略可删除的行。任何需要历史的查询都必须搜索两个表并合并结果。

3)如果数据量不是太大,他们只是将所有内容都放在一个表中,并将一些条目标记为历史记录。查询必须忽略历史行。包含历史的查询很容易。随着表增长到包含许多未使用的行,这可能会减慢数据库访问速度,但有时可以通过巧妙地使用索引来改善这种情况。

于 2013-04-29T15:23:56.140 回答
1

为此,有一个特殊的Hibernate Envers项目。请参阅此处的官方文档。只需配置它,使用 @Audited 注释注释必要的属性,仅此而已。不需要数据库触发器。

一个陷阱:如果您想为每个删除操作记录一条记录,那么您需要使用Session.delete(entity)way 而不是 HQL “删除 ...”。

编辑。还可以查看spring data jpa 的原生审计支持

于 2013-04-30T15:26:55.597 回答