Cassandra insert/update 如果不存在或字段=值

Cassandra insert/update if not exists or field=value

如果记录不存在,我想在单个操作中执行插入操作,或者仅当行的某个字段具有特定值时才进行更新。

想象一下 table:

CREATE TABLE (id VARCHAR PRIMARY KEY, field_a VARCHAR, field_b VARCHAR);

是否可以有类似的东西:

UPDATE my_table SET field_a='test' WHERE id='an-id' IF NOT EXISTS OR IF field_b='AVALUE';

在插入记录的单个语句上执行 INSERT/UPDATE 如果 field_b 具有值 AVALUE 或如果行尚不存在则创建新行,但万一行在 table 中,field_b 具有不同的值,更新失败。

UPDATE my_table SET field_a='test' WHERE id='an-id'
IF NOT EXISTS OR IF field_b='AVALUE';

这里有一些细微差别。首先,重要的是要记住,在 CQL 中执行 compare-and-set (CAS) 操作时,INSERTUPDATE 之间的语法和功能是 而不是 一样。

Case-in-point,IF NOT EXISTS 条件对 INSERT 有效,但对 UPDATE 无效。在 flip-side 上,IF EXISTSUPDATE 有效,但对 INSERT 无效。

其次,OR 不是 CQL WHERE 或 CAS 操作条件中的有效运算符。

第三,使用 UPDATEIF EXISTS short-circuits 任何后续条件。所以 UPDATE 可以 使用 IF EXISTS IF (condition) [ AND (another condition) ],但不能同时使用。

考虑到这些要点,这里的一种方法似乎是将语句分成两部分:

INSERT INTO my_table (id,field_a) VALUES ('a1','test') IF NOT EXISTS;

并且:

UPDATE my_table SET field_a='test' WHERE id='an-id' IF field_b='AVALUE';

这些都是有效的 CQL。但是,这并没有真正帮助这种情况。另一种方法是在应用程序端构建此逻辑。从技术上讲,read-before-write 方法在 Cassandra 中被认为是 anti-patterns,in-built CAS 操作由于使用轻量级事务而无法承受。

也许像SELECT field_a,field_b FROM my_table WHERE id='an-id';这样的东西足以回答它是否存在以及field_b的值是什么,从而触发额外的写入?这里可能存在竞争条件,所以我会仔细检查业务需求,看看这样的事情是否可行。