我希望模仿一个更新插入功能,但也添加了一个条件要求,即如果该行尚不存在,则插入所有行,但如果该行存在,则仅更新某些行。我在这上面花了很长时间,似乎无法找到一种通过良好实践来实现这一目标的方法。
例如,假设我有这张表:
Issues
id TEXT,
type INT,
creationDate TIMESTAMP
PRIMARY KEY (id)
{id: 123, type: 2, creationDate: 1000}
并且主键不存在,我将所有列插入到一个新行中。{id: 123, type: 4, creationDate: 1053}
再次插入,我希望行为是 creationDate 保持为 1000 以显示第一个问题发生的时间,但我希望该类型反映最近的问题类型“4”。{id: 123, type: 4, creationDate: 1000}
这在 CQL 中可能吗?解决这个问题的最佳方法是什么?到目前为止,我想过批处理 INSERT-IF-NOT-EXISTS 和 UPDATE 并一起执行它们......或者我想过运行 SELECT 然后在 golang 中根据行是否确定是插入还是更新存在与否。
注意:我的代码在 golang 中,我正在使用 gocqlx 库来实现这一点。我的主要目标是让它以遵循 cassandra/cql 最佳实践的有效方式工作
谢谢! :)
CQL 不支持您概述的复杂场景。
只能在分区键上指定条件,不能在分区中指定非主键列。没有 CQL 语法可以防止列已存在时被覆盖。干杯!
[更新] 仔细考虑之后,一个可能的解决方法是将创建定义为 CQL
set
集合。由于 set
中的元素是有序的,您知道第一个元素将始终是最早的创建日期。
为了说明,这是我的示例表架构:
CREATE TABLE community.myset (
id int PRIMARY KEY,
creation set<int>,
type int
)
我可以做一个upsert,不管它是否存在:
cqlsh> UPDATE myset SET creation = creation + {10} WHERE id = 1;
cqlsh> SELECT * FROM myset ;
id | creation | type
----+----------+------
1 | {10} | null
重复做:
cqlsh> UPDATE myset SET creation = creation + {100} WHERE id = 1;
cqlsh> SELECT * FROM myset ;
id | creation | type
----+-----------+------
1 | {10, 100} | null
然后我可以独立设置类型:
cqlsh> UPDATE myset SET type=1 WHERE id = 1;
cqlsh> SELECT * FROM myset ;
id | creation | type
----+-----------+------
1 | {10, 100} | 1
希望这适用于您的用例。干杯!