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) 操作时,INSERT
和 UPDATE
之间的语法和功能是 而不是 一样。
Case-in-point,IF NOT EXISTS
条件对 INSERT
有效,但对 UPDATE
无效。在 flip-side 上,IF EXISTS
对 UPDATE
有效,但对 INSERT
无效。
其次,OR
不是 CQL WHERE
或 CAS 操作条件中的有效运算符。
第三,使用 UPDATE
和 IF 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
的值是什么,从而触发额外的写入?这里可能存在竞争条件,所以我会仔细检查业务需求,看看这样的事情是否可行。
如果记录不存在,我想在单个操作中执行插入操作,或者仅当行的某个字段具有特定值时才进行更新。
想象一下 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) 操作时,INSERT
和 UPDATE
之间的语法和功能是 而不是 一样。
Case-in-point,IF NOT EXISTS
条件对 INSERT
有效,但对 UPDATE
无效。在 flip-side 上,IF EXISTS
对 UPDATE
有效,但对 INSERT
无效。
其次,OR
不是 CQL WHERE
或 CAS 操作条件中的有效运算符。
第三,使用 UPDATE
和 IF 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
的值是什么,从而触发额外的写入?这里可能存在竞争条件,所以我会仔细检查业务需求,看看这样的事情是否可行。