Cassandra数据模型

时间:2014-04-08 20:28:53

标签: cassandra-2.0

我是一名cassandra新手试图了解如何在cassandra中建模我们当前的sql数据。数据库存储的文档元数据包括其他数据中的document_id,last_modified_time,size_in_bytes,文档数量可以任意大,因此我们正在寻找可扩展的存储和查询解决方案。

需要2个范围查询

  1. 选择last_modified_time> = x和last_modified_time
  2. 的所有文档
  3. 选择尺寸> = x且尺寸< = y
  4. 的所有文档

    还有一组查询,其中文档需要按特定元数据进行分组,例如

    1. 选择(x,y,z)
    2. 中用户的所有文档

      基于这些查询设计数据模型的最佳做法是什么?

      我最初想的是有一个表(在Cassandra 2.0,CQL 3.0中),其中last_mod_time作为辅助索引,如下所示

      创建表t_document(     document_id bigint,
          last_mod_time bigint,     尺寸bigint,     用户文字,     ....     主键(document_id,last_mod_time) }

      这应该处理查询1.

      我是否需要为查询2创建另一个主键为(document_id,size)的表?或者我可以将大小添加为同一表的主键中的第三项,例如(document_id,last_mod_time,size)。但在这种情况下,第二个查询是否可以在where子句中使用last_mod_time而不使用?

      对于查询3(一个或多个用户的所有文档),最佳做法是创建主键为(user,doc_id)的t_user_doc表吗?或者更好的方法是在同一个t_document表上为用户创建二级索引?

      感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

当谈到不平等时,你在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的精度来缓解基数问题,比如只存储day组件。