CHAPTER 9 读写数据

CHAPTER 9 读写数据

写操作

特性:

  1. 写入速度很快, 因为没有要求磁盘的读写和寻址;
  2. 所有的写操作是追加性质的, insert和update操作没有任何区别(可以归纳为一个upsert操作);
  3. 数据库永远是可写入状态, 在一个column family中, 写操作永远是原子性的;

写操作的一致性级别

轻量级的事务

Cassandra不提供ACID事务.但是有事务的机制: lightweight transactions 和 batches.

Cassandra’s lightweight transaction (LWT)的机制是Paxos算法,有以下几个特点:

  1. 事务的作用域为单个分区
  2. 事务由cas(compare and set)机制构成, 比较成功操作执行
  3. 比较失败, 可以决定是重试或者放弃该操作
  4. USING TIMESTAMP 操作不支持

使用方法:
在insert语句后面加上IF NOT EXISTS

cqlsh> INSERT INTO hotel.hotels (id, name, phone) VALUES (
'AZ123', 'Super Hotel at WestWorld', '1-888-999-9999') IF NOT EXISTS;

这条语句是根据主键进行插入的意思,重复执行这条语句的话会失败.
update操作也是一样.

cqlsh> UPDATE hotel.hotels SET name='Super Hotel Suites at WestWorld'
... WHERE id='AZ123' IF name='Super Hotel at WestWorld';

重复执行以上操作会失败.

总结使用方式:
INSERT : IF NOT EXISTS
UPDATE: IF x=y
操作keyspace和table的时候也支持 IF NOT EXISTS
Java代码操作

SimpleStatement hotelInsert = session.newSimpleStatement(
"INSERT INTO hotels (id, name, phone) VALUES (?, ?, ?) IF NOT EXISTS",
"AZ123", "Super Hotel at WestWorld", "1-888-999-9999");
ResultSet hotelInsertResult = session.execute(hotelInsert);
boolean wasApplied = hotelInsertResult.wasApplied();
if (wasApplied) {
	Row row = hotelInsertResult.one();
	row.getBool("applied");
}

批处理

lightweight transactions 只作用于单个分区, batch机制允许你将多个分区的操作整合成一个statement.
特性:

  1. 只有修改操作(增删改)可以被包含在batch中
  2. batches是原子性的, 一旦batch成功,那么包含在batch中的所有操作都会成功
  3. batches不是一个事务机制, 但是你可以在batch中的statement中使用lightweight transactions.要注意的是多个事务的statement要是在一个分区中才行.
  4. Counter修改有一个特别的counter batch, counter batch中只能包含counter操作
  5. 在一个batch中, 属于一个指定了分区键的所有update操作会被隔离执行, 跨分区的操作则没有隔离性的保证.这意味着在一个批次的修改操作执行完之前,你是有可能读到已经更新的数据的.

使用方式:

cqlsh> 
BEGIN BATCH
INSERT INTO hotel.hotels (id, name, phone)
	VALUES ('AZ123', 'Super Hotel at WestWorld', '1-888-999-9999');
INSERT INTO hotel.hotels_by_poi (poi_name, id, name, phone)
	VALUES ('West World', 'AZ123', 'Super Hotel at WestWorld',
	'1-888-999-9999');
APPLY BATCH;

java代码

SimpleStatement hotelInsert = session.newSimpleStatement(
	"INSERT INTO hotels (id, name, phone) VALUES (?, ?, ?)",
	"AZ123", "Super Hotel at WestWorld", "1-888-999-9999");
SimpleStatement hotelsByPoiInsert = session.newSimpleStatement(
	"INSERT INTO hotels_by_poi (poi_name, id, name, phone)
	VALUES (?, ?, ?, ?)", "WestWorld", "AZ123",
	"Super Hotel at WestWorld", "1-888-999-9999");
BatchStatement hotelBatch = new BatchStatement();
hotelBatch.add(hotelsByPoiInsert);
hotelBatch.add(hotelInsert);
ResultSet hotelInsertResult = session.execute(hotelBatch);

cassandra.yaml中有两个参数跟batch有关:
batch_size_warn_threshold_in_kb 默认5KB
batch_size_fail_threshold_in_kb 默认50KB
以上大小指的是CQL语句的总大小, 设置限制是为了避免影响性能和稳定性.

读操作

几个特点:
读操作更加容易,连接到任何一个节点就可以读取数据.如果一个node上没有要读取的数据,那么这个节点会成为一个坐标指向有数据的节点.
读操作比写操作慢.为了执行读操作,cassandra需要寻址,通过增加节点在内存中存入更多的数据,用更多的缓存.cassandra还必须等待读操作的同步响应,还要执行read repair.

范围查询,排序,过滤

bulk loading工具
COPY工具可以导入导出csv格式文件.

导出 to:指定输出文件

cqlsh:hotel> COPY hotels TO 'hotels.csv' WITH HEADER=TRUE;

导入 from:从哪个文件导入

cqlsh:hotel> COPY hotels FROM 'hotels.csv' WITH HEADER=true;

hotel_id 是 partition key,date 和 room_number 是 clustering columns
范围查询

cqlsh:hotel> SELECT * FROM available_rooms_by_hotel_date
WHERE hotel_id='AZ123' and date>'2016-01-05' and date<'2016-01-12';

WHERE语法规则:

  1. 分区key必须指定
  2. 只有之前所有的clustering key都被约束了,你指定的这个clustering key才能被约束
cqlsh:hotel> SELECT * FROM available_rooms_by_hotel_date
WHERE hotel_id='AZ123' and room_number=101;
InvalidRequest: code=2200 [Invalid query] message="PRIMARY KEY column
"room_number" cannot be restricted as preceding column "date" is not
restricted"

这些约束是建表的时候指定的, 这些约束可以让cassandra获取连续的,排好序的rows

ALLOW FILTERING是个例外, 可以让我们忽略分区key, 例如:

cqlsh:hotel> SELECT * FROM available_rooms_by_hotel_date
WHERE date='2016-01-25' ALLOW FILTERING;

ALLOW FILTERING不推荐使用, 它是代价高昂的查询.如果你发现你需要用到这种查询, 最好的方法是修改你的数据模型.

IN
in查询比较慢,因为其查询的结果可能是在不连续的row上

cqlsh:hotel> SELECT * FROM available_rooms_by_hotel_date
WHERE hotel_id='AZ123' AND date IN ('2016-01-05', '2016-01-12');

SELECT可以覆盖建表时的排序规则

cqlsh:hotel> SELECT * FROM available_rooms_by_hotel_date
WHERE hotel_id='AZ123' and date>'2016-01-05' and date<'2016-01-12'
ORDER BY date DESC;

函数和聚合

user-defined functions (UDFs) and user-defined aggregates (UDAs)
用户定义函数, 用户定义聚合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值