前言

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

  路漫漫其修远兮,吾将上下而求索!

  github:https://github.com/youzhibing

  码云(gitee):https://gitee.com/youzhibing

索引与排序

  Cassandra对查询的支持很弱,只支持主键列及索引列的查询,而且主键列还有各种限制,不过查询弱归弱,但它还是支持索引和排序的。

  cassandra的查询约束

    第一主键 只能用=号查询

    第二主键 支持= > < >= <=

    索引列 只支持=号

  索引查询

    Cassandra支持创建二级索引,可以创建在除了第一主键(分区键:partition key)之外所有的列上;不同的cassandra版本对集合列的索引的支持也是不同的,有的支持有的不支持,大家可以去看下官方文档的Changes,2.1版本开始,可以建立集合索引

    建一张teacher表:

  1. create table teacher(
  2. id int,
  3. address text,
  4. name text,
  5. age int,
  6. height int,
  7. primary key(id,address,name)
  8. );

    向teacher表中插入数据:

  1. insert into teacher(id,address,name,age,height) values(1,'guangdong','lixiao',32,172);
  2. insert into teacher(id,address,name,age,height) values(1,'guangxi','linzexu',68,178);
  3. insert into teacher(id,address,name,age,height) values(1,'guangxi','lihao',25,178);
  4. insert into teacher(id,address,name,age,height) values(2,'guangxi','lixiaolong',32,172);
  5. insert into teacher(id,address,name,age,height) values(2,'guangdong','lixiao',32,172);
  6. insert into teacher(id,address,name,age,height) values(2,'guangxi','linzexu',68,178);
  7. insert into teacher(id,address,name,age,height) values(2,'guangxi','lihao',25,178);
  8. insert into teacher(id,address,name,age,height) values(2,'guangxi','nnd',32,172);

    建索引

  1. CREATE INDEX idx_teacher_age on teacher(age);

    索引列只可以用=号查询,所以

  1. select * from teacher where age=32; //可以
  2. select * from teacher where age>32; //不行

如果查询条件里,有一个是根据索引查询,那其它非索引非主键字段,可以通过加一个ALLOW FILTERING来过滤实现

  1. select * from teacher where age=32 and height>30 ALLOW FILTERING;

先根据age=32过滤出结果集,然后再对结果集进行height>30过滤

  排序

    建一张tt表:

  1. create table tt(
  2. id int,
  3. address text,
  4. name text,
  5. age int,
  6. height int,
  7. primary key(id,address,name)
  8. )WITH CLUSTERING ORDER BY(address DESC, name ASC);

    向tt表中插入数据:

  1. insert into tt(id,address,name,age,height) values(1,'guangdong','lixiao',32,172);
  2. insert into tt(id,address,name,age,height) values(1,'guangxi','linzexu',68,178);
  3. insert into tt(id,address,name,age,height) values(1,'guangxi','lihao',25,178);
  4. insert into tt(id,address,name,age,height) values(2,'guangxi','lixiaolong',32,172);
  5. insert into tt(id,address,name,age,height) values(2,'guangdong','lixiao',32,172);
  6. insert into tt(id,address,name,age,height) values(2,'guangxi','linzexu',68,178);
  7. insert into tt(id,address,name,age,height) values(2,'guangxi','lihao',25,178);
  8. insert into tt(id,address,name,age,height) values(2,'guangxi','nnd',32,172);

    Cassandra支持排序,但也是限制重重

      a、  必须有第一主键的=号查询;cassandra的第一主键是决定记录分布在哪台机器上,也就是说cassandra只支持单台机器上的记录排序。

      b、  只能根据第二、三、四…主键进行有序的,相同的排序。

        有序:order by后面只能是先二、再三、再四…这样的顺序,有四,前面必须有三;有三,前面必须有二,以此类推。

        相同的顺序:参与排序的主键要么与建表时指定的顺序一致,要么全部相反,具体会体现在下面的示例中

      c、  不能有索引查询

    正确示例

  1. SELECT * FROM teacher WHERE id=1 ORDER BY address ASC;
  2. SELECT * FROM teacher WHERE id=1 ORDER BY address ASC, name ASC;
  3. SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address ASC;
  4. SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address ASC, name ASC;
  5. SELECT * FROM teacher WHERE id=1 ORDER BY address DESC;
  6. SELECT * FROM teacher WHERE id=1 ORDER BY address DESC, name DESC;
  7. SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address DESC;
  8. SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address DESC, name DESC;
  1. SELECT * FROM tt WHERE id=1 ORDER BY address DESC;
  2. SELECT * FROM tt WHERE id=1 ORDER BY address DESC, name ASC;
  3. SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address DESC;
  4. SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address DESC, name ASC;
  5. SELECT * FROM tt WHERE id=1 ORDER BY address ASC;
  6. SELECT * FROM tt WHERE id=1 ORDER BY address ASC, name DESC;
  7. SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address ASC;
  8. SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address ASC, name DESC;

    错误示例

  1. SELECT * FROM teacher ORDER BY address DESC; //没有第一主键 不行
  2. SELECT * FROM teacher WHERE id=1 ORDER BY name DESC; //必须以第二主键开始排序
  3. SELECT * FROM teacher WHERE id=1 ORDER BY address DESC, name ASC; //不是与建表时指定的排序一致或者完全相反 (默认是address ASC, name ASC)
  4. SELECT * FROM teacher WHERE age=1 ORDER BY address DESC; //不能有索引
  5. SELECT * FROM tt WHERE id=1 ORDER BY address DESC, name DESC; //不是与建表时指定的排序一致或者完全相反 (建表时指定了address DESC, name ASC)

    其实cassandra的任何查询,最后的结果都是有序的,默认与建表时指定的排序规则一致(例如teacher表是address ASC,name ASC,而tt表则是address DESC,name ASC),因为它内部就是这样存储的。所以你对teacher表使用address DESC, name ASC 或者address ASC,name DESC排序,对tt表使用address DESC, name DESC 或者address ASC,name ASC排序,cassandra都是比较为难的。

    当然这个默认存储排序方式,是可以在建表的时候指定的,就想tt表那样。

分页查询

  一说分页,我很容易就想到了mysql中的limit,恰巧cassandra也是用它来实现分页的,但是cassandra的limit没有mysql的那么强大,它只能限制查询结果的条数,而不能指定从哪里开始,那么问题就来了:cassandra到底要怎么实现分页了?

  上面我们已经分析了,要实现分页还差一个条件:起始点;cassandra中通过token函数来确定起始点,具体这个token函数是干嘛的,大家自行去补脑。接下来我直接看例子,看完例子,相信大家会对token有一定的认知了。

  先看下teacher表中的全部数据:

  一共8条数据,那么我们就按一页2条记录(pageSize=2)来查出全部数据

  第一次查询

    起始查询比较好理解:select * from teacher limit 2;结果如下:

    此时,需要将上面查询得到的结果的最后一条记录的主键id,address,name的值记录1,guagnxi,lihao记录下来,下次查询需要用到

  第二次查询

    select * from teacher where token(id)=token(1) and (address,name)>('guangxi','lihao') limit 2 ALLOW FILTERING; 结果如下:

    只查询出了1条记录,不够2条,继续查询,这时语句应该这么写:select * from teacher where token(id)>token(1) limit 1;结果如下:

  将2,guangdong,lixiao记录下来,供下次查询用

  后续查询

    和第二次查询一样,先查询token(id)相等(where token(id)=token(1)),直到出现查询的记录数小于pageSize,再查询token(id)大的(token(id)>token(1))

  总结

    1、第一次查询,得到的记录数若小于pageSize,那么就说明后面没数据,若等于pageSize,那就不知道是否还有数据,则需要进行第二次查询。

    2、第二次查询,先从token(id)=开始查,若在token(id)=的查询中出现记录数(searchedCounts)小于pageSize,则转向token(id)>的开始查,若token(id)>的查询记录数小于(pageSize – searchedCounts),那么就说明没有数据了,若token(id)>的查询记录数等于(pageSize – searchedCounts),那么重复第二次查询。

    综上所述,知道后面没有数据的点只有两个,1、第一次查询的时候;2、token(id)>的时候,其他时候都不能断定后面没有数据

    cassandra 的分页查询,主要是通过查询结果的默认的排列顺序来实现的,本文的例子是没有查询条件的情况,有查询条件的情况,也是一样的。你只要知道了cassandra的默认查询结果的排序规则,就知道如何具体的分页查询了,默认排序在建表的时候是可以指定的,就想tt表那样,对tt的分页查询我就不演示了,希望大家自己去实现tt表的分页查询,里面有很多有趣的东西哦! tt表的默认排序规则与teacher表是不同的,那么tt表的分页与teacher表是有区别的!

参考

  cassandra2.0 如何实现分页查询

  cassandra的索引查询和排序

cassandra高级操作之索引、排序以及分页的更多相关文章

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

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

  2. cassandra高级操作之JMX操作

    需求场景 项目中有这么个需求:统计集群中各个节点的数据量存储大小,不是记录数. 一开始有点无头绪,后面查看cassandra官方文档看到Monitoring章节,里面说到:Cassandra中的指标使 ...

  3. Gridview排序与分页-不使用“DataSourceControl DataSource”的情况下如何分页和排序 ...

    如果你在GridView控件上设置 AllowPaging="true" or AllowSorting="true" 而没有使用使用数据源控件 DataSou ...

  4. Mysql高级操作学习笔记:索引结构、树的区别、索引优缺点、创建索引原则(我们对哪种数据创建索引)、索引分类、Sql性能分析、索引使用、索引失效、索引设计原则

    Mysql高级操作 索引概述: 索引是高效获取数据的数据结构 索引结构: B+Tree() Hash(不支持范围查询,精准匹配效率极高) 树的区别: 二叉树:可能产生不平衡,顺序数据可能会出现链表结构 ...

  5. 两行代码玩转Spring Data排序和分页

    一:唠嗑 在实际项目中对Spring Data的各种使用相当多,简单的增删改查Spring Data提供了现成的方法,一些复杂的,我们可以在接口方法写And,Not等关键字来搞定,想写原生SQL,CQ ...

  6. 使用solrj操作solr索引库,solr是lucene服务器

    客户端开发 Solrj 客户端开发 Solrj Solr是搭建好的lucene服务器 当然不可能完全满足一般的业务需求 可能 要针对各种的架构和业务调整 这里就需要用到Solrj了 Solrj是Sol ...

  7. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第五章:排序、分页和路由

    本章的重点是对产品信息增加排序和分页的功能,以及使用ASP.NET Routing特性添加更加友好的URL支持. 注意:如果你想按照本章的代码编写示例,你必须完成第四章或者直接从www.apress. ...

  8. MySQL学习笔记_9_MySQL高级操作(上)

    MySQL高级操作(上) 一.MySQL表复制 create table t2 like t1;               #复制表结构,t2可以学习到t1所有的表结构 insert into t2 ...

  9. python列表(list)的使用技巧及高级操作

    python列表(list)的使用技巧及高级操作置顶 2018年03月25日 13:39:41 顽劣的石头 阅读数:5478 标签: python extend bisect list enumera ...

随机推荐

  1. 使用python制作ArcGIS插件(3)ArcPy的使用说明

    使用python制作ArcGIS插件(3)ArcPy的使用说明 by 李远祥 ArcPy 是一个以成功的 arcgisscripting 模块为基础并继承了 arcgisscripting 功能进而构 ...

  2. 循环语句——for语句

    一.for语句结构:for (初始化表达式; 循环条件表达式 ;循环后的操作表达式 ) { 执行语句: } 循环条件表达式,必须是true或false 示例: class ForDemo { publ ...

  3. 私有成员的设置和访问方式——set()和get()方法

    在定义类时,为了保证类中成员数据安全性及的封装性,防止成员数据值被任意修改,通常将类中成员属性用private进行修饰. 被private所修改的成员变量,只能在类中访问,跳出本类中,就无法直接访问. ...

  4. 在vim中搜索单词

    基本的搜索: /pattern    向前搜索 ?pattern   向后搜索 n               向前重复搜索 N               向后重复搜索 搜索并替换 :%s/sear ...

  5. Android Weekly Notes Issue #245

    Android Weekly Issue #245 February 19th, 2017 Android Weekly Issue #245 本期内容: 写好单元测试的几条原则; 如何mock Ko ...

  6. iptables禁止ping入

    iptables禁止ping入 以下设置将允许自己往外ping 不允许别人ping自己 vi /etc/sysconfig/iptables 加入如下2条规则 -A INPUT -p icmp --i ...

  7. JLOI2015 解题报告

    JLOI2015 真的不愧是NOI出题组出的,题目难度够吊.不过每一道都是结论题和乱搞题真的很不好玩... T1:[JLOI2015]有意义的字符串 首先贴下popoqqq的blog吧 感性的认识就是 ...

  8. Codeforce 水题报告

    最近做了好多CF的题的说,很多cf的题都很有启发性觉得很有必要总结一下,再加上上次写题解因为太简单被老师骂了,所以这次决定总结一下,也发表一下停课一星期的感想= = Codeforces 261E M ...

  9. JVM 堆和栈的区别

      栈内存:   程序在栈内存中运行   栈中存的是基本数据类型和堆中对象的引用   栈是运行时的单元   栈解决程序的运行问题,即程序如何执行,或者说如何处理数据   一个线程一个独立的线程栈   ...

  10. angular : ui-router 操作原理

    <body> <a ui-sref="title">title<a> </body> ui-router 会去解析body里的ui- ...