CQL(Cassandra查询语言)可做的事情,不能做的事情

太长不看

    • CQLは一見SQLと同じ構文だが意外と実現できないことが多い

 

    制限をしっかり理解した上でCassandraを活用しよう

目标读者

    Cassandra導入を検討している方

首先

    • Cassandraへの問合せ言語であるCQLはSQLに似た文法を持っていますが、SQLでは当たり前に可能な問い合わせができないことに注意が必要です。安易にRDBMSからの移行ができると錯覚すると大変苦労する羽目になるでしょう。

 

    本稿では主にSQLとの違いにフォーカスしCQLのできること、できないことをまとめています。Cassandra導入を検討している方、機能検証を行っている方の一助となれば幸いです。

环境

    • 本稿は下記環境での検証に基づいて記載しています。

Cassandra 3.11.0.1855
CQL spec 3.4.4
cqlsh 5.0.1

前提的限制仅需一个选择

示例表格

    以降の説明で記載する条件句記述例は、下記のテーブル定義を前提とします。
カラム名データ型属性PKINTPartition KeyCK1INTClustering ColumnCK2INTClustering ColumnMAP1MAPEntry Index付与MAP2MAP
VALUE1TEXTSecondary Index付与VALUE2TEXT

选择

关于ALLOW FILTERING的一句话。

    • 複数のパーティションをまたぐ検索を実行するために必要となるオプションです。全行スキャンが走り大きく性能が劣化するリスクを伴います。ALLOW FILTERING句は実運用的には利用不可くらいの感覚で受け止めてください。

 

    またALLOW FILTERING不要なクエリが高速であるとは必ずしも限りません。本稿はCassandraの抽出クエリのリファレンシャルな情報を提供することを目的とするため詳細は割愛しますが、Cassandraの性能を万全に活かすためには内部構造を理解し、ノード間の物理的なI/Oを最小化するようなクエリ設計が必要となるでしょう。

不能做的事情 (Bù zuò de shì

    • まずはできないことをおさえておきましょう。CQLでは以下の構文は利用不可となっています。

条件句

!= (非等価)
NOT (論理否定)
OR (論理和)
IS NULL/ IS NOT NULL (NULL比較)

JOIN (結合)
OFFSET (相対位置指定)

可以做的事情

=(相等)

    原則どのカラムに対しても設定可能です。ただしPKを指定しない場合やINDEXが付与されていない列に対する等価条件にはALLOW FILTERING句を付与する必要がある点に注意が必要です。
条件句記述例ALLOW FILTERING備考where PK=1不要
where CK1=1要CK単独での条件のためALLOW FILTERINGが必要where PK=1 AND CK1=1不要PKが指定されているためALLOW FILTERINGは不要where CK2=1要
where PK=1 and CK2=1要
where PK=1 and CK1=1 and CK2=1不要複合CKの後方カラムを条件とする際にはPK,CK1をあわせて条件とすることでALLOW FILTERINGの付与を回避できるMAP1[‘key’]=’V’不要Entry Indexが付与されている列は単独カラムでの条件であってもALLOW FILTERINGが不要MAP1[‘key’]=’V’ and MAP1[‘keyX’]=’X’要Entry Indexが付与されていても条件を重ねるとALLOW FILTERINGが必要MAP2[‘key’]=’V’要
VALUE1=’VAL’不要Secondary Indexが付与されている列は単独カラムの条件であってもALLOW FILTERINGは不要VALUE2=’VAL’要

>,<,>=,<=(比较)

大于,小于,大于等于,小于等于(对比)

    • 等価とほぼ同様の操作が可能です。ただしCollection型に対する比較条件はサポートされていません。またCK列以外の比較条件にはALLOW FILTERINGオプションの付与が必要となります。

 

    概してCassandraは範囲検索を苦手としています。範囲取得が必要な際にはCK設計に留意してください。
条件句記述例ALLOW FILTERING備考where PK>1要
where CK1>1要
where PK>1 and CK1>1要
where PK=1 and CK1>1不要PKを指定した上でのCKの比較条件はALLOW FILTERINGが不要where CK2>1要
where PK=1 and CK2>1要
where PK=1 and CK1=1 and CK2>1不要複合CKの後方カラムではPK,CK1が特定された場合のみALLOW FILTERINGなしで比較条件が可能となるwhere VALUE1>’VAL’要
where PK=1 and VALUE1>’VAL’要
where PK=1 and CK1=1 and VALUE1>’V’要
where PK=1 and CK1=1 and CK2=1 and VALUE1>’V’要

    • in句はPK,CK列に対してのみ利用可能です。複合CKの場合にはさらに利用できる条件が厳しくなります。

 

    実行できないケースが若干わかりにくいため、下記テーブルには実行可否列を設け実行できないことを明示しています
条件句記述例実行可否ALLOW FILTERING備考where PK in (1,2,3)○不要
where CK1 in (1,2,3)○要
where PK=1 and CK1 in (1,2,3)○不要
where PK in (1,2,3) and CK1 in (1,2,3)○不要
where CK2 in (1,2,3)×n/a
where PK=1 and CK2 in (1,2,3)×n/a複合CKの後方カラムでin句を利用する際にはPK、および複合CK前方カラムの条件指定が必要となるwhere PK=1 and CK1=1 and CK2 in (1,2,3)○不要
where PK in (1,2,3) and CK1 in (1,2,3) and CK2 in (1,2,3)○不要

喜欢

    • CUSTOM INDEXを付与した列に対してのみ可能です。PK、CKにはCUSTOM INDEXを付与できないことに注意が必要です。

 

    CUSTOM INDEXをカラムVALUE2に付与する場合の例を以下に示します。
CREATE CUSTOM INDEX SAMPLE_IDX ON SAMPLE (VALUE2) USING 'org.apache.cassandra.index.sasi.SASIIndex' WITH OPTIONS = {'analyzer class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', 'case_sensitive': 'false', 'mode': 'CONTAINS', 'analyzed': 'true'};
条件句記述例ALLOW FILTERING備考where VALUE4 like ‘%VAL%’不要

按照顺序排列

    非常に限られた列に対してのみソート指定が可能です。PKが特定できること、かつCK(複合CKの場合は最前方カラム)であることがソート指定可能な列の条件となります。
条件句記述例実行可否備考order by PK×
order by CK1×
where PK=1 order by CK1○
where PK in (1,2,3) order by CK1○cqlshから実行の際にはpaging off;が必要ですorder by CK2×
where PK=1 order by CK2×
where PK=1 and CK1=1 order by CK2×

按组进行分组

    • CQLではPK列でのグループ化、PKを指定した上でのCK列でのグループ化をサポートしてます。

 

    また、標準集計関数として、min, max, avg, sum, countが使用可能です。
条件句記述例実行可否備考group by PK○
group by CK1×
where PK=1 group by CK1○
group by CK2×
where PK=1 group by CK2×
where PK=1 and CK1=1 group by CK2×

限制

    limit句による取得件数を指定した問い合わせが可能です。

最后

我已经简单总结了CQL的功能和限制,但似乎有一些暗示着高级用法的氛围…

在Cassandra中,除了主键(PK)和聚簇键(CK)之外的列不建议进行等值搜索,但在实际业务中可能会不得不对除了PK和CK列以外的列进行搜索。

请在理解查询表达式限制和使用ALLOW FILTERING的风险的基础上,努力在满足要求(性能、扩展性、可用性)的同时做出权衡。

广告
将在 10 秒后关闭
bannerAds