46

UPDATE对 Cassandra 执行 CQL和INSERT执行 CQL之间有什么区别?

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

是否有“首选”方法可以使用?或者在某些情况下应该使用一个而不是另一个?

非常感谢!

4

4 回答 4

54

有细微的差别。如果将所有非关键字段设置为空,则通过 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 查看这些内容,您会发现添加行的方式有所不同。

我很想知道这是设计使然还是错误,并查看记录此行为。

于 2014-05-16T23:04:23.010 回答
20

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

出于这个原因,INSERT不支持计数器列,因为您不能将值“插入”到计数器列中。您只能UPDATE将它们(增加或减少)某个值。以下是更新 Counter 列的方法。

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

您问:

是否有“首选”方法可以使用?或者在某些情况下应该使用一个而不是另一个?

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

于 2013-05-14T00:45:45.067 回答
2

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

于 2017-08-17T14:18:17.943 回答
0

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

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

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

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

于 2017-05-28T09:34:55.073 回答