从Cassandra 0.7开始,推荐使用CQL来创建column family结构。 同时Cassandra鼓励开发人员分享column family结构。 为什么呢?因为,虽然CQL看起来和SQL很像,他们的内部原理完全不同。记住,不要把一个column family想像成关系型数据库的表,而要想像成一个嵌套的键值有序的哈希表。
例如,用CQL创建一个ColumnFamily(Table):
CREATE TABLE example (
field1 int PRIMARY KEY,
field2 int,
field3 int);
然后插入一些行:
INSERT INTO example (field1, field2, field3) VALUES (1,2,3);
INSERT INTO example (field1, field2, field3) VALUES (4,5,6);
INSERT INTO example (field1, field2, field3) VALUES (7,8,9);
数据怎么存储呢?
RowKey: 1
=> (column=, value=, timestamp=1374546754299000)
=> (column=field2, value=00000002, timestamp=1374546754299000)
=> (column=field3, value=00000003, timestamp=1374546754299000)
-------------------
RowKey: 4
=> (column=, value=, timestamp=1374546757815000)
=> (column=field2, value=00000005, timestamp=1374546757815000)
=> (column=field3, value=00000006, timestamp=1374546757815000)
-------------------
RowKey: 7
=> (column=, value=, timestamp=1374546761055000)
=> (column=field2, value=00000008, timestamp=1374546761055000)
=> (column=field3, value=00000009, timestamp=1374546761055000)
对于每一个插入的行,有三点需要注意:row key (RowKey: <?>),列名(column=<?>)和列值(value=<?>)。从上面的例子,我们可以做出一些基本的关于CQL如何映射到Cassandra内部存储结构的总结:
你可能也注意到了,每一个row,都有一个列,列名和列值都为空。这并不是bug。事实上这是为了支持只有row key字段有值,而没有任何其他列有值的情况。
一个更复杂一点的例子:
CREATE TABLE example (
partitionKey1 text,
partitionKey2 text,
clusterKey1 text,
clusterKey2 text,
normalField1 text,
normalField2 text,
PRIMARY KEY (
(partitionKey1, partitionKey2),
clusterKey1, clusterKey2
)
);
这里我们用字段在内部存储时的类型来命名字段。而且我们已经包含了所有情形。这里的主键不仅仅是复合主键,而且是复合partition key (在PRIMARY KEY部分的前半段,用括号括起的部分)和复合cluster key。
然后插入一些行:
INSERT INTO example (
partitionKey1,
partitionKey2,
clusterKey1,
clusterKey2,
normalField1,
normalField2
) VALUES (
'partitionVal1',
'partitionVal2',
'clusterVal1',
'clusterVal2',
'normalVal1',
'normalVal2');
数据怎么存储呢?
RowKey: partitionVal1:partitionVal2
=> (column=clusterVal1:clusterVal2:, value=, timestamp=1374630892473000)
=> (column=clusterVal1:clusterVal2:normalfield1, value=6e6f726d616c56616c31, timestamp=1374630892473000)
=> (column=clusterVal1:clusterVal2:normalfield2, value=6e6f726d616c56616c32, timestamp=1374630892473000)
下面是一个set,list和map类型的例子:
CREATE TABLE example (
key1 text PRIMARY KEY,
map1 map<text,text>,
list1 list<text>,
set1 set<text>
);
插入数据:
INSERT INTO example (
key1,
map1,
list1,
set1
) VALUES (
'john',
{'patricia':'555-4326','doug':'555-1579'},
['doug','scott'],
{'patricia','scott'}
)
数据怎么存储呢?
RowKey: john
=> (column=, value=, timestamp=1374683971220000)
=> (column=map1:doug, value='555-1579', timestamp=1374683971220000)
=> (column=map1:patricia, value='555-4326', timestamp=1374683971220000)
=> (column=list1:26017c10f48711e2801fdf9895e5d0f8, value='doug', timestamp=1374683971220000)
=> (column=list1:26017c12f48711e2801fdf9895e5d0f8, value='scott', timestamp=1374683971220000)
=> (column=set1:'patricia', value=, timestamp=1374683971220000)
=> (column=set1:'scott', value=, timestamp=1374683971220000)
map,list和set的内部存储各不相同: