卡桑德拉柱系列设计

时间:2015-05-18 09:40:23

标签: cassandra

我在设计符合以下要求的色谱柱系列时遇到问题: 我想更新符合某些条件的X行,这些行不是主键且不是唯一的。

例如,如果User列系列包含IDnamebirthday列,我想更新在特定日期之后出生的所有用户。
即使我添加了生日'到主键(假设' ID','生日')我无法执行此查询,因为缺少部分主键。

我如何通过设计不同的列系列来解决这个问题? 感谢。

1 个答案:

答案 0 :(得分:1)

根据cassandra docs,如果没有明确定义其分区键,则无法更新行。这不是出于意外,而是因为此功能(例如update users set status=1 where id>10)可以允许用户一次更新表中的所有数据,这在大型数据库上可能非常非常昂贵。 Cassandra明确禁止所有需要在多个分区内进行数据扫描的操作。

要一次更新多个用户,您必须知道他们的ID。将表定义为:

CREATE TABLE stackoverflow.users (
    id timeuuid PRIMARY KEY,
    dob timestamp,
    status text
)

并且知道用户的主键,您可以运行update users set status='foo' where id in (1,2,3,4)之类的查询。但IN语句中包含非常大的键集的查询可能cause performance issues on C*

但是如何才能拥有像select id from some_table where dob>'2000-01-01 00:00:01'这样有效的范围查询?有两种选择,而且这两种选择都不可接受:

  1. 创建一个索引表 CREATE TABLE stackoverflow.dob_index ( year int, dob timestamp, ids list<timeuuid>, PRIMARY KEY (year, dob) ) 使用复合分区+群集主键,并使用多个查询(如select * from dob_index where year=2014 and dob<'2014-05-01 00:00:01';)来获取不同年份的ID。请注意,我已为表定义了多个分区,以便在群集中具有某种均匀的分区分布。但一般的想法是,你真的不应该有少量非常大的分区。如果有选择的话,请选择大量小的。
  2. 为复杂查询提供单独的独立索引(如ElasticSearch / Solr / Sphinx)。
  3. 但我建议您重新审视您的应用程序逻辑,以避免更新/删除数据:

    1. 而不是直接更新users表,您可以使用单独的表user_status插入新状态: CREATE TABLE user_statuses ( id timeuuid, updated_at timestamp, status text, PRIMARY KEY (id, updated_at) )
    2. 当您需要一次扫描/更新大量行时,更喜欢使用Spark等工具在您的群集节点之间有效地分配工作负载。