这是一个带有一些填充数据的虚构场景。出于税务目的,我的虚构公司必须保留历史数据记录。因此,我在表中添加了版本列。
TABLE EMPLOYEE: (with personal commentary)
|ID | VERSION | NAME | Position | PAY |
+---+---------+------------+----------+-----+
| 1 | 1 | John Doe | Owner | 100 | Started company
| 1 | 2 | John Doe | Owner | 80 | Pay cut to hire a coder
| 2 | 1 | Mark May | Coder | 20 | Hire said coder
| 2 | 2 | Mark May | Coder | 30 | Productive coder gets raise
| 3 | 1 | Jane Field | Admn Asst| 15 | Need office staff
| 2 | 3 | Mark May | Coder | 35 | Productive coder gets raise
| 1 | 3 | John Doe | Owner | 120 | Sales = profit for owner!
| 3 | 2 | Jane Field | Admn Asst| 20 | Raise for office staff
| 4 | 1 | Cody Munn | Coder | 20 | Hire another coder
| 4 | 2 | Cody Munn | Coder | 25 | Give that coder raise
| 3 | 3 | Jane Munn | Admn Asst| 20 | Jane marries Cody <3
| 2 | 4 | Mark May | Dev Lead | 40 | Promote mark to Dev Lead
| 4 | 3 | Cody Munn | Coder | 30 | Give Cody a raise
| 2 | 5 | Mark May | Retired | 0 | Mark retires
| 5 | 1 | Joey Trib | Dev Lead | 40 | Bring outside help for Dev Lead
| 6 | 1 | Hire Meplz | Coder | 10 | Hire a cheap coder
| 3 | 4 | Jane Munn | Retired | 0 | Jane quits
| 7 | 1 | Work Fofre | Admn Asst| 10 | Hire Janes replacement
| 8 | 1 | Fran Hesky | Coder | 10 | Hire another coder
| 9 | 1 | Deby Olav | Coder | 25 | Hire another coder
| 4 | 4 | Cody Munn | VP Ops | 80 | Promote Cody
| 9 | 2 | Deby Olav | VP Ops | 80 | Cody fails at VP Ops, promote Deby
| 4 | 5 | Cody Munn | Retired | 0 | Cody retires in shame
| 5 | 2 | Joey Trib | Dev Lead | 50 | Give Joey a raise
+---+---------+------------+----------+-----+
现在,如果我想做类似“获取当前编码员列表”之类的事情,我不能这样做SELECT * FROM EMPLOYEE WHERE Position = 'Coder'
因为这会返回大量历史数据......这很糟糕。
我正在寻找处理这种情况的好主意。我看到了一些让我眼前一亮的选择,但我确信有人会说“哇,这是一个菜鸟错误,发光......试试这个尺寸:”这就是这个地方的全部意义,对吧? :-)
想法 1:像这样保留当前版本的版本表
TABLE EMPLOYEE_VERSION:
|ID |VERSION|
+---+-------+
| 1 | 3 |
| 2 | 5 |
| 3 | 4 |
| 4 | 6 |
| 5 | 2 |
| 6 | 1 |
| 7 | 1 |
| 8 | 1 |
| 9 | 2 |
+---+-------+
尽管我不确定如何通过单个查询来做到这一点,但我确信它可以完成,并且我打赌我可以通过相当小的努力来解决它。
当然,每次插入 EMPLOYEE 表以增加给定 ID 的版本(或在创建新 ID 时插入版本表)时,我都必须更新此表。
这样做的开销似乎是不可取的。
想法 2:保留一个存档表和一个主表。在更新主表之前,将我要覆盖的行插入到存档表中,然后像平常一样使用主表,就好像我不关心版本控制一样。
想法 3:查找一个查询,该查询添加了以下内容SELECT * FROM EMPLOYEE WHERE Position = 'Coder' and version=MaxVersionForId(EMPLOYEE.ID)
...不完全确定我会如何做到这一点。这对我来说似乎是最好的主意,但目前我真的不确定。
想法 4:为“当前”创建一列并添加“WHERE current = true AND ...”
我突然想到,肯定有人以前做过这个,遇到过同样的问题,并且有见解可以分享,所以我来收集一下! :) 我已经尝试在这里找到问题的示例,但它们似乎专门针对特定场景。
Thanks!
EDIT 1:
首先,我感谢所有的答案,你们都说了同样的话 -DATE
比VERSION NUMBER
。我一起去的原因之一VERSION NUMBER
是为了简化服务器中的更新过程,以防止出现以下情况
A 在其会话中加载员工记录 3,并且其版本为 4。
B 在他的会话中加载员工记录 3,并且它的版本为 4。
A 进行更改并提交。这是可行的,因为数据库中的最新版本是 4。现在是 5。
B 进行更改并做出承诺。这会失败,因为最新版本是 5,而他的是 4。
将如何EFFECTIVE DATE
模式解决这个问题吗?
EDIT 2:
我想我可以通过做这样的事情来做到这一点:
A 在其会话中加载员工记录 3,其生效日期为 2010 年 1 月 1 日下午 1:00,无过期。
B 在他的会话中加载员工记录 3,其生效日期是 2010 年 1 月 1 日下午 1:00,没有过期。
A 进行更改并提交。旧副本将进入存档表(基本上是想法 2),有效期为 2010 年 9 月 22 日下午 1:00。主表的更新版本的生效日期为 2010 年 9 月 22 日下午 1:00。
B 进行更改并做出承诺。提交失败,因为有效日期(在数据库和会话中)不匹配。