我正在组建一个员工数据库,我需要能够修改员工信息,但也要跟踪所有修订。我应该如何构建数据库,以便我可以对同一用户数据进行多次修订,但能够查询最新版本?我正在查看很少变化的信息,例如姓氏,但我需要能够查询过期值。因此,如果Jenny Smith将她的名字更改为Jenny James,我需要能够在搜索其旧名称时找到用户的当前信息。
我假设我至少需要2个表,一个包含uid,另一个包含修订。然后我会加入他们并查询最新版本。但是,我是否应该进一步分解,具体取决于数据更改频率或数据类型?我正在查看每个记录大约40个字段,每个更新只有一个或两个字段可能会更改。此外,我无法从数据库中删除任何数据,我需要能够回顾所有以前的记录。
答案 0 :(得分:2)
执行此操作的一种简单方法是添加已删除的标记,而不是更新记录,而是在现有记录上设置已删除的标记并插入新记录。
如果您愿意,您当然也可以将现有记录写入存档表。但如果变化很少,而且表格不大,我也不会打扰。
要获取活动记录,请使用'where deleted = 0'进行查询,当此字段存在索引时,速度影响将最小。
通常,这会增加一些其他字段,例如修订号,上次更新记录时以及更新后的字段。修订号对于获取以前的版本以及执行乐观锁定非常有用。一旦系统运行而不是在需求收集期间,通常会出现“最后和何时更新”的问题,并且是包含“主”数据的任何表中的有用字段。
答案 1 :(得分:2)
我会使用单独的表,因为那时你可以有一个唯一的标识符,指向所有其他子记录,这也是表的PK,我认为这样你不太可能遇到数据完整性问题。例如,您有Mary Jones,他在地址表和电子邮件表以及性能评估表等中都有记录。如果您将更改记录添加到主表,您将如何重新链接所有现有信息?使用单独的历史表,这不是问题。
如果一个表中包含已删除的字段,则必须具有非自动生成的人员ID和自动生成的记录。
您还有可能忘记使用几乎每个查询所需的where deleted = 0 where子句。 (如果您确实使用了已删除的标志字段,请自己帮个忙并设置一个视图,其中where deleted = 0并要求开发人员在查询中使用视图而不是原始表。)
使用已删除的标志字段,您还需要一个触发器,以确保只有一条记录被标记为活动。
答案 2 :(得分:0)
@Peter Tillemans的建议是达到你要求的常用方法。但我不喜欢它。
数据库的结构应反映正在建模的现实事实。
我会为obsolete_employee
创建一个单独的表,只存储将来需要搜索的历史信息。这样,您可以保持真实的员工数据表清洁,并仅保留必要的旧数据。此方法还将简化与搜索历史数据无关的应用程序的报告和其他功能。
想一想当你输入select * from employee
时会得到的那种温暖的感觉,只有当前的,正确的善良才能回来!