最近在封装公司数据层操作,公司用的分布式菲关系数据库 cassandra,对于go语言关于cassandra的第三方库主要有一下两个:
- github.com/gocql/gocql
- github.com/gocassa/gocassa
其中 gocassa 就是基于gocql 进行二次抽象封装的,个人觉得作者抽象的很到位,按照不同建表方式对应有各种操作方法。
在我看gocassa过程中,对于建立表格时候需要实现建立好对应的索引以便于进行聚合查询等操作(这也是与MySQL这种关系型数据库的区别所在)。
Cassandra之中一共包含下面5种Key:
1. Primary Key
2. Partition Key
3. Composite Key
4. Compound Key
5. Clustering Key
Primary key 是用来获取某一行的数据, 可以是一列或者多列(复合列 composite)
Primary = Partition Key + [Clustering Key] (Clustering Key 可选)
primary key 中的字段组成一体不能重复。
Partition Key
看如下示例:
单一型:
CREATE TABLE sample (
id text,
name text,
PRIMARY KEY (id)
);
CREATE TABLE users (
id int,
name text,
uid int,
adress text,
PRIMARY KEY (id, name, uid)
);
id ==> Partition Key (单一)
name, uid ==> Clustering Key
复合型:
CREATE TABLE sample1 (
id text,
name text,
PRIMARY KEY ((id, name))
);
CREATE TABLE users (
id int,
name text,
uid int,
adress text,
PRIMARY KEY ((id, name), uid)
);
id, name ==> Partition Key (复合)
uid ==> Clustering Key
Clustering Key
Cassandra中所有的数据都只能根据Primary Key中的字段来排序,
因此, 如果想根据某个column来排序, 必须将改 column 加到 Primary key 中,
如 primary key (id, c1, c2 ,c3), 其中 id 是 partition key,
c1, c2 ,c3是Clustering Key.
(如果想用id和c1作为partition key, 只需添加括号: primary key ((id, c1), c2 ,c3)).
示例:
CREATE TABLE sample3 (
id text,
gmt_create bigint,
name text,
score text,
PRIMARY KEY ((id), gmt_create)
);
在该表中插入若干纪录后, 使用select *查询该表, 得到如下纪录:
id | gmt_create | name | score
-----+------------+-------+--------
id3 | 1925 | name3 | score3
id3 | 1926 | name4 | score4
id1 | 1923 | name1 | score1
id2 | 1924 | name2 | score2
cql表中有四条记录, 其中id=id3有两条记录, 那么是否意味着cassandra中有四行来保存这些记录呢?用Cssandra-Cli来查询:
RowKey: id3
=> (name=1925:, value=, timestamp=1442494070376000)
=> (name=1925:name, value=6e616d6533, timestamp=1442494070376000)
=> (name=1925:score, value=73636f726533, timestamp=1442494070376000)
=> (name=1926:, value=, timestamp=1442494335821000)
=> (name=1926:name, value=6e616d6534, timestamp=1442494335821000)
=> (name=1926:score, value=73636f726534, timestamp=1442494335821000)
-------------------
RowKey: id1
=> (name=1923:, value=, timestamp=1442494039343000)
=> (name=1923:name, value=6e616d6531, timestamp=1442494039343000)
=> (name=1923:score, value=73636f726531, timestamp=1442494039343000)
-------------------
RowKey: id2
=> (name=1924:, value=, timestamp=1442494054817000)
=> (name=1924:name, value=6e616d6532, timestamp=1442494054817000)
=> (name=1924:score, value=73636f726532, timestamp=1442494054817000)
3 Rows Returned.
可以看到, cassandra中只用3行来保存数据, 其中id=id3到两条记录被保存在同一行上. 事实上, 当存在clustering key时, 当partition key相同而clustering key不同时, 其纪录是保存在同一行上的,
而每一个 column 的 name 责由 clustering 的值 + “:” + 原来的 column name 构成
(如sample3中, column score的name = 1923:score),
sample3在cassandra中的存储结构如下图所示:
+-------------+----------------+-------------------+----------------------+
| | name = 1925: | name=1925:name | name=1925:score |
| | value = | value=6e616d6533 | value=73636f726533 |
| | timestamp | timestamp | timestamp |
| id 3 +----------------+-------------------+----------------------+
| | name = 1926: | name=1926:name | name=1926:score |
| | value= | value=6e616d6534 | value=73636f726534 |
| | timestamp | timestamp | timestamp |
+-------------+----------------+-------------------+----------------------+
| | name = 1923: | name=1923:name | name=1923:score |
| id 1 | value = | value=6e616d6531 | value=73636f726531 |
| | timestamp | timestamp | timestamp |
+-------------+----------------+-------------------+----------------------+
| | name = 1924: | name=1924:name | name=1924:score |
| id 2 | value = | value=6e616d6532 | value=73636f726532 |
| | timestamp | timestamp | timestamp |
+-------------+----------------+-------------------+----------------------+