我有一个Web项目,它使用数据库来存储数据,这些数据用于生成将为远程计算机处理的任务,以更改记录并存储新数据。我的问题是我必须在每个表上存储所有更改但我不需要所有这些信息。例如,表A可以有5个字段但我只需要2个用于历史目的。另一个表B可能有3个,我将不得不添加另一个表(例如日期)。此外,我不需要在日常任务生成期间进行更改,只需要更新最新任务。
维护更改历史记录的最佳方法是哪种?有人告诉我,一个好主意是有两个表,A(B)表和另一个名为A_history(B_history)的表,带有所需的字段。这实际上就是我正在做的事情,使用触发器插入历史表,但我对这种方法感到不舒服。我的项目使用Spring(Spring-data,Hibernate和JPA),如果我更改数据库(当前是MySQL),我必须迁移触发器。有没有一种管理历史记录的好方法?可以使用Hibernate / JPA注释生成表。
如果我维护两个表的方法,我可以在存储库中添加一个方法来立即从当前表和历史表中获取行吗?
答案 0 :(得分:1)
我不是数据库专家。我所看到的确实归结为几种方法。
1)他们向事务表添加一个触发器,用于复制对历史表的插入和更新,但不删除。这意味着任何需要包含历史记录的查询都可以从历史记录表中完成,因为所有当前信息都存在。
2)他们有一个周期性的任务,将标记为可删除的数据复制到历史表中。然后它从事务表中删除数据。事务表中的任何查询都必须确保忽略可删除的行。任何需要历史记录的查询都必须搜索两个表并合并结果。
3)如果数据量不是太大,他们只需将所有内容保留在一个表中,并将某些条目标记为历史记录。查询必须忽略历史行。包含历史记录的查询很容易。这可能会减慢数据库访问速度,因为表增长到包含许多未使用的行,但有时可以通过巧妙地使用索引来改善这些行。
答案 1 :(得分:1)
对于这个pourpose,有一个特殊的Hibernate Envers项目。参见官方文档here。只需配置它,使用@Audited注释注释必要的属性即可。不需要DB触发器。
一个缺陷:如果你想为每个删除操作创建一个记录,那么你需要使用Session.delete(entity)
方式而不是HQL“删除...”。
编辑。另请查看弹簧数据jpa的native auditing support。