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;
这里的要点是数据已经按照您需要的顺序排序,因此当您从数据库中获取结果时不需要进行任何客户端排序。干杯!
对于一个消息传递应用程序,我有一个数据库结构相对于:
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 条记录。
这看起来像是您在
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;
这里的要点是数据已经按照您需要的顺序排序,因此当您从数据库中获取结果时不需要进行任何客户端排序。干杯!