Cassandra数据建模需求:获取从未成功完成任务的章节编号
找出从未成功完成任务的章节编号(Cassandra实现)
嘿,针对你的需求,我整理了几个在Cassandra里实现的方案,你可以根据数据规模和查询频率来选择最适合的:
核心思路
我们的目标是筛选出没有任何result='successful'记录的section。Cassandra的查询模型是主键驱动的,所以直接做全局排除查询需要点技巧,下面是具体方法:
方法1:用聚合函数一步到位(Cassandra 3.8+适用)
如果你的Cassandra版本在3.8及以上,可以用GROUP BY结合条件聚合来直接筛选:
SELECT section FROM SAMPLE.ALERTS GROUP BY section HAVING COUNT(CASE WHEN result = 'successful' THEN 1 END) = 0;
原理:
CASE语句会给每条成功记录标记1,非成功的记录返回NULLCOUNT()只会统计非NULL的值,所以当计数为0时,就说明这个章节从来没有成功过- 注意:如果你的数据分布在多个
job_id分区里,执行这个查询可能需要加上ALLOW FILTERING,但生产环境数据量大的话不建议这么做——全表扫描性能会很差。
方法2:分两步查询(生产环境推荐)
为了避免全表扫描的性能问题,可以拆成两个查询,在应用层做过滤:
- 先拿到所有有过成功记录的章节:
SELECT DISTINCT section FROM SAMPLE.ALERTS WHERE result = 'successful';
- 再拿到所有存在的章节:
SELECT DISTINCT section FROM SAMPLE.ALERTS;
最后在你的应用代码里,把第二个结果里属于第一个集合的章节去掉,剩下的就是从未成功的章节。这种方式性能更可控,适合数据量大的场景。
方法3:创建物化视图(频繁查询场景首选)
如果这个查询你需要经常执行,不如提前建一个物化视图来缓存统计结果:
CREATE MATERIALIZED VIEW SAMPLE.SECTION_SUCCESS_SUMMARY AS SELECT section, COUNT(CASE WHEN result = 'successful' THEN 1 END) AS success_count FROM SAMPLE.ALERTS GROUP BY section;
之后查询就快多了,直接从物化视图里捞结果:
SELECT section FROM SAMPLE.SECTION_SUCCESS_SUMMARY WHERE success_count = 0;
物化视图会自动同步原表的数据更新,适合查询频繁、数据更新不算特别频繁的场景。
内容的提问来源于stack exchange,提问作者theone
相关产品推荐
相关产品推荐

