问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

深入理解CQL中的Where子句

发布网友 发布时间:2022-09-05 01:12

我来回答

1个回答

热心网友 时间:2023-10-03 16:53

虽然CQL和SQL他们之间有很多的不同,但是他们也有很多相类似的语法。造成这些差异的原因主要来自于Cassandra处理分布式数据并旨在防止低效查询的事实。

其中CQL与SQL一个很大不同的地方在于他们的where子句。本文的目的就是描述CQL WHERE子句所支持的内容以及与普通SQL不同的原因。

主键列

在Cassandra数据中,主键列有两种数据类型组成而且他们有着特殊的意义:分区键列(the partition key columns )和集群列(the clustering columns)。他们两组合在一起

就确定了你每行的主键(相当于mysql的主键一样)。

分区键(partition key)列是主键的第一部分,其作用是将数据均匀地分布在集群中。行将依据分区键(partition key)的hash值分布在集群周围(注:说白了就是每行的数据放在集群的哪台机器是根据partition key进行hash计算来决定的)。

聚簇列(the clustering columns)通常用于聚集分区的数据,从而可以非常有效地检索行。

由于它们扮演的角色不同,分区键,clustering和普通列在WHERE子句使用中有着不同的*。而且,这些*条件根据查询类型而不同:比如SELECT,UPDATE或DELETE。

SELECT语句的WHERE子句*

分区键key的*

分区键列仅支持两个运算符:=和IN

IN的使用*

在2.2版本之前,IN只能应用到分区键的最后一个列。所以,比如,如果你的表是下面这样的话:

CREATE TABLE numberOfRequests (

cluster text,

date text,

time text,

numberOfRequests int,

PRIMARY KEY ((cluster, date), time)

)

在2.1版本中,您只能在date这列上使用IN运算符。在2.2版本中,你可以在分区键列中的任何列中使用IN运算符.

最后,你的查询会像这样子:

SELECT * FROM numberOfRequests

WHERE cluster IN ('cluster1', 'cluster2')

AND date = '2015-05-06'

AND time >= '12:00'

AND time <= '14:00';

这个查询从2.2版本开始是正确的,但是在之前的版本是错误的。

这个更新使CQL更统一了,但是你还是应该小心在分区键列使用IN运算符的*。 Ryan Svihla的好文章会给你一个清晰的解释,告诉你为什么要尽量避免它们。

2.2版本引入的另一个变化是操作结果不会按IN子句指定的分区键顺序返回。从2.2版本开始,操作结果以列类型的自然顺序返回而且重复值被忽略。

无*的分区键列

Cassandra要求您要么*所有分区键列要么一点都不*,除非你的查询可以使用二级索引。

这意味着这个查询像这样子的:

SELECT * FROM numberOfRequests WHERE cluster='cluster1' AND time ='12:00';

这个查询将会拒绝因为date这列是不受*的。

之所以这样,是因为Cassandra需要所有的分区键列才能够计算散列,以便它能够定位包含该分区的节点。

如果没有在分区键上指定*条件,但在集群键上指定了某些*条件,则Cassandra将要求ALLOW FILTERING被添加到查询中。有关ALLOW FILTERING的更多信息,您应该查看ALLOW FILTERING的解释。

Cassandra distributes the partition accross the nodes using the selected partitioner .由于只有ByteOrderedPartitioner保持数据的有序分布,所以Cassandra不直接在分区键上支持>,> =,<=和<运算符。

然而,它允许您通过使用标记功能(token function)在分区键上使用>,>,<=和<运算符。

SELECT * FROM numberOfRequests

如果使用ByteOrderedPartitioner,则可以在多个分区上执行一些范围查询。你应该小心,不建议使用ByteOrderedPartitioner,因为它可能会导致群集不平衡。

Clustering column的*

Clustering column支持单列的=,IN,>,> =,<=,<,CONTAINS和CONTAINS KEY运算符以及多列的=,IN,>,> =,<=和<运算符。

clustering columns的无*

clustering columns的作用是对分区内的数据进行群集。如果你有下面的表格:

CREATE TABLE numberOfRequests (

数据将按以下方式存储在每个分区中:

{datacenter: US_WEST_COAST {hour: 0 {minute: 0 {numberOfRequests: 130}} {minute: 1 {numberOfRequests: 125}} … {minute: 59 {numberOfRequests: 97}}} {hour: 1 {minute: 0 …

您可以看到,为了在没有二级索引的情况下以有效的方式检索数据,你需要知道你选择的所有集群键列。

所以,如果你执行下面语句:

SELECT * FROM numberOfRequests

Cassandra将高效的找到上面所查询的数据,但是如果你执行的语句是下面这样的:

SELECT * FROM numberOfRequests

Cassandra会拒绝上面这条语句的查询,因为它必须扫描整个分区才能找到请求的数据,效率不高(注:其实就是clustering key只能从左向右加条件且中间不能断,你可以只用给datacenter = 'US_WEST_COAST' 条件,hour和minute不给,但是你不能使用了minute字段但是没hour字段的查询)。

IN在Clustering column中的*

在2.2版本之前,只有最后一个集群列(clustering columns)允许对集群列进行IN*。在2.2中,IN*可以用于任何列,下面的查询将起作用:

SELECT * FROM numberOfRequests

通过使用多列IN*( multi-column IN restriction ),可以在2.2版本之前检索相同的一组数据:

SELECT * FROM numberOfRequests

在2.2中,多列IN*可以应用于任何一组集群列。

SELECT * FROM numberOfRequests

在2.2之前,多列IN*只能应用于最后一组被*的集群列。结果,以前的查询在2.1中是无效的。但是下面的查询是完全有效的。

SELECT * FROM numberOfRequests

单列在执行范围查询的时候只能出现在查询条件的最后一栏。

因此,下面的查询是正确的:

SELECT * FROM numberOfRequests

SELECT * FROM numberOfRequests

SELECT * FROM numberOfRequests

但是下面这条语句是不正确的:

SELECT * FROM numberOfRequests

多列范围查询的时候最一组clustering columns的*。

SELECT * FROM numberOfRequests

如果你的查询是多列分片且后面一组是第一组列的子集,那么第二组的查询的列必须以第一组的第一列打头,如下面的列子:

SELECT * FROM numberOfRequests

这条语句是正确的,但是下面这条是错误的:

SELECT * FROM numberOfRequests

CONTAINS 和CONTAINS KEY 的使用*

CONTAINS和CONTAINS KEY*只能在查询使用二级索引时用于集合。

二级索引查询

对二级索引的直接查询只支持=,CONTAINS或CONTAINS KEY。

CONTAINS只能用于集合类型。 CONTAINS KEY只能用于map集合且map的key是建立了index的。

例如,你如果有这样的table:

CREATE TABLE contacts (

);

CREATE INDEX ON contacts (firstName);

CREATE INDEX ON contacts (keys(phones)); // Using the keys function to index the map keys

CREATE INDEX ON contacts (emails);

接下来的查询是生效的:

SELECT * FROM contacts WHERE firstname = 'Benjamin';

SELECT * FROM contacts WHERE phones CONTAINS KEY 'office';

SELECT * FROM contacts WHERE emails CONTAINS ' Benjamin@oops.com ';

二级索引过滤器

二级索引查询允许您使用过滤在非索引列上使用=,>,> =,<=和<,CONTAINS和CONTAINS KEY来查询返回的结果。

因此,下面的查询是有效的,只要指定了ALLOW FILTERING:

SELECT * FROM contacts

SELECT * FROM contacts

WHERE phones CONTAINS KEY 'office'

AND phones CONTAINS '0000.0000.0000'

ALLOW FILTERING;

你应该谨慎的使用filtering,因为这操作代价很高。

分区键上的二级索引*

当Cassandra必须执行二级索引查询时,它将联系所有节点以检查位于每个节点上的二级索引的部分。如果所有分区键组件都受到*,则Cassandra将使用该信息只查询包含指定分区键的节点,这将使查询更高效。

对于二级索引查询,分区键列上只支持=操作。

Clustering column restrictions and Secondary indices

对于每个索引值,Cassandra存储了整个主键(分区键列+集群列)的每一行包含值。当执行索引查询时,Casssandra将从索引中检索包含该值的行的主键。然后它将从表中检索行并执行所需的任何过滤。

如果第一个Clustering column已经被*,Cassandra将对索引返回的主键执行一个过滤,使得过滤效率更高。

对于这种类型的过滤,Cassandra的 Clustering column将接受以下操作:=,IN,>,> =,<=和<。

所以,如果我们将以下二级索引添加到numberOfRequests表中:

CREATE INDEX ON numberOfRequests (minute);

他下面的查询是完全有效的:

SELECT * FROM numberOfRequests

WHERE子句对UPDATE和DELETE语句的*

在UPDATE和DELETE语句中,所有主键列都必须受到*,唯一允许的*是:

1. 单列情况 = 可以作用在任何分区键或集群列上

2.单列IN 在最后一个分区键列上的*
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
国家对腾讯已经作出解除音乐版权处罚,为什么网易云还是很 市场监管总局依法对腾讯控股有限公司作出责令解除网络音乐 腾讯放弃音乐独家版权,绝大部分独家协议已按期解约 高级BEC和中级口译哪个难? 三级口译是什么样的水平 高级日语口译大概是什么水平 高级口译常用谚语 品牌型号怎么填写 送刀剑是什么风水 送礼送菜刀是什么意思 cpda项目数据分析师与cda数据分析师的区别 风水问题:办公室想放一些手办公仔,但又怕招小人,请问真的会吗?怎么破... 中原工学院宿舍条件,宿舍环境图片(10篇) 中原工学院好吗 中原工学院邮编 附地址和介绍 大家谁能告诉我,一点灵护发素,是什么成分啊 关于雨的牵动情感的诗句(关于雨的诗句及表达的情感) 雨思念的诗句原创 网络被禁用了怎么办?求详细步骤 电脑上软件被禁用了网络怎么恢复 ...怎么画眼妆啊?因为眼皮摺会折进去,连睫毛也遮住不少。 ...怎么画眼线阿?!!! 一睁眼上眼皮把睫毛盖住一半,我哭啊... ...当地的荔枝现在卖什么价啦?我看到我楼下水果店卖的十元一斤。_百度... 广西合浦适合种那个品种的山竹果 除了合浦珍珠,还盛产这些宝玉石...宝藏广西终于藏不住了 合浦果香园食品有限公司怎么样? 合浦山口镇有水果批发吗? 奇瑞qq3手动后视镜为什么不能折叠 新税法折旧年限 环保设备的折旧年限? 洒水车十年后是半年年检吗 东奥换设备需要重新刷脸吗 酷狗下载mp3的歌曲怎么转格式啊? 3p空调多少钱?家用空调怎么选购? 在ppt中怎样插入PDF格式的图片? 想问下苹果手机使用小影软件怎么添加本地曲库的音乐呢 北京东城算市中心吗 关于《醉玲珑》结局和剧情问题,有知道的吗? 宏碁投影机p1203开机图像有花点 爱普生EB-X7和宏基X1230P哪个好 换个宏基投影机X1230P的DMD模板多少钱? 八个月宝宝吸收不好怎么办 儿童吸收功能差怎么办 1岁多宝宝肠胃吸收不好怎么调理啊? 电脑主板冷门知识科普 求助大佬。计算机主机配置 台式机配置有什么推荐 西餐宴请中的4m原则指的是 多久不使用会自动注销,谢谢。- 问一问 酒桌上言语中透视着的礼节问题?谁来作答 多久不登录自动注销多长时间不用会被注销