在 sql 中保留主键的同时实现修订号
Posted
技术标签:
【中文标题】在 sql 中保留主键的同时实现修订号【英文标题】:Implement revision number while keeping primary key in sql 【发布时间】:2022-01-03 15:34:32 【问题描述】:假设我有一个带有主键和一些数据的 psql 表:
pkey | price
----------------------+-------
0075QlyLvw8bi7q6XJo7 | 20
(1 row)
但是,我想保存它的历史更新,而不会丢失将其他表中的键引用为外键的功能。
我正在考虑做某种修订号+时间戳的方法,其中每个“更新”都是一个新行,例如:
pkey | price | rev_no
----------------------+-------+--------
0075QlyLvw8bi7q6XJo7 | 20 | 0
----------------------+-------+--------
0075QlyLvw8bi7q6XJo7 | 15 | 1
(2 rows)
然后创建一个视图,该视图始终采用表的最高修订号并从该视图中引用键。
但是,对于我认为应该相当普遍的任务而言,这项工作似乎有点过于繁重。有什么我想念的吗?对于这些我不知道的问题,您有更好的解决方案还是有一个众所周知的范例?
【问题讨论】:
您可以将旧值移动到历史表中,以便您的主表只包含最新版本。这可以例如在触发器中完成 这并没有错。您应该只考虑 1)哪些操作需要快速 2)您要保留多少修订版 3)如何摆脱旧数据。确切的解决方案将取决于这些。 数据修订是许多业务应用程序的核心功能,但它并未作为数据库级别的预定义解决方案实现。您必须根据自己的需求来实施它,它可能比您当前考虑的解决方案复杂得多。 【参考方案1】:假设PKey
实际上是定义的主键,如果不创建历史表并将旧数据移至其中,您就无法执行您概述的修订方案。任何修订版的主键必须是唯一的。但是如果你有一个正确规范化的表有几个有效的方法,以下是一个:
-
查看其他属性并确定候选业务键(可以定义为唯一的业务含义列 - 可能是项目名称。
如果不存在,请添加 2 列:有效时间戳和被取代的时间戳。
现在在已识别的列上创建一个部分唯一索引,从 #1 开始,并且被取代的时间戳是一列,意思是 这是当前活动的版本。
创建一个简单的视图为
Select * from table
。由于这是一个简单的视图,它是完全可更新的。使用此视图进行选择、插入和删除,但是
为更新创建一个代替触发器。此触发器将设置当前活动行的被取代时间戳,并插入应用的新行更新和更新的版本号。
通过以上内容,您可以唯一地保留当前的活动版本。此外,您维护每个版本的所有关系的历史记录。 (见demo,包括几个有用的功能)
【讨论】:
以上是关于在 sql 中保留主键的同时实现修订号的主要内容,如果未能解决你的问题,请参考以下文章