0

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

需要 2 个范围查询

  1. 选择 last_modified_time >=x 和 last_modified_time 的所有文档
  2. 选择 size >= x 和 size <= y 的所有文档

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

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

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

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

创建表 t_document (document_id bigint,
last_mod_time bigint, size 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 表上为用户创建二级索引?

谢谢你的帮助。

4

1 回答 1

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));

“dummy”列始终设置为相同的值,并被用作占位符分区键,所有数据都存储在单个分区中。

这种数据模型的缺点是,事实上,所有数据都存储在一个分区中。每个分区最多有 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 组件。

于 2015-02-03T04:13:15.993 回答