需要推荐适当的主键结构

时间:2014-10-01 18:02:52

标签: cassandra database nosql

我有很多时间序列数据,我想存储在Cassandra数据库中。由于我只能对主键中的字段执行WHERE子句,因此我需要一些建议,说明如何根据我查询它的方式来解决这个问题。

我的数据采用以下格式:

SYSTEM_SERIAL_NUMBER,DEVICE_ID,TIMESTAMP,...OTHER COLUMNS

每个序列号都有多个设备,每个设备都有数千个时间戳,因此唯一标识每组数据的主键必须包含所有三个。

我将对此数据进行基本上两种类型的查询。

SELECT * FROM TABLE WHERE system_serial_number = 'X' and device_id = 'x' and timestamp(在范围内)

SELECT * FROM TABLE WHERE system_serial_number = 'X' and timestamp(在范围内)

第二个是查询的可能性更大,因为我通常会在应用程序中输入一个时间范围,并且我希望查看每个设备中给定序列号的数据。但我无法将设备名称保留在密钥之外,因为您需要串行/设备/时间戳才能唯一地标识整行。

我尝试按如下方式创建表:

CREATE TABLE devices (
system_serial_number text,
device_id int,
time_stamp timestamp,
...,
PRIMARY KEY ((system_serial_number,device_id),time_stamp)
);

还有:

CREATE TABLE devices (
system_serial_number text,
device_id int,
time_stamp timestamp,
...,
PRIMARY KEY (system_serial_number,device_id,time_stamp)
);

我认为第一个会阻止我限制列限制,但它总是要求我每次查询时都输入设备ID和Serial。第二个是列效率较低(基于我的理解),它允许我只通过序列搜索。他们中的任何一个都不允许我通过串行/时间戳进行搜索,这实际上是我将要进行的最常见的搜索,但并不是唯一足以成为主键的。

我能够让查询工作的唯一方法是使用带有复合键的第一个,然后为序列号添加二级索引,然后允许我按序列搜索/时间戳,但我必须使用效率低下的ALLOW FILTERING

有关获得我需要的最佳方式的任何建议吗?

1 个答案:

答案 0 :(得分:1)

最简单的答案是:

PRIMARY KEY (system_serial_number, time_stamp, device_id)
  • system_serial_number将是分区密钥,用于标识哪些副本(节点)将包含数据。单个序列号的所有数据都需要适合同一个分区。为了有效访问,将需要所有查询来指定序列号。如果分区大小是一个问题,如果用例允许,可能有进一步细分的方法。

  • time_stamp将是用于对分区内的行进行排序的群集密钥。也就是说,无论设备如何,相同序列号的所有逻辑行都将按时间戳排序。 不是分区键的第一个PK列确定排序顺序。

  • device_id是用于区分逻辑行的附加PK列,但不会帮助您排序或执行其他范围扫描。

由于您提到每个设备都会生成数千个时间戳,并且每个序列号都有许多设备,因此如果采用上述方法,您可能还需要关注分区的大小。一种常见的方法是在多个分区中中断单个序列号的数据,但这可以使查询数据更高效或更麻烦,具体取决于您决定细分数据的方式。

您必须使用一些想象力和特定用例的知识来决定正确的分区布局。我能想到一些想法:

  • PRIMARY KEY ((system_serial_number, device_hash_modulus), time_stamp, device_id)

    • 想法:哈希您的设备ID并应用模数将数据拆分为固定数量的“存储桶”
    • 优势:使用均匀哈希分布,在已知数量的节点上均匀分布数据
    • 缺点:查询给定序列号的“所有设备”需要进行 N 查询,根据为模运算选择的数量为每个“桶”一个查询
    • 缺点:如果初始选择对于最终数据大小而言太小,则可能需要调整存储方案(并迁移数据)

  • PRIMARY KEY ((system_serial_number, coarse_time_stamp), time_stamp, device_id)

    • 想法:将数据随时间分成不同的分区,大小取决于粗略你如何制作分区时间戳(年?年+月?,年+天?等)。应根据在给定时间段内预期有多少独特记录做出决定。
    • 优势:假设群集配置了随机分区程序,随着时间的推移,数据将在群集中均匀分布。
    • 缺点:在时间范围内查询记录可能涉及对不同分区进行单独查询,从而使程序逻辑更加复杂。如果分区时间戳不够粗糙,或者要搜索的时间戳范围太宽,性能将受到影响。

您可能还有其他选择,但这取决于您对当前用例的理解程度(以及您预测数据集未来行为的程度)。

相关问题