Cassandra 聊天应用程序:插入最后一条消息后对房间进行排序

Cassandra chat app: sorting rooms after last message inserted

对于一个消息传递应用程序,我有一个数据库结构相对于:

CREATE TABLE users(
    userid text,
    name text, 
    rooms list<text>
    ...
    PRIMARY KEY (userid)
);

CREATE TABLE rooms(
    roomid text,
    members list<text>,
    createdat bigint,
    lastmessage bigint,
    ...
    PRIMARY KEY (roomid, createdat)
);

CREATE TABLE messages(
    roomid text,
    bucket int,
    messageid bigint,
    authorid text,
    ...
    PRIMARY KEY ((hash, roomid), messageid)
);

启动时,客户端请求给定用户的所有房间。我希望在某个时候,用户将成为大量频道的成员。所以我只想检索最后 X 个活动频道以减少流量。

当前房间存储最后一个消息 ID(包括时间戳的雪花)所以我能够在检索所有房间后进行排序。

仅从 cassandra 加载最后 X 个活动房间需要进行哪些更改? 我知道我需要以某种方式对结构进行反规范化,但我不知道该怎么做。

提前致谢!

再创建一个table

CREATE TABLE user_active_channels (
   userid text,
   time bigint,
   room text,
   PRIMARY KEY (userid, time))
WITH CLUSTERING ORDER BY (time DESC);

每次用户加入房间时,将数据保存在此table。 然后查询:

SELECT room FROM user_active_channels
 WHERE userid='The users Id' AND time > 0 limit 5;

由于聚类列是时间,数据在分区上按降序排列,所以前5条记录将是时间最长的记录,因此是最新用户的活跃房间,避免检索所有数据,您可以将查询限制为仅 return 前 5 条记录。

这看起来像是您在 中的问题的变体,我建议在其中为您的应用查询“为用户提供所有房间”创建此 table:

CREATE TABLE rooms_by_userid (
  ...
  PRIMARY KEY (userid, roomid)
)

根据您的描述,应用查询听起来像是“给我一个用户最近的 10 个房间”。您还提到您正在使用 messageid 确定最近的房间。在这种情况下,table 看起来像:

CREATE TABLE rooms_by_userid_by_messageid (
   userid text,
   messageid bigint,
   roomid text,
   ...
   PRIMARY KEY (userid, messageid)
) WITH CLUSTERING ORDER BY (messageid DESC, roomid ASC)

此 table 中的数据将按用户 ID 进行分区,并将包含按消息 ID 倒序排序的行(最近的排在最前面),其中每条消息都有一个关联的房间。您将使用 LIMIT 10 检索 10 个最近的房间,如下所示:

SELECT roomid FROM rooms_by_userid_by_messageid
  WHERE userid = ?
  AND messageid = ?
  LIMIT 10;

这里的要点是数据已经按照您需要的顺序排序,因此当您从数据库中获取结果时不需要进行任何客户端排序。干杯!