【发布时间】:2020-06-17 05:34:39
【问题描述】:
我正在寻找有关如何以任何 SQL 风格实现版本化 key:val 对的建议。
(我们现在假设 SQlite 和 Postgres。)
我有一张表,初步是这样的:
locale key version -> value
语言环境和键构成原始未版本化的候选/主键。添加版本以允许存储多个版本。
棘手的部分是源数据中的“更新”(我无法控制)可能会在不更改值的情况下增加版本号。在这些情况下,我想禁止增加版本号。
但是,我不能规定该值是唯一的,因为我希望允许值切换,例如
en_US key1 1 -> "hello world"
en_US key1 42 -> "henlo world"
en_US key1 57 -> "hello world"
是一个有效的序列:错误被意外引入然后回滚。保留大约 42 版的数据很重要。
但是,我们可能经常发现源数据的版本 58 不会更新键的值 - 所以这是“最后修改”版本语义。
例如以下是无效序列:
en_US key1 57 -> "hello world"
en_US key1 58 -> "hello world"
为保留“上次修改”语义,不应添加版本 58 条目。
我可以进行“插入 if”样式检查并查询语言环境/键的最新版本是否与收到的版本匹配,但我担心这会使我面临竞争条件。
在 sqlite/postgres 中有没有更基本的方法来模拟这个约束?我不确定这种约束在形式上被称为什么。 (这不是很“独特”。)
【问题讨论】:
-
“我担心比赛条件” - 怎么回事?
-
我很好奇这一切的应用。我的第一个想法是一个 UPSERT,即
INSERT如果新行与最后一行具有相同的内容,它将失败。在 Postgres 中,您添加一个ON CONFLICT UPDATE子句来捕获失败的INSERT并改为执行UPDATE。如何在没有唯一约束的情况下使INSERT失败,我不确定。也许是CHECK约束。 -
好问题 - 源数据是版本化的,但我需要编译历史以便可以调用/使用过去的版本。版本之间的大集合中没有多少键更改,因此希望保持“已更改”版本语义。可能有一种更基本的方法可以做到这一点,但版本本身对客户有用,不能在内部任意。
标签: sql postgresql sqlite