为什么Cassandra UPDATE不违反写入前不读取规则



我对关于卡桑德拉的两个看似矛盾的说法感到困惑

    写入
  1. 前不读取(大概这是因为写入是顺序的,而读取需要扫描主键索引)
  2. INSERT 和 UPDATE 具有相同的语义(在旧版本的 CQL 手册中声明,但可能仍然认为本质上是正确的)

假设我创建了以下简单表:

CREATE TABLE data (
  id varchar PRIMARY KEY,
  names set<text>
);

现在我插入一些值:

insert into data (id, names) values ('123', {'joe', 'john'});

现在,如果我进行更新:

update data set names = names + {'mary'} where id = '123';

结果符合预期:

 id  | names
-----+-------------------------
 123 | {'joe', 'john', 'mary'}

这不是在写入之前必须进行读取的情况吗?"成本"似乎如下

  1. 读取列的成本
  2. 创建两个集合的并集的成本(此处可以忽略不计,但对于较大的集合可能会很明显)
  3. 使用键数据和新列数据写入数据的成本

插入只是做最后一件事。

写作前无需阅读。
在内部,每个集合使用每个条目一列来存储数据 -- 当您请求集合中的新条目时,操作在单列*中完成:如果该列已经存在,它将被覆盖,否则将被创建(InsertOrUpdate)。这就是为什么集合中的每个条目都可以具有自定义 ttl 和写入时间的原因。

*虽然使用 MapSet 这是透明的,但有一些内部技巧可以在List内允许多个具有相同名称的列。

最新更新