Cassandra建模,我有十亿种某种数字代码存储,我应该使用宽行(带簇密钥的CQL)吗?

时间:2015-06-24 04:00:28

标签: cassandra modeling

我目前正在进行Cassandra建模,我有数十亿的某种数字代码hnm_code可以存储,如下所示:

create table hnm (
    create_batch_id int, // A creation batch can generate up to 1 million code.
    hnm_code text,       // Cardinality: billions
    product_name text,
    primary key (hnm_code)
);

create_batch_id相比,hnm_code的基数相对较小。但是,我想要的是我应该能够使用单个hnm_code列的值来查询该记录(查询时create_batch_id未知)。 我应该使用宽行(带簇密钥的CQL),像这样吗?:

create table hnm_with_cluster_key (
    create_batch_id int,
    hnm_code text,
    product_name text,
    primary key (create_batch_id, hnm_code)
);

谢谢!如果您能告诉我如何在大量查询中获得良好性能并均匀分布hnm_code,那将是很好的。

2 个答案:

答案 0 :(得分:2)

  

我想要的是我应该能够使用单个hnm_code列的值来查询该记录

在Cassandra中,您应该设计模型以匹配您的查询模式。所以这个案子说明了一切。在hnm_code上使用分区键的第一个解决方案将实现此目的。

  

查询时未知的create_batch_id

如果您要将第二个解决方案与PRIMARY KEY (create_batch_id, hnm_code)一起使用, 需要在查询时知道(并提供)create_batch_id

  

如果您可以告诉我如何在大量此查询中获得良好性能并均匀分布hnm_code,那将是一件好事。

Cassandra行按分区键的散列值分配。因此,该密钥的基数越高,您在群集中的分布就越均匀。此外,Cassandra旨在通过分区键进行查找,因此您的查询应该非常快。

  

此外,使用第二个表定义,我的查询如下所示:select * from hnm_with_cluster_key where hnm_code='1234' allow filtering;

使用数十亿的CQL行数,使用ALLOW FILTERING指令表现良好。我强烈建议反对

  

现在我想也许我只需要这两个表,一个用于通过单个条件hnm_code = $hnm_code选择单个hnm_code行,一个用于通过create_batch_id = $batch_id选择创建批量的hnm_codes,但我很反感这个重复,考虑到数十亿行加倍。

这就是你问题的症结所在。 Cassandra根本不支持允许这种查询灵活性的类型。从单个表设计支持多个查询通常是不可行的。如果您需要create_batch_id支持查询,那么您将需要两个表。每个模型都不会支持对另一个模型执行良好的查询。

是的,数据重复/冗余可能违反我们在学校教授的关于规范化的所有内容。但Cassandra并不适合使用完全标准化的模型。我去年为Planet Cassandra撰写了一篇文章,讨论了其中的一些权衡:Escaping Disco-Era Data Modeling

基本上,虽然大规模数据复制不是任何人真正想做的事情,但在设计高性能Cassandra模型时,这可能是必要的权衡。

答案 1 :(得分:0)

Cassandra与另一个SQL不同,它使用第一个主键作为分区键。在我看来,分区键最好不是唯一的。所以第二种设计更好。