【问题标题】:Cassandra column family designCassandra 柱族设计
【发布时间】:2015-05-18 09:40:23
【问题描述】:

我在设计符合以下要求的列族时遇到了问题: 我想为非主键且不唯一的字段更新与某些条件匹配的 X 行。

例如,如果 User 列族具有 IDnamebirthday 列,我想更新在某个特定日期之后出生的所有用户。
即使我将“生日”添加到主键(比如说“ID”、“生日”),我也无法执行此查询,因为缺少部分主键。

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

【问题讨论】:

    标签: cassandra


    【解决方案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&lt;'2014-05-01 00:00:01'; 来获取不同年份的 id。请注意,我已经为表定义了多个分区,以便在集群中具有某种均匀的分区分布。但一般的想法是,你真的不应该有少量非常大的分区。如果有选择的话,更喜欢大量的小东西。
    2. 为复杂查询(如 ElasticSearch/Solr/Sphinx)提供单独的独立索引。

    但我建议您重新审视您的应用程序逻辑,以避免更新/删除数据:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-25
      • 2020-01-26
      • 1970-01-01
      相关资源
      最近更新 更多