小编典典

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

sql

这是一个虚构的场景,其中包含一些填充的数据。出于税收目的,我的虚构公司必须保留历史数据记录。出于这个原因,我在表中包括了一个version列。

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: 在“当前”列中添加“当前=真实AND …”

在我看来,人们肯定已经做过,遇到了同样的问题,并且有见识可以分享,所以我来收集一下!:)我已经尝试在此处查找问题的示例,但是它们似乎专用于特定情况。

谢谢!

编辑1:

首先,我感谢所有答案,并且你们都说过同样的话-DATE比更好VERSION NUMBER。我要使用的原因之一是VERSION NUMBER简化服务器中的更新过程,以防止出现以下情况

人员A在其会话中加载员工记录3,并且具有版本4。人员B在其会话中加载员工记录3,并且具有版本4。人员A进行更改和提交。之所以可行,是因为数据库中的最新版本是4。现在是5。人员B进行更改并提交。失败是因为最新版本是5,而他的版本是4。

EFFECTIVE DATE模式将如何解决此问题?

编辑2:

我想我可以通过以下操作来做到这一点:人员A在他的会话中加载了员工记录3,其生效日期为2010年1月1日,下午1:00,无任何延期。B员工在其会话中加载员工记录3,其生效日期为2010年1月1日,下午1:00,无任何费用。人员A进行更改并提交。旧副本进入存档表(基本上是概念2),有效期为9/22/2010
1:00 pm。主表的更新版本的生效日期为9/22/2010 1:00 pm。人B进行更改并提交。提交失败,因为有效日期(在数据库和会话中)不匹配。


阅读 160

收藏
2021-04-15

共1个答案

小编典典

我认为您已经走错了路。

通常,对于版本控制或存储历史数据,您需要执行两项(或两项)操作之一。

  1. 您有一个单独的表,该表模仿原始表+一个更改日期的日期/时间列。每当记录更新时,就在更新之前将现有内容插入到历史表中。

  2. 您有一个单独的仓库数据库。在这种情况下,您可以像上面的#1中那样对它进行版本控制,也可以仅每隔一段时间(每小时,每天,每周)对其快照一次。

将您的版本号与普通表放在同一张表中会遇到一些问题。首先,表的大小将变得疯狂。这将对正常的生产查询造成持续的压力。

其次,它将从根本上增加联接等的查询复杂度,以确保使用每个记录的最新版本。

2021-04-15