Cassandra中UPDATE和INSERT之间的区别?

时间:2013-05-13 22:32:09

标签: cassandra cql cql3

对Cassandra执行CQL时,UPDATEINSERT之间有什么区别?

看起来似乎没有区别,但现在documentation表示INSERT不支持UPDATE的计数器。

是否有"首选"使用方法?或者是否有人应该使用另一个?

非常感谢!

4 个答案:

答案 0 :(得分:46)

有一个微妙的区别。如果将所有非键字段设置为null,则会保留通过INSERT插入的记录。如果将所有非键字段设置为空,则通过UPDATE插入的记录将消失。

试试这个:

CREATE TABLE T (
  pk int,
  f1 int,
  PRIMARY KEY (pk)
);

INSERT INTO T (pk, f1) VALUES (1, 1);
UPDATE T SET f1=2 where pk=2;
SELECT * FROM T;

返回:

 pk | f1
----+----
  1 |  1
  2 |  2

现在,将每行设置f1更新为null。

UPDATE T SET f1 = null WHERE pk = 1;
UPDATE T SET f1 = null WHERE pk = 2;
SELECT * FROM T;

请注意,第1行仍然存在,而第2行则被删除。

 pk | f1
----+------
  1 | null

如果您使用Cassandra-cli查看这些内容,您会看到添加行的方式不同。

我确定想知道这是设计还是错误,并且会记录此行为。

答案 1 :(得分:19)

Cassandra中的计数器列无法设置为任意值:它们只能递增或递减任意值。

因此,INSERT不支持计数器列,因为您无法将值“插入”计数器列。您只能UPDATE它们(递增或递减)某个值。以下是更新计数器列的方法。

    UPDATE ... SET name1 = name1 + <value> 

你问:

  
    

是否有“首选”方法可供使用?或者是否有人应该使用另一个?

  

是。如果要将值插入数据库,则可以使用INSERT。如果列不存在,将为您创建。否则,INSERT的效果类似于UPDATE。如果您没有预先设计的架构(动态列族,即随时插入任何内容),INSERT非常有用。如果您事先设计架构(静态列族,类似于RDMS)并且知道每列,那么您可以使用UPDATE

答案 2 :(得分:1)

另一个微妙的区别(我开始相信cql是一个可怕的cassandra接口,由于使用类似的SQL语法但语义略有不同而充满细微之处和警告)是在现有数据上设置TTL。使用UPDATE,即使新的实际值等于旧值,也无法更新键的TTL。解决方案是改为插入新行,并设置新的TTL

答案 3 :(得分:0)

关于billbaird突出显示的细微差别(我无法直接评论该帖子),如果所有非关键字段都为空,则删除由更新操作创建的行:

这是预期的行为而不是基于https://issues.apache.org/jira/browse/CASSANDRA-11805的错误报告的错误(已被关闭为“不是问题”)

我第一次使用Spring Data时遇到了这个问题。我使用的是存储库的save(T entity)方法,但没有创建任何行。事实证明,Spring Data正在使用UPDATE因为它确定对象不是'new'(不确定'isNew'的测试在这里是否有意义),而我碰巧正在测试只有关键字段设置。

对于这个Spring Data案例,Cassandra特定的存储库接口确实提供了insert方法,如果需要这种行为,它似乎始终使用INSERT(尽管Spring的文档没有记录这些细节充足)。