gpt4 book ai didi

cassandra - 使用二级索引更新 Cassandra 2.1 中的行

转载 作者:行者123 更新时间:2023-12-02 23:38:11 26 4
gpt4 key购买 nike

我使用的是 Cassandra 2.1,模型大致如下:

CREATE TABLE events (
client_id bigint,
bucket int,
timestamp timeuuid,
...
ticket_id bigint,
PRIMARY KEY ((client_id, bucket), timestamp)
);
CREATE INDEX events_ticket ON events(ticket_id);

如您所见,我已在 ticket_id 上创建了二级索引。这个索引工作正常。 events 包含大约 1 亿行,而其中只有 500 万行包含大约 50,000 个不同的门票。因此,一张票证平均包含 100 个事件。

查询二级索引无需提供分区键,这在我们的情况下很方便。由于 bucket 列有时很难事先确定(即您应该知道事件的日期,bucket 是当前日期)。

cqlsh> select * from events where ticket_id = 123;

client_id | bucket | timestamp | ... | ticket_id
-----------+--------+-----------+-----+-----------

(0 rows)

当一张工单的所有事件都需要转移到另一张工单时,如何解决问题? IE。以下查询将不起作用:

cqlsh> UPDATE events SET ticket_id = 321 WHERE ticket_id = 123;
InvalidRequest: code=2200 [Invalid query] message="Non PRIMARY KEY ticket_id found in where clause"

这是否意味着二级索引不能在 UPDATE 查询中使用?

我应该使用什么模型来支持这些更改?

最佳答案

首先,UPDATEINSERT 操作在 Cassandra 中的处理方式相同。它们通俗地称为“UPSERT”。

Does this imply secondary indexes cannot be used in UPDATE queries?

正确。如果不指定完整的 PRIMARY KEY,则无法在 Cassandra 中执行 UPSERT。即使具有部分主键的 UPSERT 也不起作用。而且(正如您所发现的)按索引值进行 UPSERT 也不起作用。

How do I solve the problem when all events of a ticket should be moved to another ticket?

不幸的是,实现此目的的唯一方法是查询 events 中每行的键(使用特定的 ticket_id)和 UPSERT ticket_id 通过这些键。好处是,您不必先删除它们,因为ticket_id不是主键的一部分。

How do I solve the problem when all events of a ticket should be moved to another ticket?

我认为您最好的计划是完全放弃二级索引,并创建一个查询表来与您的 events 表一起工作:

CREATE TABLE eventsbyticketid (
client_id bigint,
bucket int,
timestamp timeuuid,
...
ticket_id bigint,
PRIMARY KEY ((ticket_id), timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);

这将允许您快速按 ticket_id 查询(获取您的 client_idbuckettimestamp .这将为您提供在 events 表上 UPSERT 新 ticket_id 所需的信息。

然后,您还可以通过 ticket_id(在 eventsbyticketid 表上)执行DELETE。只要您拥有完整的分区键 (ticket_id),Cassandra 就允许使用部分主键进行DELETE 操作。因此,从查询表中删除旧的 ticket_id 会很容易。为了确保写入原子性,您可以将 UPSERT 一起批处理:

BEGIN BATCH
UPDATE events SET ticket_id = 321 WHERE client_id=2112 AND bucket='2015-04-22 14:53' AND timestamp=4a7e2730-e929-11e4-88c8-21b264d4c94d;
UPDATE eventsbyticketid SET client_id=2112, bucket='2015-04-22 14:53' WHERE ticket_id=321 AND timestamp=4a7e2730-e929-11e4-88c8-21b264d4c94d
APPLY BATCH;

这实际上与执行相同:

BEGIN BATCH
INSERT INTO events (client_id,bucket,timestamp,ticketid) VALUES(2112,'2015-04-22 14:53',4a7e2730-e929-11e4-88c8-21b264d4c94d,321);
INSERT INTO eventsbyticketid (client_id,bucket,timestamp,ticketid) VALUES(2112,'2015-04-22 14:53',4a7e2730-e929-11e4-88c8-21b264d4c94d,321);
APPLY BATCH;

旁注:timestamp 实际上是 Cassandra 中的一种(保留字)数据类型。这使得它成为 timeuuid 列的一个非常糟糕的名称。

关于cassandra - 使用二级索引更新 Cassandra 2.1 中的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30168264/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com