Cassandra中表的建立、查询和排序

最近一个项目用到了Cassandra。用了之后再发现,为了性能,它牺牲了太多关系数据库的功能。当然可能很多项目用不到关系数据库的功能,那样的话,可能Cassandra是一个很好的选择。这次做的这个项目,需要用到很多关系数据库的功能,因为设计已经定了,很多程序基本上是为了Cassandra而增加的代码。

Cassandra的查询功能很弱,如果要用到相对复杂的查询,最好不要用Cassandra。

下面说说Cassandra的功能和限制。

Cassandra表的建立

Cassandra可以定义主键和索引。在CQL中,主键的定义和SQL差不多,不过因为结构上的不同,Cassandra的主键第一个列是节点(分区)主键,第二列开始才是真正的主键。

正因为主键第一个列是节点主键,所以索引不可以建在主键的第一个列上。还有一些特殊类型(如:集合类型)的列,也是不可以建立索引的。其它列都是可以的。

另外,Cassandra的索引不支持多个列。

Cassandra的结果默认是按主键排序的,因为Cassandra排序功能也很弱,所以节点主键以外的主键可以加入默认排序的定义(不指定时,默认全部升序)。查询结果只能按主键的相同或相反排序。

例:下面的CQL

SQL
CREATE TABLE test(
	a INT,
	b INT,
	c INT,
	d INT,
	e INT,
	f INT,
	PRIMARY KEY(a,b,c,d))
	WITH CLUSTERING ORDER BY (b DESC, c ASC, d ASC);

CREATE INDEX ON test(d);
CREATE INDEX ON test(e);

下面的代码就会出错

SQL
/* 节点主键上建索引 */
CREATE INDEX ON test(a);
/* 索引上定义多个列 */
CREATE INDEX ON test(c, d);
/* 节点主键上设置默认排序 */
WITH CLUSTERING ORDER BY (a ASC, b DESC, c ASC, d ASC);

Cassandra表的主键查询

Cassandra的主键查询必须按顺序指定值,只有查询的最后一列允许使用范围查询(>,<等运算符),前面的必须用 = 或者 in 。其中,节点主键不能使用范围查询。不能跳跃主键查询。

例:下面的CQL

SQL
SELECT * FROM test WHERE a = 1;
SELECT * FROM test WHERE a in (1, 2);

SELECT * FROM test WHERE a = 1 and b > 0;
SELECT * FROM test WHERE a in (1, 2) and b > 0;

SELECT * FROM test WHERE a = 1 and b = 0 and c > 1;
SELECT * FROM test WHERE a in (1, 2) and b in (0, 1) and c > 1;

下面的代码就会出错

SQL
/* 节点主键使用了范围查询 */
SELECT * FROM test WHERE a > 1;
/* 使用了两个范围查询 */
SELECT * FROM test WHERE a = 1 and b > 0 and c > 1;
/* 跳过了主键c查询 */
SELECT * FROM test WHERE a = 1 and c = 1;

Cassandra表的索引查询

Cassandra表的索引查询只能使用 = 来查询。除索引列之外,还可以指定节点主键,同样节点主键也只能使用 = 来查询。

例:下面的CQL

SQL
SELECT * FROM test WHERE d = 1;

SELECT * FROM test WHERE a = 1 and d = 0;

下面的代码就会出错

SQL
/* 索引使用了=以外的查询 */
SELECT * FROM test WHERE d > 1;
SELECT * FROM test WHERE d in (1, 2);
/* 节点主键使用了=以外的查询 */
SELECT * FROM test WHERE a > 1 and d = 1;
SELECT * FROM test WHERE a in (1, 2) and d = 1;

Cassandra表的其它查询

在满足了之前的主键查询的条件之后,如果还需要添加其它查询列,可以在CQL里加上 ALLOW FILTERING 来开启其它键查询。

例:下面的CQL

SQL
/* f查询 */
SELECT * FROM test WHERE f > 0 ALLOW FILTERING;
/* 使用主键加f查询 */
SELECT * FROM test WHERE a = 1 AND b > 0 AND f > 0 ALLOW FILTERING;
/* 使用主键加e,f查询 */
SELECT * FROM test WHERE a = 1 AND e > 0 AND f > 0 ALLOW FILTERING;

下面的代码就会出错

SQL
/* 不满足主键查询的条件,跳过了b查询 */
SELECT * FROM test WHERE a = 1 AND c = 0 AND f > 0 ALLOW FILTERING;

Cassandra表的排序

Cassandra不支持多结点排序,也就是说如果要排序的话,只有在节点主键使用 = 查询后再能用。而且,排序只能和主键排序相同或者相反,不能自由指定排序。所以在写CQL时,只指定节点主键外的第一个主键结果也是一样的。同主键查询一样,排序也不能跳跃指定。

例:下面的CQL

SQL
/* 和主键排序相同 */
SELECT * FROM test WHERE a = 1 ORDER BY b DESC, c ASC, d ASC;
/* 和上面排序相同 */
SELECT * FROM test WHERE a = 1 ORDER BY b DESC;
/* 和主键排序相反 */
SELECT * FROM test WHERE a = 1 ORDER BY b ASC, c DESC, d DESC;
/* 和上面排序相同 */
SELECT * FROM test where a = 1 ORDER BY b ASC;

下面的代码就会出错

SQL
/* 节点主键使用了 = 以外的查询 */
SELECT * FROM test WHERE a IN (1, 2) ORDER BY b DESC, c ASC, d ASC;
/* 跳跃主键指定排序 */
SELECT * FROM test WHERE a = 1 ORDER BY b DESC, d ASC;

转载请注明:宇托的狗窝 » Cassandra中表的建立、查询和排序

与本文相关的文章

发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址