摘要
CQL全称Cassandra Query Language是Cassandra 的查询语句,提供了一套类似于SQL的语法,因为长期以来关系型数据库都是主流的存储,并且无论是MySQL,SQL Server,还是Oracle,都提供了统一的一套查询语法SQL,所以为了适应开发者的习惯,帮助开发者能够平滑的迁移到Cassandra,Cassandra提供了一套类SQL的CQL实现
CQL相比较于SQL有很多的限制,比如不支持join,不支持子查询
原因在于cassandra是为大数据存储设计的,而它的部署模式又都是基于分区方式的,不像mongo还有复制集这个小规模的数据库集群设计,当数据量大的时候再进行分片。为了提供检索效率,所以在CQL语法上做了限制,避免低效的查询语句。cassandra的数据是根据partition key做hash计算后分布到各个节点的,扫描各个节点的效率是很低的。所以cassandra query检索的一个基本原则就是尽可能的查找少的节点。
Note:尽可能的查找少的节点是所有分布式集群都必须遵循的规范
CQL概览
CQL 语法操作手册:https://docs.datastax.com/en/cql/3.3/index.html
关系型数据库是行的集合,Cassandra是wide column的集合,即两级映射,一级key,一级是key value如果没有clustering key的话,每个分区就是单行,一个分区包含多行的话就叫做宽行(wide-row)。cassandra 根据partition key的hash value来决定数据存储在哪个节点,这个相当于是hash索引,所以不能进行范围查询。然后在每个分区根据clustering key来排序,这个不是基于hash的,所以可以根据范围来查询。以下表为例,node为partition key,(date,number)是clustering key.
CREATE KEYSPACE test WITH REPLICATION = { 'class': 'SimpleStrategy', 'replication_factor': 1 };
CREATE TABLE log(node text, date text, name text, number int, Primary Key(node,date,number));
在关系型数据库中数据是这么存储的
node date number name
n1 feb 1 name1
n1 feb 2 name2
n2 feb 1 name3
n2 feb 2 name4
而在cassandra则是
partition1
,
}
partition2
,
}
cassandra 的列不固定,所以列名也要存。
支不支持范围查询?
-IN操作
cassandra 2.2 以前IN只能用于partition key的最后一列,2.2之后改进了可以用于partition key的任意一列了。但是要注意IN操作的效率比较低,在摘要中已经说过了要尽可能的减少查询的节点,in操作会查询多个节点,如果设置了replicat factor为3的话,查询的节点数又会三倍增加。这样coordinate 节点的查询压力就会增加,需要保存各个节点的查询结果,就有可能会导致GC暂停,堆内存增加。
cassandra 3.0之后的IN支持在clustering key的列,不过如果是单列,必须要指定之前clustering key的值。(=或者IN)-范围查询>,
partition key
Cassandra是基于partition key的hash分步数据的,所以不支持范围查询。只允许在partition key的字段上面利用token函数来进行范围查询。
SELECT * FROM log WHERE token(node) > token('1')
注:分区器ByteOrderedPartitioner是有序分布数据的,所以理论上应该可以支持范围查询,但是使用这种分区器容易导致数据分布的不平衡,所以一搬不推荐使用
clustering key
单列的话,范围查询只能用于最后一列。前面的列必须要给定SELECT *FROM log WHERE node = '1' AND date >='date1'SELECT *FROM log WHERE node = '1' AND date = 'date' AND number >=1无效的就是这种
SELECT *FROM log where node = '1' AND number >= 1
总结
1.partition key是基于hash,不支持大于,小于这种范围查询,IN操作的是支持的。
2.clustering key是排序的,支持IN,大于小于查询。它相当于一个联合索引,所以要想让联合索引生效,得保证前面字段都有。
3.当没有给定partition key,而给定clustering key,需要扫描所有节点,然后进行过滤。所以执行效率可能比较低。所以Cassandra 要求使用ALLOW FILTERING。当过滤到的数据占查询的数据比例比较高的时候,还比较有效。
问题
问题1:where 语法中支不支持or
不支持,or 在SQL中一般是用来减少发到DB的请求。其中每个条件都构成了单个查询。Cassandra要求尽可能的减少请求节点,要求在每次查询时指定partition key,显然对于or这样多字段的条件,很难分析语境。
问题2:cassandra支不支持模糊查询
不支持LIKE操作,cassandra3.4以后可以使用,但是有很多限制。可以看下这篇文章介绍http://www.tsoft.se/wp/2016/08/12/sql-like-operation-in-cassandra-is-possible-in-v3-4/-
问题3: 一张表支持上千个字段吗
支持,对字段的数目没有限制,只有对一个paritition的cell数目有20亿的限制。所以列越多的话,相应的能够存储的行数就少了。
领取专属 10元无门槛券
私享最新 技术干货