Cassandra 数据模型
Posted
技术标签:
【中文标题】Cassandra 数据模型【英文标题】:Cassandra data model 【发布时间】:2014-04-08 20:28:53 【问题描述】:我是一名 cassandra 新手,试图了解如何在 cassandra 中对我们当前的 sql 数据进行建模。数据库存储文档元数据,其中包括 document_id、last_modified_time、size_in_bytes 以及许多其他数据,并且文档的数量可以任意大,因此我们正在寻找一种可扩展的存储和查询解决方案。
需要2个范围查询
-
选择 last_modified_time >=x 和 last_modified_time 的所有文档
选择所有尺寸 >= x 和尺寸
还有一组查询,其中文档需要按特定元数据分组,例如
-
选择用户在 (x,y,z) 中的所有文档
根据这些查询设计数据模型的最佳做法是什么?
我最初的想法是有一个表(在 Cassandra 2.0,CQL 3.0 中),其中 last_mod_time 作为二级索引,如下所示
创建表 t_document ( 文档 ID 大整数, last_mod_time bigint , 大小大整数, 用户文本, …… 主键(document_id,last_mod_time)
这应该处理查询 1。
我是否需要为查询 2 创建另一个主键为 (document_id, size) 的表?或者我可以将大小添加为同一个表的主键中的第三项,例如(document_id、last_mod_time、大小)。但是在这种情况下,第二个查询是否会在 where 子句中不使用 last_mod_time 的情况下工作?
对于一个或多个用户的所有文档的查询 3,创建一个主键为 (user, doc_id) 的 t_user_doc 表是最佳实践吗?或者更好的方法是在同一个 t_document 表上为用户创建二级索引?
感谢您的帮助。
【问题讨论】:
【参考方案1】:谈到不平等时,您在 Cassandra 中没有太多选择。它们必须是前导集群列(或二级索引)。因此数据模型可能如下所示:
CREATE TABLE docs_by_time (
dummy int,
last_modified_time timestamp,
document_id bigint,
size_in_bytes bigint,
PRIMARY KEY ((dummy),last_modified_time,document_id));
“虚拟”列始终设置为相同的值,并被用作占位符分区键,所有数据都存储在单个分区中。
这种数据模型的缺点是,事实上,所有数据都存储在一个分区中。每个分区最多有 20 亿个单元,但更重要的是,单个分区永远不会跨越节点。所以这种方法无法扩展。
您可以在表上创建二级索引:
CREATE TABLE docs (
document_id bigint,
last_modified_time timestamp,
size_in_bytes bigint,
PRIMARY KEY ((dummy),last_modified_time,document_id));
CREATE INDEX docs_last_modified on docs(last_modified);
但是二级索引有很大的缺点 (http://www.slideshare.net/edanuff/indexing-in-cassandra),不建议用于高基数的数据。您可以通过降低 last_modified_time 的精度来缓解基数问题,例如,只存储天组件。
【讨论】:
以上是关于Cassandra 数据模型的主要内容,如果未能解决你的问题,请参考以下文章