在 PostgreSQL 中提供版本化行的好方法是什么?如何查询它们?
我想在表中存储不同文本和其他数据的不同版本。对于文本,我的表如下所示:
id BigSerial, PRIMARY KEY
version Integer
text Text
origin BigInt
现在我想在该表中存储不同版本的文本,如下所示:
1,0,"My Text, first Version",null
2,1,"My Text, second Version",1
3,0,"My 2nd Text v1",null
4,1,"My 2nd Text v2",3
我还不知道如何查询每组文本具有最高版本号的行。
I want to store different versions of different texts and other data in a table. For the texts, my table looks like this:
id BigSerial, PRIMARY KEY
version Integer
text Text
origin BigInt
Now I want to store different versions of texts in this table like this:
1,0,"My Text, first Version",null
2,1,"My Text, second Version",1
3,0,"My 2nd Text v1",null
4,1,"My 2nd Text v2",3
I don't know yet how to query for the row with the highest version number for each set of texts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Bigserial ID 号没有任何用处。
每个 id 的版本数。
每个 id 的当前版本。
尽管我使用公用表表达式编写了该内容,但您可能希望创建当前版本的视图。我认为访问此数据的大多数应用程序都需要当前版本。
The Bigserial id number serves no useful purpose.
Number of versions for every id.
Current version for every id.
Although I wrote that with a common table expression, you probably want to create a view of current versions. I'd think most applications that access this data will need the current version.
时态表扩展可能会有所帮助,如果您不想推出自己的......
https://github.com/arkhipov/temporal_tables
Temporal tables extension might help, if you don't want to roll your own that is...
https://github.com/arkhipov/temporal_tables
由于并非所有文本集都可以以相同的速率获得新版本,因此没有真正的方法可以对版本号进行断言,而无需同时涉及 id 和源。
例如,要知道“5”是特定文本集的最新版本,您必须确定不存在版本“6”。执行此操作的方法是查看版本“6”的行是否具有版本“5”的行的起源。但这只是简化为找到没有其他行声称其为原点的行;你不需要版本号。
因此,您可以将“我是否具有最高版本号”的问题改写为“是否没有其他行以我的 id 作为其起源”。如果没有其他行,那么这是您的最新行,您可以返回结果。您可以使用类似以下查询的方式来完成此操作:
生成的连接表中,descendant.id 为 null 的唯一行是最新的行。请注意,父代和子代都是来自同一个表的别名。这就是所谓的“自连接”,当您将分层数据(如版本控制机制)存储在单个表中时,可以很方便地执行此操作。
但值得注意的是,这只会为您找到最新版本。如果您想知道这是哪个版本,那么您肯定会从版本列中受益。否则,您最终将不得不执行递归查询,因为您事先不知道版本列表的深度。没有人喜欢写这些。
希望这有帮助。
Since not all of the set of texts may get new versions at the same rate, there's no real way of making an assertion on version number that won't have to involve both the id and the origin.
For instance, to know that "5" is the latest version of a particular text set, you'll have to establish that there is no version "6". The way to do that is to see if there is a row with a version "6" that has an origin to the row with version "5". But this just reduces to finding a row that has no other row claiming it as an origin point; you don't need the version number.
So, you can rephrase the question of "do I have the highest version number" as "is there no other row that has my id as its origin". If there is no other row, then this is your newest row, and you can return your result. You can accomplish this with something like the following query:
The only rows in the resulting joined table where descendant.id will be null are the ones that are the newest. Notice that both parent and descendants are aliased from the same table. This is what is known as a "self-join", and is handy to do when you have hierarchical data (like your versioning mechanism) stored within a single table.
It is worth noting, though, that this only finds the newest version for you. If you want to know which version this is, then you will definitely benefit from having your version column. Otherwise, you will end up having to do a recursive query, since you won't know the depth of your version list up front. No one likes writing those.
Hope this helps.