用于范围查询的 cassandra 的表定义语句?

Posted

技术标签:

【中文标题】用于范围查询的 cassandra 的表定义语句?【英文标题】:table definition statement for cassandra for range queries? 【发布时间】:2015-10-21 21:36:22 【问题描述】:

这是表格数据

video_id uuid
user_id timeuuid
added_year int
added_date timestamp
title text
description text

我想根据以下查询构造表

select * from video_by_year where added_year<2013;

创建表 videos_by_year (

video_id uuid
user_id timeuuid
added_year int
added_date timestamp
title text
description text
PRIMARY KEY ((added_year) added_year)

) ;

注意:我已将added_year 用作主键和集群键,我认为这是不正确的。

【问题讨论】:

【参考方案1】:

因此,cassandra 中数据建模的一个问题是第一个组件 - 分区键 - 必须使用“=”。如果您意识到 cassandra 在做什么,那么其原因就很清楚了——它使用该值,对其进行哈希处理(md5 或 murmur3),并使用它来确定集群中的哪些服务器拥有该分区。

因此,您不能使用不等式 - 它需要扫描集群中的每一行。

如果您需要在 2013 年之前添加视频,请考虑使用一个系统,其中您使用日期的某些部分作为分区键,然后从每个日期“桶”中选择,您可以异步并行执行此操作。例如:

create table videos_by_year (
 video_id uuid
 user_id timeuuid
 added_date_bucket text
 added_date timestamp
 title text
 description text
 PRIMARY KEY ((added_date_bucket), added_date, video_id)
) ;

我为 added_date_bucket 使用了文本,因此您可以使用“YYYY”或“YYYY-MM”或类似名称。请注意,根据您将视频添加到系统的速度,您甚至可能需要 'YYYY-MM-DD' 或 'YYYY-MM-DD-HH:ii:ss',因为你会达到几个实际限制每桶百万视频。

您可以变得聪明,将 video_id 设置为 timeuuid,然后将 added_date 和 video_id 放在一个列中。

【讨论】:

你说的每桶几百万个视频的实际限制是多少? 每个分区有 20 亿个单元的硬性上限。使用您的方案,每行有 4 个单元格,这为您提供了 500M 行的硬上限。但实际上,非常宽的行不太理想 - 它们性能不佳,压缩速度慢,并且您最终会接触到比非常小的分区更多的稳定 pee 读取,这意味着它更慢。 如果 video_is 是唯一的,如何导致宽行? 好问题,与 cassandra 中“行”一词的重载有关。当我说“非常宽的行”时,我的意思是“非常宽的分区”。在 Cassandra 中,磁盘行(“分区”)基于主键的第一个元素(在我的示例中为 added_date_bucket)。每个 CQL 行(视频/用户/时间戳/标题/描述)按 added_date_bucket 的顺序物理存储在磁盘上。这就是 2B 细胞限制的用武之地。

以上是关于用于范围查询的 cassandra 的表定义语句?的主要内容,如果未能解决你的问题,请参考以下文章

SparkSql 查询以从 cassandra 获取定义值的上一行和下一行

使用 Spring-data-cassandra 查询具有复合主键的表

Cassandra中的双范围查询

带范围边界查询的Cassandra BoundStatement

使用Spring-data-cassandra查询具有复合主键的表

如何使用 Cassandra 中的 QueryBuilder 定义具有 2 个条件的 Where 查询?