Cassandra的数据模型类似于关系型数据库的模型,且提供了与SQL语言非常类似的CQL语言进行操作。
但是Cassandra的数据模型类似于多层键值对结构,与关系型数据库存在巨大差别。
本文基于: [cqlsh 5.0.1 | Cassandra 3.11.2 | CQL spec 3.4.4 | Native protocol v4]
目录:
多层KV结构
Cassandra 的数据模型由 keyspace (类似关系型数据库里的database), column family(类似关系型数据库里的table), 主键(key)和列(column)组成。
对于一个 column family 不应该想象成关系型数据库中的表, 而是一个多层的key-value结构:
Map<PartitionKey, SortedMap<ClusteringKey, Column>>我们使用CQL来描述:
create table table1 ( key1 int, key2 int, content text, PRIMARY KEY ((key1), key2) );在上述CQL创建的表(column family)中,key1是 partition key, 而 key2 是 clustering key, key1 和 key2 称为主键(PRIMARY KEY)
Cassandra支持更复杂的表结构:
CREATE TABLE table2 ( pkey1 int, pkey2 int, ckey1 int, ckey2 int, content text, PRIMARY KEY ((pkey1, pkey2), ckey1, ckey2) );此时的数据结构可以描述为:
Map<pkey1, Map<pkey2, SortedMap<ckey1, SortedMap<ckey2, content>>>>作为一个分布式数据库, Cassandra 根据 partition key 决定数据如何在集群的各个节点上分区。clustering key 决定数据在分区内的排序。
查询
下文中将以 table2 为例介绍 cassadra 数据模型的特性。
从上文使用Map描述的表结构可知,我们无法根据非主键进行查询(如table2中的data):
SELECT * FROM table2 WHERE content='a'; -- error SELECT * FROM table2 WHERE pkey1 = 1 AND content='a'; -- error SELECT * FROM table2 WHERE pkey1 = 1 AND pkey2 = 1; -- right通常情况下,在对形如((pkey1, pkey2), ckey1, ckey2)这样的主键列进行查询时需要注意:
- partition key 仅支持精确查询(=, in), 不能进行范围查询(>, <, >=, <=)。注: Cassandra 不支持 != 查询。
- 涉及多个 partition key 的查询必须提供前置 partition key 的精确值。即若要查询 pkey2 则必须提供 pkey1 的精确值。
- 涉及 clustering key 的查询,必须提供所有 partition key 的精确值
- 涉及的 clustering key 不能跳跃,若要根据 ckey2 进行查询则必须提供 ckey1 的精确值
(请不要记忆上述结论,根据Cassandra的内部数据结构很容易明白可以进行什么样的查询)
下面根据具体示例说明。
仅涉及partition key:
SELECT * FROM table2 WHERE pkey1 = 1; -- right SELECT * FROM table2 WHERE pkey1=1 AND pkey2=1; -- right SELECT * FROM table2 WHERE pkey2=1; -- error涉及一个 clustering key:
