Cassandra - 按 ID 分组和按日期排序
Cassandra - Grouping By ID and Ordering by Date
我的应用程序的一部分由一个讨论板组成:有线程、posts 和类别。线程按类别分组,posts 按线程分组。我在提出一个模型/查询时遇到问题,该模型/查询将允许按类别选择线程,并按其最后 post.
的降序排列
类别
CREATE TABLE keyspace.categories (
id ascii PRIMARY KEY,
description text,
name text,
...
);
线程
CREATE TABLE keyspace.threads (
id ascii PRIMARY KEY,
category_id ascii,
content text,
...
);
Post
CREATE TABLE keyspace.posts (
thread_id ascii,
created_at timestamp,
id ascii,
content text,
...
PRIMARY KEY (thread_id, created_at, id)
);
我最初考虑将最后一个 post 的 "created at" 时间作为线程 table 上的集群键,但这是不可能的,因为它会随着每个 post.
然后我考虑创建一个中间体 table,每次创建 post 时都会写入该中间体。这解决了第一种方法的不可变性问题,但问题是它将包含每个线程的多个值,而且我无法找出支持按线程分组和按日期排序的分区/集群顺序。
例如,以下内容允许我按线程分组,但不能按日期排序:
CREATE TABLE last_post_for_category (
category_id ascii,
thread_id ascii,
created_at timestamp,
PRIMARY KEY ((category_id), thread_id, created_at)
) WITH CLUSTERING ORDER BY (thread_id DESC, created_at DESC);
SELECT thread_id FROM last_post_for_category WHERE category_id = 'category' GROUP BY thread_id, created_at;
以下将允许我按日期排序,但不能按线程分组:
CREATE TABLE keyspace.last_post_for_category (
category_id ascii,
thread_id ascii,
created_at timestamp,
PRIMARY KEY ((category_id), created_at, thread_id)
) WITH CLUSTERING ORDER BY (created_at DESC, thread_id DESC);
SELECT thread_id FROM last_post_for_category WHERE category_id = 'category' GROUP BY created_at, thread_id;
我无法在 (category_id, thread_id)
上执行 distinct
,因为我对执行此查询时的线程 ID 一无所知。
有人知道我如何才能最好地表示此排序吗?
首先,我建议您使用数据类型datetime
而不是timestamp
,因为这样可以方便您修改它或设置默认值。这只是一个建议。
建议的解决方案:
将属性last_post
添加到tablethreads
以保存每个线程中最后添加的时间post。
首次创建线程时,last_post
值应该等于一个非常旧的日期(因为该线程中还没有 post)。
tha 之后,创建一个触发器,以便每当在 posts
中插入一个 post 时,触发器就会更新相应线程的 last_post
值。可以这样添加触发器:
CREATE TRIGGER triggerName ON posts
FOR INSERT
AS
declare @post_time datetime;
declare @thread_id int;
select @post_time=i.created_at from inserted i;
select @thread_id=i.thread_id from inserted i;
update threads set lastpost = @post_time where id=@thread_id
GO
最后一步将按 last_post
排序的类别直接查询 select 个线程,就像这样:
select * from threads where category_id = 'theCategoryYouWant' order by lastpost asc /*or desc as you like*/
注意:如果你想在编辑post时更新created_at
,你需要添加一个类似的触发器来更新last_post
对应线程的属性。
我的应用程序的一部分由一个讨论板组成:有线程、posts 和类别。线程按类别分组,posts 按线程分组。我在提出一个模型/查询时遇到问题,该模型/查询将允许按类别选择线程,并按其最后 post.
的降序排列类别
CREATE TABLE keyspace.categories (
id ascii PRIMARY KEY,
description text,
name text,
...
);
线程
CREATE TABLE keyspace.threads (
id ascii PRIMARY KEY,
category_id ascii,
content text,
...
);
Post
CREATE TABLE keyspace.posts (
thread_id ascii,
created_at timestamp,
id ascii,
content text,
...
PRIMARY KEY (thread_id, created_at, id)
);
我最初考虑将最后一个 post 的 "created at" 时间作为线程 table 上的集群键,但这是不可能的,因为它会随着每个 post.
然后我考虑创建一个中间体 table,每次创建 post 时都会写入该中间体。这解决了第一种方法的不可变性问题,但问题是它将包含每个线程的多个值,而且我无法找出支持按线程分组和按日期排序的分区/集群顺序。
例如,以下内容允许我按线程分组,但不能按日期排序:
CREATE TABLE last_post_for_category (
category_id ascii,
thread_id ascii,
created_at timestamp,
PRIMARY KEY ((category_id), thread_id, created_at)
) WITH CLUSTERING ORDER BY (thread_id DESC, created_at DESC);
SELECT thread_id FROM last_post_for_category WHERE category_id = 'category' GROUP BY thread_id, created_at;
以下将允许我按日期排序,但不能按线程分组:
CREATE TABLE keyspace.last_post_for_category (
category_id ascii,
thread_id ascii,
created_at timestamp,
PRIMARY KEY ((category_id), created_at, thread_id)
) WITH CLUSTERING ORDER BY (created_at DESC, thread_id DESC);
SELECT thread_id FROM last_post_for_category WHERE category_id = 'category' GROUP BY created_at, thread_id;
我无法在 (category_id, thread_id)
上执行 distinct
,因为我对执行此查询时的线程 ID 一无所知。
有人知道我如何才能最好地表示此排序吗?
首先,我建议您使用数据类型datetime
而不是timestamp
,因为这样可以方便您修改它或设置默认值。这只是一个建议。
建议的解决方案:
将属性last_post
添加到tablethreads
以保存每个线程中最后添加的时间post。
首次创建线程时,last_post
值应该等于一个非常旧的日期(因为该线程中还没有 post)。
tha 之后,创建一个触发器,以便每当在 posts
中插入一个 post 时,触发器就会更新相应线程的 last_post
值。可以这样添加触发器:
CREATE TRIGGER triggerName ON posts
FOR INSERT
AS
declare @post_time datetime;
declare @thread_id int;
select @post_time=i.created_at from inserted i;
select @thread_id=i.thread_id from inserted i;
update threads set lastpost = @post_time where id=@thread_id
GO
最后一步将按 last_post
排序的类别直接查询 select 个线程,就像这样:
select * from threads where category_id = 'theCategoryYouWant' order by lastpost asc /*or desc as you like*/
注意:如果你想在编辑post时更新created_at
,你需要添加一个类似的触发器来更新last_post
对应线程的属性。