我们与Cassandra的使用案例是显示博客帖子的前10位最近访问者。以下是Cassandra表定义
CREATE TABLE blogs_by_visitor (
blogposturl text,
visitor text,
visited_ts timestamp,
PRIMARY KEY (blogposturl, visitor)
);
现在,为了显示给定博客帖子的前10位访问者,需要有一个明确的"顺序"关于时间戳的条款。由于visted_ts不是Cassandra中聚类列的一部分,因此我们无法完成此操作。 visit_ts不属于群集列的原因是为了避免记录重复(读取为重复)访问者。主键的设计方式是为重复访问者设置最新时间戳。
在RDBMS世界中,查询看起来如下所示,可以使用blogposturl和timestamp列创建辅助索引。
Select visitor from blog_table
where
blogposturl = ?
and rownum <= 10
order by timestamp desc
我们的Cassandra应用程序当前正在遵循的另一种方法是获取结果,然后根据应用程序端的时间戳进行排序。但是,如果一个特定的博客文章变得如此受欢迎并且它拥有超过100,000名访问者,该怎么办这些博客的查询变得非常慢。
我认为二级索引在这里不会有用,因为我不担心过滤它(而只是为了排序 - 这是不可能的)。
关于我们如何以不同方式对表进行建模的任何想法?
实际表中有其他列,为简单起见,将其简化为
答案 0 :(得分:2)
这些类型的工作由Apache Spark或Hadoop完成。一个计划作业,按时间戳计算每个URL的唯一访问者顺序,并将结果存储到cassandra中。
或者您可以在blogs_by_visitor
之上创建Materialized View。此表格将确保唯一身份访问者,实体化视图将根据visited_ts
时间戳记显示结果。
让我们创建物化视图:
CREATE MATERIALIZED VIEW unique_visitor AS
SELECT *
FROM blogs_by_visitor
WHERE blogposturl IS NOT NULL AND visitor IS NOT NULL AND visited_ts IS NOT NULL
PRIMARY KEY (blogposturl, visited_ts, visitor)
WITH CLUSTERING ORDER BY (visited_ts DESC, visitor ASC);
现在,您只需选择博客帖子中最近的10位唯一身份访问者。
SELECT * FROM unique_visitor WHERE blogposturl = ? LIMIT 10;
你可以看到我没有在select查询中指定排序顺序。因为在物化视图架构中,a指定了默认排序顺序visited_ts DESC
注意:以上架构将在物化视图中产生大量意外的墓碑生成
或者您可以像下面那样更改表格schmea:
CREATE TABLE blogs_by_visitor (
blogposturl text,
year int,
month int,
day int,
visitor text,
visited_ts timestamp,
PRIMARY KEY ((blogposturl, year, month, day), visitor)
);
现在,您在单个分区中只有少量数据。因此,您可以根据客户端的单个分区中的visited_ts
对所有访问者进行排序。如果您认为一天中的访问者数量可能很大,那么也可以在分区键中添加小时数。