Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cassandra 更新是否成为隐含的插入_Cassandra_Cql - Fatal编程技术网

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文

对于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