最终我要将其转换为Hibernate / JPA设计。但我想从纯粹的数据库角度出发。我们有各种表格,其中包含未来有效日期的数据。使用以下伪定义获取员工表:
雇员
employee_reviews
非常简单。但是,假设员工A的id = 1,effectiveFrom = 1/1/2011,effectiveTo = 1/1/2099。该员工将来会改变工作,这理论上会创建一个新行,id = 2,有效的因子= 7/1/2011,有效期为1/1/2099,而id = 1的有效性已更新为6 /二千零十一分之三十零。但是现在,我的程序必须通过任何与员工每晚都有FK关系的表,并更新那些FK以引用新生效的员工条目。
我在纯SQL和Hibernate论坛上看到了各种帖子,我应该有一个单独的employee_versions表,这是我将所有有效日期数据存储的地方,导致下面更新的伪定义:
雇员
employee_versions
employee_reviews
然后,要获得任何实际数据,必须实际从employee_versions中选择具有适当employee_id和日期范围的数据。对于每个版本化实体都有这个辅助“版本”表,这感觉相当不自然。
任何人都有任何意见,您之前的工作建议等等?就像我说的那样,我首先从一般的SQL设计角度出发,然后在Hibernate中进行分层。谢谢!
答案 0 :(得分:3)
该员工将来会改变工作,理论上会创建一个新的(员工)行
为什么呢?这有什么意义?您的employee
实体不再代表员工,它现在代表了“一个人在一个位置”的一些概念。
我认为将员工“改变工作” - 职位时正在改变的实体分离到一个单独的表格中会更有意义,所以你最终不会得到一些混乱的概念,其中一个实际的人实际上是多个employee
行。
我不明白为什么你认为这似乎是“不自然的”必须从额外的表中选择 - 你会将具有多重性(一个人的位置)的东西从单一的东西(雇员)中分离出来。 / p>
答案 1 :(得分:1)
您需要决定是设计数据库以支持操作还是数据仓库以支持报告。如果它是第二个,那么你在开始时的设计与Kimbal的Type 2缓慢变化的尺寸非常相似。传统上,您希望您的运营数据库代表您员工的最新版本,并为其提供一些业务密钥(员工#,SSN等)。然后可以将数据加载到数据仓库中,其中EMPLOYEE维度中的每个单独记录都具有代理键和有效/结束日期。事实(例如评论)将根据业务关键字和日期/时间与EMPLOYEE维度中的记录相关联。例如,当他转到高级工程师职位时,您将能够区分员工A在初级技师职位时对他的评论的评论。
答案 2 :(得分:0)
对于这类事情,我们通常只有一个名为Active的布尔字段,它允许更容易查询适用的最新记录。
答案 3 :(得分:0)
要展开matt b's answer,您对问题域的讨论会清楚地表明您的设计所要求的是“位置”表。即使员工进入新职位,员工的评论仍然与该员工相关。此外,在我所经历过的每一家公司中,员工任期的概念都与他们在公司的整个历史有关,而不仅仅与当前的职位有关。
通常,优秀的做法是将所需的任何复杂更新视为设计需要更改的标志。
答案 4 :(得分:0)
有一个与独特的人类相对应的实体:
EMPLOYEE
eeid PK
firstname
surname
dateofbirth
dateofhire
dateoftermination
etc
并且存在与员工持有的职位相对应的实体:
EMPLOYEEPOSITION
id pk
eeid FK references EMPLOYEE(eeid)
title
reportsto FK references EMPLOYEE(eeid)
startdate not null usually
enddate allows null
如何强制执行员工职位是否可以重叠的问题通常不会通过创建多个EMPLOYEE记录来解决。对EMPLOYEEPOSITION的插入/更新通常会查看每个EE位置的startdate / enddate列,并根据有效的规则(例如允许/禁止重叠)提交或回滚操作。
所有EE的位置都可以使用eeid找到。
除非必要,否则您通常不会在EE记录中设置终止日期。如果EE是合同工,我会将合同条款实例化为员工。
您可以从这里将任何存在于多对一关系中的实体类比回到EMPLOYEE。
答案 5 :(得分:0)
查找temporal databases。您的数据是暂时的,尽管日期可能是将来的日期。据推测,您现在插入的面向未来的数据在未来的更改生效时仍具有相同的形式和含义。