新闻提要,例如 cassandra 上的时间序列数据
news feed like time-series data on cassandra
我正在制作一个网站,我想将所有用户 post 存储在一个 table 中,按他们 post 的时间排序。我做的cassandra数据模型是这个
CREATE TABLE Posts(
ID uuid,
title text,
insertedTime timestamp,
postHour int,
contentURL text,
userID text,
PRIMARY KEY (postHour, insertedTime)
) WITH CLUSTERING ORDER BY (insertedTime DESC);
我面临的问题是,当用户访问 posts 页面时,它通过查询
获取最新的页面
SELECT * FROM Posts WHERE postHour = ?;
? = 当前时间
到目前为止,当用户向下滚动时 ajax 请求从服务器获取更多 post。 Javascript 跟踪 lastFetched 项目的 post 小时,并在请求新的 posts 时与 cassandra PagingState 一起发回服务器。
但是当用户向下滚动时,这种方法将查询超过 1 个分区。
我想知道这个模型是否可以毫无问题地执行,是否有任何其他模型可以遵循。
有人请指点我正确的方向。
谢谢。
这是一个好的开始,但有几点建议:
您可能需要的不仅仅是 postHour
作为分区键。我猜您不希望将所有 post 不分日期 存储在一起,然后翻阅它们。你可能想看的是:
PRIMARY KEY ((postYear, postMonth, postDay, postHour), insertedTime)
但是还是有问题。您的 PRIMARY KEY
必须唯一标识一行(在本例中为 post)。我猜测有可能,尽管不太可能,两个用户可能会使用相同的 insertedTime
值创建 post。那么您真正需要的是添加 ID
以确保它们是唯一的:
PRIMARY KEY ((postYear, postMonth, postDay, postHour), insertedTime, ID)
在这一点上,我会考虑将您的 ID
和 insertedTime
列合并为 timeuuid
类型的单个 ID
列。通过这些更改,您的最终 table 看起来像:
CREATE TABLE Posts(
ID timeuuid,
postYear int,
postMonth int,
postDay int,
postHour int,
title text,
contentURL text,
userID text,
PRIMARY KEY ((postYear, postMonth, postDay, postHour), ID)
) WITH CLUSTERING ORDER BY (ID DESC);
无论您使用哪种编程语言,都应该有一种方法可以从插入的时间生成 timeuuid
,然后从 timeuuid
值中提取该时间(如果您想在 UI 之类的。 (或者您可以使用 CQL timeuuid functions 进行转换。)
关于您关于查询多个分区的问题,是的,这样做完全没问题,但如果您不小心,可能 运行 会遇到麻烦。例如,如果有 48 小时没有 posts 会怎样?您是否必须发出 48 次 return 空结果的查询才能最终在第 49 次查询中得到一些结果? (这可能会非常缓慢并且用户体验糟糕。)
您可以采取一些措施来尝试缓解这种情况:
- 减少分区的粒度。例如,不要按小时执行 post 秒,而是 天 前 post 秒,或 月 post 秒。如果您知道这些分区不会变得太大(即用户不会创建太多 post 分区变得很大),那可能是最简单的解决方案。
创建第二个 table 以跟踪哪些分区实际上有 post。例如,如果您坚持按小时计算 posts,则可以像这样创建 table:
CREATE TABLE post_hours (
postYear int,
postMonth int,
postDay int,
postHour int,
PRIMARY KEY (postYear, postMonth, postDay, postHour)
);
然后,只要用户添加新的 post,您就可以插入此 table(使用 Batch)。然后,您可以在查询 Posts
table 之前查询 table first 以确定哪些分区具有 posts 并且应该是查询(从而避免查询一大堆空分区)。
我正在制作一个网站,我想将所有用户 post 存储在一个 table 中,按他们 post 的时间排序。我做的cassandra数据模型是这个
CREATE TABLE Posts(
ID uuid,
title text,
insertedTime timestamp,
postHour int,
contentURL text,
userID text,
PRIMARY KEY (postHour, insertedTime)
) WITH CLUSTERING ORDER BY (insertedTime DESC);
我面临的问题是,当用户访问 posts 页面时,它通过查询
获取最新的页面SELECT * FROM Posts WHERE postHour = ?;
? = 当前时间
到目前为止,当用户向下滚动时 ajax 请求从服务器获取更多 post。 Javascript 跟踪 lastFetched 项目的 post 小时,并在请求新的 posts 时与 cassandra PagingState 一起发回服务器。
但是当用户向下滚动时,这种方法将查询超过 1 个分区。 我想知道这个模型是否可以毫无问题地执行,是否有任何其他模型可以遵循。
有人请指点我正确的方向。 谢谢。
这是一个好的开始,但有几点建议:
您可能需要的不仅仅是
postHour
作为分区键。我猜您不希望将所有 post 不分日期 存储在一起,然后翻阅它们。你可能想看的是:PRIMARY KEY ((postYear, postMonth, postDay, postHour), insertedTime)
但是还是有问题。您的
PRIMARY KEY
必须唯一标识一行(在本例中为 post)。我猜测有可能,尽管不太可能,两个用户可能会使用相同的insertedTime
值创建 post。那么您真正需要的是添加ID
以确保它们是唯一的:PRIMARY KEY ((postYear, postMonth, postDay, postHour), insertedTime, ID)
在这一点上,我会考虑将您的
ID
和insertedTime
列合并为timeuuid
类型的单个ID
列。通过这些更改,您的最终 table 看起来像:CREATE TABLE Posts( ID timeuuid, postYear int, postMonth int, postDay int, postHour int, title text, contentURL text, userID text, PRIMARY KEY ((postYear, postMonth, postDay, postHour), ID) ) WITH CLUSTERING ORDER BY (ID DESC);
无论您使用哪种编程语言,都应该有一种方法可以从插入的时间生成
timeuuid
,然后从timeuuid
值中提取该时间(如果您想在 UI 之类的。 (或者您可以使用 CQL timeuuid functions 进行转换。)
关于您关于查询多个分区的问题,是的,这样做完全没问题,但如果您不小心,可能 运行 会遇到麻烦。例如,如果有 48 小时没有 posts 会怎样?您是否必须发出 48 次 return 空结果的查询才能最终在第 49 次查询中得到一些结果? (这可能会非常缓慢并且用户体验糟糕。)
您可以采取一些措施来尝试缓解这种情况:
- 减少分区的粒度。例如,不要按小时执行 post 秒,而是 天 前 post 秒,或 月 post 秒。如果您知道这些分区不会变得太大(即用户不会创建太多 post 分区变得很大),那可能是最简单的解决方案。
创建第二个 table 以跟踪哪些分区实际上有 post。例如,如果您坚持按小时计算 posts,则可以像这样创建 table:
CREATE TABLE post_hours ( postYear int, postMonth int, postDay int, postHour int, PRIMARY KEY (postYear, postMonth, postDay, postHour) );
然后,只要用户添加新的 post,您就可以插入此 table(使用 Batch)。然后,您可以在查询
Posts
table 之前查询 table first 以确定哪些分区具有 posts 并且应该是查询(从而避免查询一大堆空分区)。