在Cassandra中UPDATE和INSERT的区别



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

看起来以前没有区别,但是现在文档说INSERT不支持计数器而UPDATE支持。

是否有一个"首选"的方法使用?或者在某些情况下,应该使用其中一个而不是另一个?

非常感谢!

有一个微妙的区别。如果将所有非关键字段设置为空,则通过INSERT插入的记录将保留。如果将所有非关键字段设置为null,则通过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查看这些,您将看到添加行方式的不同。

我很想知道这是设计还是错误,并看到这个行为文档

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

因此,INSERT不支持计数器列,因为您不能将值"插入"到计数器列中。您只能通过某些值对它们进行UPDATE(递增或递减)。下面是更新Counter列的方法。

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

你问:

是否有一个"首选"的方法使用?或者在某些情况下,应该使用其中一个而不是另一个?

是的。如果要向数据库插入值,可以使用INSERT。如果列不存在,将为您创建它。否则,INSERT的效果与UPDATE相似。INSERT是有用的,当你没有一个预先设计的模式(动态列族,即插入任何东西,随时)。如果您正在预先设计模式(静态列族,类似于RDMS)并且知道每个列,那么您可以使用UPDATE

另一个微妙的区别(我开始相信cql对cassandra来说是一个糟糕的接口,由于使用类似的SQL语法,但语义略有不同,因此充满了微妙和警告)是在现有数据上设置ttl。使用UPDATE,您不能更新密钥的TTL,即使新的实际值等于旧的值。解决方案是插入新行,新的TTL已经设置为

关于billbaird强调的细微差异(我无法直接评论该帖子),如果所有非关键字段为空,则由更新操作创建的行将被删除:

这是预期的行为,而不是基于https://issues.apache.org/jira/browse/CASSANDRA-11805上的错误报告的错误(该错误被关闭为"not a Problem")

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

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

最新更新