接触cassandra比较早了,13年时就开始了解使用(算是最早使用的一批),虽然到现在cassandra的底层实现原理没什么变化,但是客户端方面已经增添了很多新特性和新的操作接口,使它的操作越来越像sql了。太长时间没有去了解和总结新的特性和接口,让我对项目中的cassandra部分的使用居然有点无所适从,真是尴尬。所以是该时候进行新的总结了。
首先看建表空间和建表语句:
旧的
使用客户端工具:./bin/cassandra-cli
建表空间的语句
create keyspace cassandra_keyspace
with placement_strategy = 'NetworkTopologyStrategy'
andstrategy_options = {datacenter1 : 2}
anddurable_writes = true;
建表语句
create Column familyformal_bill_sz_20140901_0 with comparator=UTF8Type
anddefault_validation_class=UTF8Type and key_validation_class=UTF8Type;
--建立含二级索引的表的例子
create Column family product_offer_object_group withcomparator=UTF8Type
anddefault_validation_class=UTF8Type and key_validation_class=UTF8Type
and column_metadata=
[
{column_name: 10, validation_class:UTF8Type,index_type: KEYS},
{column_name: 12, validation_class:UTF8Type,index_type: KEYS}
];
新的
新的使用客户端工具:./bin/csql
建表空间的语句
CREATE KEYSPACE zrf_test IF NOT EXISTSmyCas WITH REPLICATION = {'class': 'SimpleStrategy','replication_factor':2};
建表的语句
create tablezrf_test.repeate_table_20170201(
serid text,
noteid text,
state bigint,
primary key(serid,noteid));
建索引
Create index on repeate_table_20170201(state);
--旧的建表语句只是建了表框架,并没有字段的说法,而是列名,动态的列是不需要在建表语句中明显指定的,而是入库时在插入api中指定(索引除外),而新的建表语句表面上更靠近了传统的关系型数据库的概念。减少了从关系型转nosql型的概念隔膜。
修改表结构:
增加字段
Alter table repeate_table_20170201 add mapsmap<text,text>;
删除字段
Alter table repeate_table_20170201 drop maps;
删除表
Drop table repeate_table_20170201;
新的增删改查语法
1.插入
Insert into repeate_table_20170201 (serid, noteid)values (‘123’,’888’);
--怎么,跟sql语句非常像吧,让你有产生在使用关系型数据库的错觉,但是下面的特征会把这表名的感觉撕碎
(1). Insert into repeate_table_20170201 values(‘123’,’888’);
--这种对表的所有字段按顺序插入各个字段字的语句在关系型数据库中是可用的,但是在cassandra中是不可用的,必须在语句中指定每个插入值对应的字段名,为什么,这是因为cassandra的底层模型根本没有变化,根本没有字段这一说法,所谓的字段不过是插入每个列名都恰巧一样而已。
(2).select * from repeate_table_20170201where 非索引非主键字段=xxxx;
--这种语句是查不出数据的,为什么?还是跟cassandra底层模型还是宽列模型有关,根本不存在字段的概念,所以不可能根据字段去过滤记录,字段是创造出来的表名概念。
2.查询
select * from repeate_table_20170201 where serid=’123’ and noteid=’888’; //正确
select * from repeate_table_20170201 where serid=’123’;// 正确
select * from repeate_table_20170201 where noteid=’888’;//报错
select * from repeate_table_20170201 where非索引非主键字段= xxxx;//报错
select * from repeate_table_20170201 where 索引字段= xxxx;//正确
--可见过滤条件必须是主键或则索引字段,而且是从第一个主键开始的连续主键字段不能中间跳过。这个还是跟cassandra的底层实现模型有关,因为cassandra的分发是按照主键中第一个字段进行哈希分发的,说白了只有主键中第一个字段是真正的key,key-value模型本质没改变,至于主键中第一个字段和第三个字段的组合为什么也不能作为过滤条件呢?应该还是跟列族的模型,怀疑现有的模型多采用的是多层列族模型,主键中第一个字段(key)下面有子列族,而主键中第二个字段是子列族的入口,主键中第三个字段才是真正的列名。所以必须一层层地往下搜索,而不能跳过第二层直接进入第三层,这些和关系型数据库不同的语法实际无时无刻再提醒我们,cassandra的底层模型没变。
3.更新
Update repeate_table_20170201 setstate=2;//报错,不能全量更新
Update repeate_table_20170201 set state=2where state=0;//报错,更新时不能用索引字段作过滤条件
Update repeate_table_20170201 set state=2where serid=’123’;//正确
--可见更新也是有限制的,但是为什么能根据索引进行过滤查询但是不能进行更新过滤呢?理论上是可以的,但是估计是由于在cassandra中更新其实是一个插入,现在的版本中间并没有帮我们做逻辑转化。
4.删除
Delete from repeate_table_20170201 where ……..;
--同理,删除的过滤条件跟更新一样,不支持全量删除和按索引为条件过滤。因为在cassandra的底层实现删除和更新都是插入。
新增列值类型
现在cassandra增加支持了List、Set、Map三种集合类型,比如我们创建表时
create table zrf_test.test_table(
serid text,
bills list<text>,
maps map<text,text>,
sets set<text>,
primary key(serid));
插入map
insert into test_table (serid,bills) values (‘1234’,[‘hello’,’world’]);
追加list元素 update test_table set bills=bills+[‘zrf’] where serid=’1234’;
插入map
insert into test_table (serid,maps) values (‘1235’,{‘1’:’1235’,’2’:’70320000’});
插入set
insert into test_table (serid,sets) value (‘1235’,{‘test’,’test1’,’test’});
下一篇,代码中api的使用总结