【问题标题】:table definition statement for cassandra for range queries?用于范围查询的 cassandra 的表定义语句?
【发布时间】:2024-01-20 02:12:01
【问题描述】:

这是表格数据

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 用作主键和集群键,我认为这是不正确的。

【问题讨论】:

    标签: cassandra data-modeling cassandra-2.0


    【解决方案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 细胞限制的用武之地。
    最近更新 更多