不幸的是,接受的答案并非 100% 准确。insert
s 与 s 不同update
:
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)
斯库拉做同样的事情。
在 Scylla 和 Cassandra 中,行是细胞序列。每列都有一个对应的单元格(或在非冻结集合或 UDT 的情况下的一组单元格)。但是还有一个额外的、不可见的单元格 -行标记(至少在 Scylla 中;我怀疑 Cassandra 有类似的东西)。
行标记对所有其他单元格都死了的行产生了影响:当且仅当至少有一个活的单元格时,才会在查询中显示一行。因此,如果行标记处于活动状态,则该行将显示,即使所有其他列之前使用例如update
s 设置为空。
insert
s 创建一个实时行标记,而update
s 不触摸行标记,所以很明显它们是不同的。上面的例子说明了这一点。有人可能会争辩说,行标记是 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
与null
更新相同:
update ks.t set v = null where pk = 0 and ck = 0
实际上,单元格删除也不会触及行标记。它仅将指定的单元格设置为null
.
这与行删除不同:
delete from ks.t where pk = 0 and ck = 0
因为行删除插入行墓碑,这会杀死行中的所有单元格(包括行标记)。您可以说行删除与插入相反。更新和单元格删除介于两者之间。