我正在努力为我试图满足的用例进行数据建模。我看了this和this,甚至这个,但它们并不是我所需要的。
我有一个基本的表格:
CREATE TABLE documents (
itemid_version text,
xml_payload text,
insert_time timestamp,
PRIMARY KEY (itemid_version)
);
itemid
实际上是一个UUID(对所有文档都是唯一的),version
是一个int(版本0是“第一个”版本)。xml_payload
是完整的XML文档,可能会非常大。是的,我基本上是在创建一个版本化的文档存储。
正如你所看到的,我将这两个连接起来创建一个主键,我将在后面解释需求和/或用例时解释为什么这样做:
- 用例1:用户需要获取单个(1)文档,用户知道项目ID和版本(不一定是最新版本)
- 用例2:用户需要获取单个(1)文档,用户知道项目ID,但不知道最新版本
- 用例3:用户需要单个(1)文档的版本历史
- 用例4:用户需要获取文档列表(1个或多个),用户知道项目ID和版本(不一定是最新版本)
我将编写执行用例的客户端代码,请原谅语法,因为我试图成为语言无关的。
第一个很简单
$itemid_version = concat($itemid, $version)
$doc = csql("select * from documents where itemid_version = {0};"
-f $itemid_version)
现在,为了满足第二和第三个用例,我添加了下表:
CREATE TABLE document_versions (
itemid uuid,
version int,
PRIMARY KEY (itemid, version)
) WITH clustering order by (version DESC);
将在创建新文档和现有文档的新版本时添加新记录。
现在我们有这个(用例#2):
$latest_itemid, $latest_version = csql("select itemid,
version from document_versions where item_id = {0}
order by version DESC limit 1;" -f $itemid)
$itemid_version = concat($latest_itemid, $latest_version)
$doc = csql("select * from documents where itemid_version = {0};"
-f $itemid_version)
这个(用例#3):
$versions = csql("select version from document_versions where item_id = {0}"
-f $itemid)
对于第三个要求,我添加了另一个表:
CREATE TABLE latest_documents (
itemid uuid,
version int,
PRIMARY KEY (itemid, version)
)
为新文档插入记录,为现有文档更新记录。
现在我们有了这个
$latest_itemids, $latest_versions = csql("select itemid, version
from latest_documents where item_id in ({0})" -f $itemid_list.toCSV())
foreach ($one_itemid in $latest_itemids, $one_version in $latest_versions)
$itemid_version = concat($latest_itemid, $latest_version)
$latest_docs.append(
cql("select * from documents where itemid_version = {0};"
-f $itemid_version))
现在,我希望清楚为什么我将itemid
和version
连接起来为documents
创建索引,而不是创建复合键:在SELECT
的WHERE
子句中不能有OR
。
您可以假设只有一个进程执行插入/更新,因此不需要担心一致性或隔离问题。
我的思路对吗?有很多事情让我不舒服......但主要是因为我还不了解Cassandra:
- 我觉得
documents
的主键应该是(itemid,version)的组合,但是我不能满足用例#4(从查询返回一个列表)......由于性能问题(网络开销),我不可能对每个文档使用单独的SELECT语句......或者我可以(应该)吗? - 如果事先不知道文件的版本,则需要两次往返才能获得文件。这可能是我必须接受的妥协,除非有更好的办法。
2条答案
按热度按时间f0brbegy1#
让我们看看我们是否可以从您的查询开始以自顶向下的方式提出一个模型:
huus2vyu2#
这实际上与您的解决方案非常相似,除了您可以存储所有版本并能够从一个表(
document_versions
)中获取“最新”版本。在大多数情况下,我认为你可以在一个
SELECT
中得到你想要的,除了用例2,它需要获取文档的最新版本,其中SELECT
首先需要在document_versions
上。itemid
+version
馈送到第二个查询中)