cassandra高階操作之索引、排序以及分頁

weixin_30555753發表於2017-03-25

前言

  本次就給大家講講cassandra的高階操作:索引、排序和分頁;處於效能的考慮,cassandra對這些支援都比較簡單,所以我們不能希望cassandra完全適用於我們的邏輯,而是應該將我們的邏輯設計的更適合於cassandra

  路漫漫其修遠兮,吾將上下而求索!

  github:https://github.com/youzhibing

  碼雲(gitee):https://gitee.com/youzhibing

索引與排序

  Cassandra對查詢的支援很弱,只支援主鍵列及索引列的查詢,而且主鍵列還有各種限制,不過查詢弱歸弱,但它還是支援索引和排序的。

  cassandra的查詢約束

    第一主鍵 只能用=號查詢

    第二主鍵 支援= > < >= <=

    索引列 只支援=號

 

  索引查詢

    Cassandra支援建立二級索引,可以建立在除了第一主鍵(分割槽鍵:partition key)之外所有的列上;不同的cassandra版本對集合列的索引的支援也是不同的,有的支援有的不支援,大家可以去看下官方文件的Changes,2.1版本開始,可以建立集合索引

    建一張teacher表:

create table teacher(
    id int,
    address text,
    name text,
    age int,
    height int,
    primary key(id,address,name)
);

    向teacher表中插入資料:

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

    建索引

CREATE INDEX idx_teacher_age on teacher(age);

    索引列只可以用=號查詢,所以

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

           如果查詢條件裡,有一個是根據索引查詢,那其它非索引非主鍵欄位,可以通過加一個ALLOW FILTERING來過濾實現

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

           先根據age=32過濾出結果集,然後再對結果集進行height>30過濾

  排序

    建一張tt表:

create table tt(
    id int,
    address text,
    name text,
    age int,
    height int,
    primary key(id,address,name)
)WITH CLUSTERING ORDER BY(address DESC, name ASC);

    向tt表中插入資料:

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

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

      a、  必須有第一主鍵的=號查詢;cassandra的第一主鍵是決定記錄分佈在哪臺機器上,也就是說cassandra只支援單臺機器上的記錄排序。

      b、  只能根據第二、三、四…主鍵進行有序的,相同的排序。

        有序:order by後面只能是先二、再三、再四…這樣的順序,有四,前面必須有三;有三,前面必須有二,以此類推。

        相同的順序:參與排序的主鍵要麼與建表時指定的順序一致,要麼全部相反,具體會體現在下面的示例中

      c、  不能有索引查詢

    正確示例

SELECT * FROM teacher WHERE id=1 ORDER BY address ASC;
SELECT * FROM teacher WHERE id=1 ORDER BY address ASC, name ASC;
SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address ASC;
SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address ASC, name ASC;
SELECT * FROM teacher WHERE id=1 ORDER BY address DESC;
SELECT * FROM teacher WHERE id=1 ORDER BY address DESC, name DESC;
SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address DESC;
SELECT * FROM teacher WHERE id=1 AND address='guangxi' ORDER BY address DESC, name DESC;
SELECT * FROM tt WHERE id=1 ORDER BY address DESC;
SELECT * FROM tt WHERE id=1 ORDER BY address DESC, name ASC;
SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address DESC;
SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address DESC, name ASC;
SELECT * FROM tt WHERE id=1 ORDER BY address ASC;
SELECT * FROM tt WHERE id=1 ORDER BY address ASC, name DESC;
SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address ASC;
SELECT * FROM tt WHERE id=1 AND address='guangxi' ORDER BY address ASC, name DESC;

    錯誤示例

SELECT * FROM teacher ORDER BY address DESC;                        //沒有第一主鍵 不行
SELECT * FROM teacher WHERE id=1 ORDER BY name DESC;                //必須以第二主鍵開始排序
SELECT * FROM teacher WHERE id=1 ORDER BY address DESC, name ASC;   //不是與建表時指定的排序一致或者完全相反 (預設是address ASC, name ASC)
SELECT * FROM teacher WHERE age=1 ORDER BY address DESC;            //不能有索引
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的索引查詢和排序

轉載於:https://www.cnblogs.com/youzhibing/p/6617986.html

相關文章