2010-08-23 45 views
2

我正在组建一个员工数据库,我需要能够修改员工信息,但也要跟踪所有修订。我应该如何构建数据库,以便可以对相同的用户数据进行多次修订,但是能够根据最新版本进行查询?我正在查看很少发生变化的信息,例如Last Name,但我需要能够查询过期值。所以如果珍妮史密斯将她的名字改为詹妮詹姆斯,我需要能够在我搜索她的旧名时找到用户当前的信息。我应该在哪里分手我的用户记录以跟踪修订

我假设我将至少需要2个表,其中一个包含uid,另一个包含修订版。然后,我会加入他们,并查询最新的修订。但是,我应该进一步分解它,这取决于数据更改的频率或数据类型?我正在查看每个记录约40个字段,每个更新只有一个或两个字段可能会更改。此外,我无法从数据库中删除任何数据,我需要能够回顾以前的所有记录。

回答

2

这样做的一个简单方法是添加一个已删除的标志,而不是更新记录,在现有记录上设置已删除标志并插入新记录。

如果您愿意,您当然也可以将现有记录写入存档表。但如果变化不频繁,桌子不大,我就不会打扰。

要获得活动记录,使用'where deleted = 0'进行查询,当此字段上存在索引时,速度影响最小。

通常,这会增加一些其他字段,如修订号,记录上次更新时间以及更新记录的时间。修订号对于获得以前的版本以及进行乐观锁定非常有用。 '谁更新了最后一次以及什么时候'的问题通常在系统运行后才会发生,而不是在需求收集期间出现,并且是包含'主'数据的任何表格的有用字段。

+0

“已删除”列上的索引如何提供帮助?如果查询引擎使用此索引,是不是必须对所有其他列执行表扫描?将搜索字段编入索引并放弃搜索结果中删除的行不是更好吗? – 2010-08-23 21:36:12

+1

不,它会在已删除的列上使用索引扫描,然后在其他列中进行搜索。您可以有多个索引,并且查询优化器将使用数据库收集的统计信息来估计每个索引的相对性能,并将它们按顺序排列,以便首先使用期望得到最少结果的索引。尝试对一些查询进行EXPLAIN PLAN,看看它是如何工作的。优化器通常非常聪明,以至于只有10%的记录被实际删除时,他们才知道使用索引是不值得的。 – 2010-08-23 21:48:33

+0

所以让我重申一遍。我会有两张桌子,其中一名工作人员不变,另一名工作人员的细节可变。该员工详细信息表中将有一个索引字段(已删除),我将在为该工作人员插入新记录时设置该字段。当我想查询最新版本时,我只限于删除= 0的地方。我错过了什么吗? – 2010-08-24 20:32:45

2

我会使用单独的表格,因为那样您就可以拥有一个唯一的标识符,指向所有其他子记录,这也是表格的PK,我认为它不太可能会导致数据完整性问题。例如,你有玛丽琼斯在地址表和电子邮件表和绩效评估表等记录。如果你添加一个变更记录到主表,你将如何重新链接所有现有的信息?使用单独的历史记录表,这不是问题。

在一个表中删除字段后,您必须具有非自动生成的人员ID和自动生成的记录编号。

您还有可能忘记使用几乎每个查询所需的where deleted = 0 where子句。 (如果确实使用已删除的标志字段,请为自己做个忙,并使用where deleted = 0设置视图,并要求开发人员在查询中使用视图而不是原始表。)

使用已删除的标志字段还需要一个触发器来确保只有一个记录被标记为活动。

+0

+1你说过我的感受。 :-) – 2010-08-23 21:47:25

+0

我看起来至少有两张表,一张包含工作人员的不可变ID和一张带有可变工作人员信息的表。这样我永远不必删除一条记录,因为每条记录都将不可变的id设置为外键。我想知道是否应该将两个表以外的记录拆分成表格,这些表格中的字段按抽象类型分组或者可能更新。 – 2010-08-24 20:43:21

0

@Peter Tillemans的建议是完成您要求的常用方法。但我不喜欢它。

数据库的结构应反映正在建模的现实世界事实。

我会为obsolete_employee创建一个单独的表格,只存储将来需要搜索的历史信息。通过这种方式,您可以保持您的真实员工数据表清洁,并只保留必要的旧数据。这种方法还将简化与搜索历史数据无关的应用程序的报告和其他功能。

只要想一想,当你输入select * from employee而没有其他任何东西时,你会得到那种温暖的感觉,正确的善良会回流!

相关问题