MySql中的结构(对于紧凑性我使用的是简化表示法)
表示法:表名 - > [column1(键或索引),column2,...]
documents->[doc_id(primary key), title, description]
elements->[element_id(primary key), doc_id(index), title, description]
每个文档都可以包含大量元素(1到100k +之间)
我们有两个关键要求:
Cassandra的结构
第一个解决方案
documents->[doc_id(primary key), title, description, elements] (elements could be a SET or a TEXT, each time new elements are added (they are never removed) we would append it to this column)
elements->[element_id(primary key), title, description]
要加载我们需要的文档:
使用给定的文件加载并获取所有元素ID:来自doc_id ='id'的文档的SELECT *
使用给定的ID加载所有元素:SELECT * FROM elements where element_id IN(从查询a加载的ID)
更新元素将通过其主键完成。
第二个解决方案
documents->[doc_id(primary key), title, description]
elements->[element_id(primary key), doc_id(secondary index), title, description]
要加载我们需要的文档:
更新元素将通过其主键完成。
有关我们解决方案的问题:
第一:在元素表中查询100k +主键是否有效?
SELECT * FROM elements WHERE element_id IN (element_id1,.... element_id100K+)?
第二:仅通过二级索引查询是否有效?
有人可以提出任何建议我们如何为我们的用例创建模型?
答案 0 :(得分:0)
使用cassandra,所有关于访问模式(我希望我理解正确,如果没有请注释)
第一
文档不应使用集合,因为set限制为65 535个元素,并且每次进行更改时都必须读取,更新。因为你需要100k +它不是你想要的。你可以使用冷冻集合等,但是再次,每次读取内存中的所有内容都必然会很慢。
第二
二级索引,小基数数据可能没问题但是从我的理解你每个文件有100k,这甚至可能没问题但是再次这不是最好的做法。我会在你的具体案例中尝试一下。
第三 - 磁盘是便宜的方法 - 总是按照你要读的方式写入数据 - cassandra的写入很便宜,所以在写入时准备好视图,
这个满足读取属于doc_id
的所有元素documents->[doc_id(primary key), title_doc (static), description_doc(static), element_id(clustering key), title, description]
元素保持不变:
elements->[element_id(primary key), doc_id, title, description]
进行更新时,您需要在文档和元素中更新它(为了保持一致性,您可以使用批处理操作 - 如果需要)如果有了element_id,您可以在获得它之后快速发出另一个查询的文档ID。 根据您的更新需求,documentId也可以是一组。 (我可能没有把这一部分弄好,因为在更新元素时不确定哪些数据可用,你是否也有doc_id,并且一个元素可以在更多的文档中?)
另外,因为在单个分区中有100k +元素并不是最好的因为检索(所有请求将转到一个节点)我建议使用复合分区键(桶)我认为在你的情况下一个简单的修复int会没事的。因此,每次去检索元素时,您只需选择文档+(1,2,3,4 ...),然后在客户端合并结果 - 这将显着加快。
一个棘手的部分是,你不会进入存储在文档中的elementid的每一个桶......当我考虑它时,最好使用两个基数用于存储桶。在你的情况下16将是理想的...然后当你想要更新特定元素时,只需使用一些已知的简单哈希函数并使用最后4位。
现在,当我想到它时,如果你总是知道元素id + doc id,你可能根本不需要元素表。
希望这有帮助
答案 1 :(得分:0)
根据Marko的建议,我们的解决方案是:
CREATE TABLE documents (
doc_id uuid,
description text,
title text,
PRIMARY KEY (doc_id)
);
CREATE TABLE nodes (
doc_id uuid,
element_id uuid,
title text,
PRIMARY KEY (doc_id, element_id)
);
我们可以使用以下查询检索所有元素:
SELECT * FROM elements WHERE doc_id='id'
并更新元素:
UPDATE elements SET title='Hello' WHERE doc_id='id' AND element_id='id';