我是一名cassandra新手试图了解如何在cassandra中建模我们当前的sql数据。数据库存储的文档元数据包括其他数据中的document_id,last_modified_time,size_in_bytes,文档数量可以任意大,因此我们正在寻找可扩展的存储和查询解决方案。
需要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表上为用户创建二级索引?
感谢您的帮助。
答案 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组件。