对于Cassandra,如果所选行不存在,那么它是否会UPDATE隐含INSERT?就是说,如果我说
UPDATE users SET name = "Raedwald" WHERE id = 545127
Run Code Online (Sandbox Code Playgroud)
并且id是PRIMARY KEY对的users表,表中有没有行与545127的关键,那将是等同于
INSERT INTO users (id, name) VALUES (545127, "Raedwald")
Run Code Online (Sandbox Code Playgroud)
我知道相反的情况是正确的:INSERT对于id已经存在的已成为UPDATE行的一部分id.较早的Cassandra文档谈到了插入实际上是"upserts"的原因.
我对CQL3,Cassandra 1.2+版本感兴趣.
kbr*_*kbr 24
不幸的是,接受的答案并非 100% 准确。inserts 与updates不同:
cqlsh> create table ks.t (pk int, ck int, v int, primary key (pk, ck));
cqlsh> update ks.t set v = null where pk = 0 and ck = 0;
cqlsh> select * from ks.t where pk = 0 and ck = 0;
pk | ck | v
----+----+---
(0 rows)
cqlsh> insert into ks.t (pk,ck,v) values (0,0,null);
cqlsh> select * from ks.t where pk = 0 and ck = 0;
pk | ck | v
----+----+------
0 | 0 | null
(1 rows)
Run Code Online (Sandbox Code Playgroud)
斯库拉做同样的事情。
在 Scylla 和 Cassandra 中,行是单元格序列。每列都有一个对应的单元格(或者在非冻结集合或 UDT 的情况下是一组单元格)。但是还有一个额外的、不可见的单元格 -行标记(至少在 Scylla 中;我怀疑 Cassandra 有类似的东西)。
行标记对所有其他单元格都已死的行有所不同:当且仅当至少有一个活动单元格时,一行才会显示在查询中。因此,如果行标记处于活动状态,即使所有其他列之前使用例如updates设置为空,该行也会显示出来。
inserts 创建一个实时行标记,而updates 不接触行标记,所以很明显它们是不同的。上面的例子说明了这一点。有人可能会争辩说,行标记是 Cassandra/Scylla 的“内部”,但正如您所见,它们的效果是可见的。无论您喜欢与否,行标记都会影响您的生活,因此记住它们可能会很有用。
遗憾的是没有文档提到行标记(好吧,我发现了这个:https : //docs.scylladb.com/architecture/sstable/sstable2/sstable-data-file/#cql-row-marker但它是在解释的上下文中SSTable 内部结构,它可能更多地致力于 Scylla 开发人员而不是用户)。
奖励:单元格删除:
delete v from ks.t where pk = 0 and ck = 0
Run Code Online (Sandbox Code Playgroud)
与null更新相同:
update ks.t set v = null where pk = 0 and ck = 0
Run Code Online (Sandbox Code Playgroud)
实际上,单元格删除也不会触及行标记。它只将指定的单元格设置为null.
这与行删除不同:
delete from ks.t where pk = 0 and ck = 0
Run Code Online (Sandbox Code Playgroud)
因为行删除插入行墓碑,这会杀死行中的所有单元格(包括行标记)。您可以说行删除与插入相反。更新和单元格删除介于两者之间。
Kin*_*tes 15
然而,人们可以做的是:
UPDATE table_name SET field = false WHERE key = 55 IF EXISTS;
Run Code Online (Sandbox Code Playgroud)
这将确保您的更新是真正的更新,而不是upsert.