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

v1l68za4  于 2022-09-27  发布在  Cassandra
关注(0)|答案(2)|浏览(263)

对于消息应用程序,我的数据库结构与以下内容相比:

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个活动频道以减少流量。
目前,房间存储了最后一个messageid(雪花,包括时间戳),因此我可以在检索所有房间后进行排序。
仅从Cassandra加载最后X个活动房间需要进行哪些更改?我知道我需要以某种方式使结构非规范化,但我不知道如何实现。

bf1o4zei

bf1o4zei1#

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

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

从你的描述来看,应用程序查询听起来像是“给我一个用户最近的10个房间”。您还提到您正在使用messageid确定最近的房间。在这种情况下,表格如下所示:

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)

此表中的数据将按用户ID进行分区,并将包含按消息ID排序的行,这些行的顺序与消息ID相反(最近的第一个),其中每条消息都有一个关联的房间。您可以使用e1d1e检索最近的10个房间,如下所示:

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

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

bttbmeg0

bttbmeg02#

创建另一个表

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

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

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

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

相关问题