如何进行保留列值的条件更新插入?

问题描述 投票:0回答:1

我希望模仿一个更新插入功能,但也添加了一个条件要求,即如果该行尚不存在,则插入所有行,但如果该行存在,则仅更新某些行。我在这上面花了很长时间,似乎无法找到一种通过良好实践来实现这一目标的方法。

例如,假设我有这张表:

Issues
            id            TEXT,
            type          INT,
            creationDate  TIMESTAMP
PRIMARY KEY (id)
  1. 如果我尝试插入
    {id: 123, type: 2, creationDate: 1000}
    并且主键不存在,我将所有列插入到一个新行中。
  2. 如果我尝试使用
    {id: 123, type: 4, creationDate: 1053}
    再次插入,我希望行为是 creationDate 保持为 1000 以显示第一个问题发生的时间,但我希望该类型反映最近的问题类型“4”。
  3. 所以现在该行应该是
    {id: 123, type: 4, creationDate: 1000}

这在 CQL 中可能吗?解决这个问题的最佳方法是什么?到目前为止,我想过批处理 INSERT-IF-NOT-EXISTS 和 UPDATE 并一起执行它们......或者我想过运行 SELECT 然后在 golang 中根据行是否确定是插入还是更新存在与否。

注意:我的代码在 golang 中,我正在使用 gocqlx 库来实现这一点。我的主要目标是让它以遵循 cassandra/cql 最佳实践的有效方式工作

谢谢! :)

cassandra cql gocql gocqlx
1个回答
1
投票

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

希望这适用于您的用例。干杯!

© www.soinside.com 2019 - 2024. All rights reserved.