备案 控制台
学习
实践
活动
专区
工具
TVP
写文章

Cassandra系列(2)-Cql

摘要

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亿的限制。所以列越多的话,相应的能够存储的行数就少了。

  • 发表于:
  • 原文链接 http://kuaibao.qq.com/s/20180202G1DF3W00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据 《腾讯内容开放平台服务协议》 转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

关注

腾讯云 开发者 公众号
10元无门槛代金券
洞察腾讯核心技术
剖析业界实践案例
腾讯云开发者公众号二维码

扫码关注腾讯云开发者

领取腾讯云代金券