【发布时间】:2011-05-18 20:39:45
【问题描述】:
我有一个关于我想针对 PostgreSQL 表执行的特定查询的问题。尽管我欢迎对我使用的表格方案提出批评,但我会更加欣赏对我实际问题的回答!
我正在使用 uuid-ossp postgresql-contrib 模块并具有以下表结构:
Column | Type | Modifiers | Storage | Description
---------------------+-----------------------------+-----------+----------+-------------
revision_id | uuid | not null | plain |
document_id | uuid | not null | plain |
user_id | uuid | not null | plain |
datetime_edited | timestamp without time zone | not null | plain |
contents | text | not null | extended |
Indexes:
"document_pkey" PRIMARY KEY, btree (revision_id)
这个想法是:
- 一个文档可能有一个或多个修订版。不删除修订。为了更新文档,插入了一个新行,其中包含新的
revision_id但相同的document_id。 -
revision_id在所有文档的所有修订版中都是唯一的。 -
contents是代表文档的数据块,user_id标识谁更新了文档。
我正在努力想出一个查询,该查询返回特定用户创建的所有文档的所有最新修订。我知道我可以做到,例如:
select * from document where user_id = '6a2aabc417b34ef99b14b10eaa8e9313';
但这会返回所有文档。如何向下钻取并要求按document_id 和LIMIT 1 进行分组,并根据datetime_edited 返回最新的revision_id?
编辑:由于一个文档可以有一个或多个修订版,我在说“所有文档由用户创建”时一直含糊其辞。 创建我的意思是用户对文档贡献了一个或多个修订,即用户编辑文档的地方至少有一个修订。
这样的事情甚至可以在一个查询中实现,还是我需要多次访问数据库才能实现这一点?
编辑:revision_id 不是单调递增的。这是一个随机的 UUID。因此,max(revision_id) != max(datetime_edited)。
【问题讨论】:
-
更好的方法可能是将旧版本放在一个单独的表中,并使用 (
doc_id,revision) 复合 PK 并在document表中只保留当前版本。那么你的查询就相当直接了,代价是更复杂的更新。 -
这绝对是一个选择。如果很少查询文档的旧修订版本并且每个文档有很多修订版本,那么从长远来看,它不仅会使查询更简单而且更快。缺点是数据没有完全标准化,但对我来说,简单总是赢。
标签: sql database postgresql set