Database PK-FK design for future-effective-date entries?

ぐ巨炮叔叔 提交于 2019-12-11 08:02:18

问题


Ultimately I'm going to convert this into a Hibernate/JPA design. But I wanted to start out from purely a database perspective. We have various tables containing data that is future-effective-dated. Take an employee table with the following pseudo-definition:

employee

  • id INT AUTO_INCREMENT
  • ... data fields ...
  • effectiveFrom DATE
  • effectiveTo DATE

employee_reviews

  • id INT AUTO_INCREMENT
  • employee_id INT FK employee.id

Very simplistic. But let's say Employee A has id = 1, effectiveFrom = 1/1/2011, effectiveTo = 1/1/2099. That employee is going to be changing jobs in the future, which would in theory create a new row, id = 2 with effectiveFrom = 7/1/2011, effectiveTo = 1/1/2099, and id = 1's effectiveTo updated to 6/30/2011. But now, my program would have to go through any table that has a FK relationship to employee every night, and update those FK to reference the newly-effective employee entry.

I have seen various postings in both pure SQL and Hibernate forums that I should have a separate employee_versions table, which is where I would have all effective-dated data stored, resulting in the updated pseudo-definition below:

employee

  • id INT AUTO_INCREMENT

employee_versions

  • id INT AUTO_INCREMENT
  • employee_id INT FK employee.id
  • ... data fields ...
  • effectiveFrom DATE
  • effectiveTo DATE

employee_reviews

  • id INT AUTO_INCREMENT
  • employee_id INT FK employee.id

Then to get any actual data, one would have to actually select from employee_versions with the proper employee_id and date range. This feels rather unnatural to have this secondary "versions" table for each versioned entity.

Anyone have any opinions, suggestions from your own prior work, etc? Like I said, I'm taking this purely from a general SQL design standpoint first before layering in Hibernate on top. Thanks!


回答1:


That employee is going to be changing jobs in the future, which would in theory create a new (employee) row

Why? What is the point of this? Your employee entity no longer represents an employee, it represents now some abstact concept of "a person in a position".

I believe it would make more sense to separate out the entity that is changing when the employee "changes jobs" - the position - into a separate table, so you do not end up with some messy concept where one physical person is actually multiple employee rows.

I don't understand why you think this seems "unnatural" to have to select from the extra table - you would be separating out something that has multiplicity (a person's position) from something that is singular (an employee).




回答2:


You need to decide whether you are designing a database to support operations or a data warehouse to support reporting. If it is the second, your design in the beginning is very similar to Kimbal's Type 2 slowly changing dimension. Traditionally, you would want your operational database to represent the most current version of your employee and to provide some business key for it (employee #, SSN, etc.). The data then can be loaded into the data warehouse, where each individual record in the EMPLOYEE dimension would have a surrogate key and effective/end dates. The facts, for example reviews, will be related to the the records in the EMPLOYEE dimension, based on the business key and date/time. For example, you will be able to differentiate reviews of employee A when he was in the Junior Technician position from his reviews when he transitioned to the Senior Engineer position.




回答3:


For this sort of thing, we usually have a single boolean field called Active, which allows easier querying on the latest record that applies.




回答4:


To expand on matt b's answer, your discussion of the problem domain makes it pretty clear that what your design is calling out for is a "position" table. An employee's reviews continue to be relevant to that employee even after they move into a new position. Also, in every corporation I've experienced, the concept of an employee's tenure is related to their entire history at the company, not just the current position.

It's generally good practice to look at any complex updates needed as a sign that the design needs to change.




回答5:


There is the entity that corresponds to the unique human being:

     EMPLOYEE
     eeid PK
     firstname
     surname
     dateofbirth
     dateofhire
     dateoftermination
     etc

and there is the entity that corresponds to the position(s) held by the employee:

     EMPLOYEEPOSITION
     id pk
     eeid FK references EMPLOYEE(eeid)
     title
     reportsto FK references EMPLOYEE(eeid)
     startdate not null usually
     enddate allows null

The question of how to enforce whether an EMPLOYEE's positions can overlap is not typically addressed by creating multiple EMPLOYEE records. Inserts/updates to EMPLOYEEPOSITION typically look at the startdate/enddate columns for each of an EE's positions and, depending on what rule is in effect (e.g. overlaps allowed/disallowed) either commit or rollback the operation.

All of an EE's positions can be found using eeid.

You do not usually put a termination date in the EE record unless and until it's necessary. If the EE is a contract worker, I'd instantiate the contract term as an EMPLOYEEPOSITION.

You can analogize from here for any entity that exists in a many-to-one relationship back to EMPLOYEE.




回答6:


Lookup temporal databases. Your data is temporal, in spite of the fact that the dates may currently be in the future. Presumably the future oriented data you insert now will still have the same form and meaning when the future change takes effect.



来源:https://stackoverflow.com/questions/6431002/database-pk-fk-design-for-future-effective-date-entries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!