SQL 表中的版本控制 - 如何处理?

2024-01-03

这是一个带有一些填充数据的虚构场景。出于税务目的,我的虚构公司必须保留历史数据记录。因此,我在表中添加了版本列。

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:

首先,我感谢所有的答案,你们都说了同样的话 -DATEVERSION 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 进行更改并做出承诺。提交失败,因为有效日期(在数据库和会话中)不匹配。


这里所拥有的称为缓慢变化的维度(SCD)。有一些经过验证的方法可以处理它:

http://en.wikipedia.org/wiki/Slowly_changing_dimension http://en.wikipedia.org/wiki/Slowly_changing_dimension

我想我应该补充一点,因为似乎没有人叫它的名字。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL 表中的版本控制 - 如何处理? 的相关文章

随机推荐