Cassandra 更新是否成为隐含的插入
对于Cassandra,如果所选行不存在,Cassandra 更新是否成为隐含的插入,cassandra,cql,Cassandra,Cql,对于Cassandra,如果所选行不存在,UPDATEs是否成为隐含的INSERT?也就是说,如果我说 UPDATE users SET name = "Raedwald" WHERE id = 545127 而id是用户表的主键,并且该表没有键为545127的行,这是否等同于 INSERT INTO users (id, name) VALUES (545127, "Raedwald") 我知道情况正好相反:对于已经存在的id的INSERT将成为该id行的更新。旧的Cassandra文
UPDATE
s是否成为隐含的INSERT
?也就是说,如果我说
UPDATE users SET name = "Raedwald" WHERE id = 545127
而id
是用户
表的主键
,并且该表没有键为545127的行,这是否等同于
INSERT INTO users (id, name) VALUES (545127, "Raedwald")
我知道情况正好相反:对于已经存在的id
的INSERT
将成为该id
行的更新。旧的Cassandra文档提到插入实际上是出于这个原因的“upserts”
我对CQL3,Cassandra版本1.2+的情况很感兴趣。是的,因为Cassandra的更新
与插入
同义,如下面关于更新
的内容所述:
请注意,与SQL不同,UPDATE
不检查行的先前存在性:如果之前不存在行,则创建该行,否则更新该行。此外,没有办法知道发生了哪些创建或更新。实际上,INSERT
和UPDATE
的语义是相同的
为了使语义有所不同,Cassandra需要进行读取以了解行是否已经存在。Cassandra是写优化的,所以您可以始终假设它不会在任何写操作上先读后写。唯一的例外是计数器(除非replicate\u on\u write=false
),在这种情况下,增量复制涉及读取。但是,我们可以做的是:
UPDATE table_name SET field = false WHERE key = 55 IF EXISTS;
这将确保您的更新是真实的更新,而不是升级。不幸的是,接受的答案并非100%准确<代码>插入
s与更新
s不同:
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)
锡拉也做了同样的事情
在“锡拉”和“卡桑德拉”中,成排的是细胞序列。每列获取一个对应的单元格(对于非冻结集合或UDT,则获取一组单元格)。但是还有一个不可见的细胞——行标记(至少在锡拉;我怀疑卡桑德拉也有类似的东西)
行标记对所有其他单元格都已死亡的行有区别:当且仅当至少有一个活动单元格时,查询中才会显示一行。因此,如果行标记处于活动状态,则该行将显示,即使之前使用例如update
s将所有其他列设置为null
insert
s创建一个活动行标记,而update
s不接触行标记,因此它们显然是不同的。上面的例子说明了这一点。
有人可能会说,行标记是卡桑德拉/锡拉的“内部”标记,但正如你所看到的,它们的效果是显而易见的。无论你喜欢与否,行标记都会影响你的生活,所以记住它们可能会很有用
令人遗憾的是,没有任何文档提到行标记(我发现了这一点:但这是在解释SSTable内部的上下文中发现的,这可能是专用于Scylla开发人员而不是用户的)
奖励:单元格删除:
与null
更新相同:
update ks.t set v = null where pk = 0 and ck = 0
实际上,单元格删除也不会触及行标记。它仅将指定的单元格设置为null
这与行删除不同:
因为行删除插入行墓碑,这将杀死行中的所有单元格(包括行标记)。可以说行删除与插入相反。更新和单元格删除介于两者之间。您好,我有一个问题,键上的更新与插入相同,但如果我想更新另一列上的数据(如用户名或…)。与insert相同吗?合并批量数据的最佳解决方案是什么?是的。需要澄清的是:
如果存在
将阻止插入
LightWeightTransactions需要启用以支持此类查询。这是一个有趣的调用。我试过你的例子,效果正如你所说的。当然,当您将值v
设置为null
以外的值时,update
确实会创建一个行标记,因此对于null
值,它的行为似乎有所不同。那一定是你提到的“一个活细胞”。再说一次,这是一个好发现!当然,当您将值v设置为null以外的值时,update
会创建一个行标记“nope!尝试将值更新回null
。编辑,更多详细信息:update
将v
设置为非null
,然后将其更新回null
,该行将消失。但是,在使用insert
设置v
后,然后将其更新为null
,该行仍将存在。因为insert
创建了一个行标记。将v
更新为非null
后看到该行的原因是v
单元格处于活动状态。行标记不可用。在使用非空的插入后,有两个活动单元格:v
单元格和行标记。这是一个很好的解释。这将是一个博客帖子的好话题!谢谢我们来看看博客帖子:)
update ks.t set v = null where pk = 0 and ck = 0
delete from ks.t where pk = 0 and ck = 0