【问题标题】:Write and Update record on Cassandra along with clustering columns在 Cassandra 上写入和更新记录以及聚类列
【发布时间】:2017-04-02 15:41:02
【问题描述】:

我有一个通知表和附加索引

CREATE TABLE notification (
    postid double,
    userid double,
    type text,
    message text,
    hasread boolean,
    postdate timestamp,
    PRIMARY KEY (userid, postdate)
)  WITH  CLUSTERING ORDER BY (postdate DESC);

CREATE INDEX postid ON notification(postid);

假设我插入了几行

select * from notification;

 userid | postdate                        | hasread | message                | postid | type
--------+---------------------------------+---------+------------------------+--------+---------
    104 | 2016-11-18 17:21:32.692000+0000 |   False | Let\'s do it together! |  70521 | newpost
    104 | 2016-11-18 17:21:26.511000+0000 |   False | Let\'s do it together! |  90521 | newpost
    103 | 2016-11-18 17:20:17.284000+0000 |   False | Let\'s do it together! |  40521 | newpost
    103 | 2016-11-18 17:20:02.925000+0000 |   False | Let\'s do it together! |  40521 | newpost
    103 | 2016-11-18 17:19:55.643000+0000 |   False | Let\'s do it together! |  30521 | newpost
    103 | 2016-11-18 17:19:49.029000+0000 |   False | Let\'s do it together! |  60521 | newpost

如果我做简单的查询,即

select * from notification where postid=40521;

那么结果似乎很好

userid | postdate                        | hasread | message                | postid | type
--------+---------------------------------+---------+------------------------+--------+---------
    103 | 2016-11-18 17:20:17.284000+0000 |   False | Let\'s do it together! |  40521 | newpost
    103 | 2016-11-18 17:20:02.925000+0000 |   False | Let\'s do it together! |  40521 | newpost

或者让我们得到这样的一行

select * from notification where postid=60521;

单行看起来还不错

userid | postdate                        | hasread | message                | postid | type
--------+---------------------------------+---------+------------------------+--------+---------
    103 | 2016-11-18 17:19:49.029000+0000 |   False | Let\'s do it together! |  60521 | newpost

但是,当我在一行中更新 hasread 行时,我会丢失 postdate 错误,即聚类列

update notification set hasread=true where postid=60521 and userid=103;
InvalidRequest: Error from server: code=2200 [Invalid query] message="Some clustering keys are missing: postdate"

我需要按排序顺序获取列表,这就是我必须使用 postdate 作为聚类列的原因。 但是同时我需要更新特定的行。我想这是关于设计的,但仍然无法弄清楚。任何建议,将不胜感激。

【问题讨论】:

    标签: cassandra cqlsh nosql


    【解决方案1】:

    在 Cassandra 中更新一行时,您必须提供整个 PRIMARY KEY。这基本上就是该错误消息告诉您的内容。请记住,Cassandra 不是关系数据库,因此您将 能够通过 postid 进行更新。

    此外,重要的是要记住 Cassandra 不区分 INSERT 和 UPDATE。由于特定行的唯一性由其完整的 PRIMARY KEY 确定,因此您必须为所有 upsert 提供所有 PRIMARY KEY 组件。本质上,这就是您需要做的:

    UPDATE notification SET hasread=true 
      WHERE userid=103 AND postdate='2016-11-18 17:19:49.029+0000';
    

    此外,postid 似乎是一个高基数列。因此,依赖该二级索引的调用不会表现良好。完全一样。如果您确实需要通过postid 进行查询,您应该考虑为该模式构建一个额外的查询表。

    【讨论】:

    • 谢谢Aaron,看来我得先得到postdate,然后根据它更新
    【解决方案2】:

    不能通过在 where 子句中指定非主列来更新或删除。

    WHERE 子句指定要更新的行。要指定行,WHERE 子句必须为行的主键的每一列提供一个值。要指定多行,您可以使用 IN 关键字来引入可能值的列表。您只能对主键的最后一列执行此操作。

    让我们更新 postid=60521 和 userid=103 的 hasread 首先你需要选择postdate

    SELECT postdate FROM notification where postid=60521 and userid=103;
    

    您将收到postdate。现在您可以使用 userid 和 postdate 更新 hasread 字段

    update notification set hasread=true where userid=103 and postdate=?;
    

    【讨论】:

    • 最后一个更新语句有两个问题。一、WHERE 子句中的postid=60521 不起作用。其次,你的毫秒精度太高了。 CQL 将产生unable to coerce...to a formatted date
    • 哦对不起我的错误。谢谢@Aaron
    猜你喜欢
    • 2017-04-16
    • 2020-08-16
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2021-02-28
    • 2013-02-06
    相关资源
    最近更新 更多