在 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 中保留主键的同时实现修订号的主要内容,如果未能解决你的问题,请参考以下文章

SQL查询删除没有主键的重复记录,保留最新的[重复]

SQL中主键和外键的定义是啥???

mycat全局系列号的学习和配置

SQL中主键的使用

sql主键和外键的区别

在主键的情况下哪个更好 bigint 或 nvarchar