瀑布式分页

如果你的应用只需要瀑布式的分页,那么,Cassandra可以很好的支持,不过记得要指定好排序顺序。

CLUSTERING ORDER BY (add_time DESC);

常见的分页,跳页问题

许多产品喜欢设计可以跳页的分页逻辑比如下面这种

首页 1 2 3 4 5 下一页 GO [ ] 页

由于Cassandra不支持类似mysql的 "Limit start,length" 也没有其他数据库的 "top + 子查询",遇到这种需求的时候,非常不方便。

这里提供一种有限的解决方案,可以一定程度上缓解需求矛盾,在Cassandra更加成熟之前,提供过渡。

具体思路

类似mysql的Limit start,length操作,

Mysql需要先扫描0 - start 的所有记录,然后从start开始,取length条数据。这也是Mysql在分页操作的时候的慢查询问题之一。

假设我们有一个表像下面这样,一个好友表,按添加时间逆序排序

CREATE TABLE friend(
user_id int,
friend_id int,
add_time bigint,
PRIMARY KEY (user_id,add_time)
)
WITH compaction = {'class':'LeveledCompactionStrategy'}
AND CLUSTERING ORDER BY (add_time DESC);

假设我们的分页是每页10个用户,如果要查询第二页好友,首先查出1 - 10用户的add_time,然后

--首先,只查询add_time 字段,获取偏移量
select add_time from friend where user_id = 10 limit 10;
--然后,用偏移量查询第二页
select * from friend where user_id = 10 and add_time < 第10个用户的add_time limit 10;

以上就是基本的思路。

如果用户选择跳到第10页,那么需要取limit 90的数据,获取第90条数据的偏移量,查询90 - 100的数据。

优化

优化的方案是有缺陷的,需要增加额外的cql,如果这是一个被频繁查询的业务,还是值得。

优化的思路

  1. 如果你查出了第5页,如果用户紧接着点击第6页(或者点击了下一页),直接使用第五页已经查出的数据的最后一条作为偏移量查询第6页,这一点和瀑布分页一样。
  2. 如果你查出了第5页,并且将第5页分页偏移量缓存在一张分页表中,如果用户要查第10页的时候,你只需要查询5 - 9页的数据,就可以知道第10页的偏移量,同时你也得到了5 - 9页的分页信息,

    缓存6 - 10 页的数据(第5页假设已经缓存过了),那么用户继续点击6 - 9 页的任何数据,都可以直接取到。
  3. 担心分页缓存的一致性问题,可以使用using ttl 关键字给分页缓存设置过期时间,使得分页缓存会定期重建,新增的数据最坏情况是堆积在第一页,而不会查不出来。
--分页缓存表的样例
CREATE TABLE forums.page_cache (
page_key text,
page_num int,
page_offset bigint,
PRIMARY KEY (page_key, page_num)
)

潜在问题

用户可能自己修改URL参数,显然你的url可能需要类似这样

index?page=3&offset=12034

你需要2个参数才能正常工作

一种可行的方案是使用base64重新编码参数,使其保持只有一个

index?page=AAG352F3

一方面用户只会修改page,另一方面有些用户可能会因为不知道怎么改而放弃,不过这么做的用户应该数量不多。

有关优化为什么不把前后两页都优化了?

  1. 按照上面介绍的优化方案,如果你查了第5页,那么1-5页的缓存肯定都已经完成了,如果要查询第4页,偏移量已经在那。
  2. 在Cassandra并非所有的查询条件都支持order by,如果使用非主键索引,就无法进行order by 操作,也就无法通过第5页查询第4页。

Cassandra 有限分页策略的更多相关文章

  1. Cassandra 的压缩策略STCS,LCS 和 DTCS

    更新说明: 本文编写时最新的Cassandra版本为2.2,最新的稳定版本为2.1.8 2016年6月23日,增加一篇译文,当下最新版本为3.7 最新的Cassandra 2.1 或者更高的版本支持3 ...

  2. Scrapy 教程(五)-分页策略

    scrapy 爬取分页网站的策略 1. 检测当前页是否存在“下一页” 2. 如果存在,把“下一页”的链接交给本方法或者其他方法 3. 如果不存在,结束 图示 示例代码 def parse(self, ...

  3. Mysql优化-大数据量下的分页策略

    一.前言 通常,我们分页时怎么实现呢? 1 SELECT * FROM table ORDER BY id LIMIT 1000, 10; 但是,数据量猛增以后呢? 1 SELECT * FROM t ...

  4. cassandra高级操作之分页的java实现(有项目具体需求)

    接着上篇博客,我们来谈谈java操作cassandra分页,需要注意的是这个分页与我们平时所做的页面分页是不同的,具体有啥不同,大家耐着性子往下看. 上篇博客讲到了cassandra的分页,相信大家会 ...

  5. cassandra高级操作之索引、排序以及分页

    本次就给大家讲讲cassandra的高级操作:索引.排序和分页:处于性能的考虑,cassandra对这些支持都比较简单,所以我们不能希望cassandra完全适用于我们的逻辑,而是应该将我们的逻辑设计 ...

  6. cassandra 3.x官方文档(7)---内部原理之如何读写数据

    写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...

  7. Bootstraptable源码

    // @author 文志新 http://jsfiddle.net/wenyi/47nz7ez9/3/ /**关于插件的通用构造 * * 构造函数PluginName($trigger,option ...

  8. oracle 学习笔记(四)

    1. SQL(高级查询) 1.1. 子查询 1.1.1. 子查询在WHERE子句中 在SELECT查询中,在WHERE查询条件中的限制条件不是一个确定的值,而是来自于另外一个查询的结果.为了给查询提供 ...

  9. [Architecture] 系统架构正交分解法

    [Architecture] 系统架构正交分解法 前言 随着企业成长,支持企业业务的软件,也会越来越庞大与复杂.当系统复杂到一定程度,开发人员会发现很多系统架构的设计细节,很难有条理.有组织的用一张大 ...

随机推荐

  1. How to make 9-patch image downloaded from the Network

    Probably everyone, who is in touch with the Android world dealt with 9-patch term. It is an image in ...

  2. 【原】linux系统运维工具必备

    操作系统:CentOS※,Ubuntu 网站服务:apache,nginx※,tomcat,tengine 开发语言:php,python※,shell※ 数据库 :Mysql※ 代理相关:lvs,k ...

  3. Fragment和Activity的区别

    Fragment用来描述一些行为或一部分用户界面在一个Activity中,可以合并多个Fragment在一个单独的Activity中建立多个UI面板,同时重用Fragment在多个activity中. ...

  4. 502 Bad Gateway什么意思

    http://baike.baidu.com/link?url=U2ijg5T5PG_tTkY67mqfx07co7qGqvMB32rbLwq4S2ThBSRIWWvU76Y0Mb8Z3z6nbViN ...

  5. oracle 事务测试

    此文章是根据官方改变 模拟帐户转账流程 1.JOHN帐户扣除-DAVID帐户增加-记录日志-事务提交 三个操作必须全部完成此事务才完成,否则失败 创建帐户余额表自增字段自增序列:    ; 创建支票表 ...

  6. 转载:Cocos2D-x 游戏接入 Windows 设备所需做的六件事

    原文地址:http://msopentech.com/zh-hans/blog/2014/05/09/cocos2d-x-%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%85%A5-wi ...

  7. C# OpenFileDialog

    OpenFileDialog 用于浏览并打开文件,在Windows Forms中使用,表现为标准的Windows对话框. 实例: 1.新建Windows Form Application 2.添加Op ...

  8. Linux系统自启动脚本

    只需编辑/etc/init.d/rc.local文件,在最后加上你的脚本即可.比如:我已经编写了一个脚本shell.sh,存放在/home/mars704/Desktop/ 下面在终端输入 gedit ...

  9. CODESOFT中怎样打印数据库中的特定数据?

      CODESOFT可用于打印.标记和跟踪的零售库存标签软件,每种产品的售卖都代表着需要打印大量的条码标签.通常我们采用的方法就是在CODESOFT连接数据库批量打 印.但是如果数据量很大,该如何选择 ...

  10. 【CImg】简单的畸变矩形矫正

    三个角点确定一个平面,畸变的平面可以看成是不同基底下同一图像的表示 ============================我是分割线============================= 1. ...