0. 引言
在传统的RDBMS 之中, 我们为了提高查询或者SQL效率,都会用到各种Statement. 比如JDBC之中常用的PreparedStatement.
Statement的使用在Cassandra会更加广泛。 并且除了PreparedStatement,还有好几种其他的Statement.如下:
- SimpleStatement
- BoundStatement / PreparedStatement
- BuiltStatement
- BatchStatement
原文链接:http://www.flyml.net/2016/09/11/cassandra-tutorial-all-kinds-statements/
(1)最简单的SimpleStatement
首先我们要明确一点: 在Cassandra之中,所有的CRUD操作都要在某一种Statement之中进行。 这一点跟JDBC不太一样
SimpleStatement 跟JDBC之中普通的查询语句类似, 一般只用来做查询或者简单的操作,并且只会使用一次或者几次。
1 2 3 4 5 |
session.execute("select release_version from system.local"); // 上面的语句与下面等价 Statement s = new SimpleStatement("select release_version from system.local"); session.execute(s); |
原文链接:http://www.flyml.net/2016/09/11/cassandra-tutorial-all-kinds-statements/
(2) BoundStatement / PreparedStatement
PreparedStatement 跟JDBC 之中的PreparedStatement 一样, 当一个查询语句会被执行很多次的时候,为了只编译一次提高效率,就会使用PreparedStatement. 但是在Cassandra之中,因为接口的设计,PreparedStatement 无法直接给session调用,需要使用BoundStatement 包装,并且绑定(bind)相应的值。
具体参考下面的例子:
1 2 3 4 5 6 7 8 9 10 11 |
PreparedStatement statement = session.prepare( "INSERT INTO simplex.songs " + "(id, title, album, artist) " + "VALUES (?, ?, ?, ?);"); BoundStatement boundStatement = new BoundStatement(statement); session.execute(boundStatement.bind( UUID.fromString("756716f7-2e54-4715-9f00-91debea6cf50"), "La Petite Tonkinoise", "Bye Bye Blackbird", "Joséphine Baker"); |
注意上面加亮的第1行跟第7行。
原文链接:http://www.flyml.net/2016/09/11/cassandra-tutorial-all-kinds-statements/
(3)BuiltStatement
(囧,笔者也是在准备这篇文章的时候才看到还有这个Statement, 因此笔者也强烈推荐各位技术从业者建立自己的博客,在分享技术的同时,也能提高自己的水平 ^_^)
官网解释:
a statement built with the QueryBuilder DSL. It can be executed directly like a simple statement, or prepared.
大概中文意思:
由QueryBuilder DSL 方式创建的Statement。 执行方式类似SimpleStatement 或者 PreparedStatement.
笔者自己并没有实践过,查看官网之后举了一个非常简单的例子帮助大家理解:
1 2 3 4 5 6 7 8 |
BuiltStatement s = select().all().from("foo").where(eq("k", 1)); // 等价于 new SimpleStatement("SELECT * FROM foo WHERE k=1"); // BuiltStatement 有自己的API与方法 s.forceNoValues(true); s.getQueryString(myCodecRegistry); |
具体说明,请看代码的注释~
原文链接:http://www.flyml.net/2016/09/11/cassandra-tutorial-all-kinds-statements/
(4)BatchStatement
顾名思义,批处理的Statement。 我们知道网络IO的开销与耗时是非常非常大的,特别是网络不太好的时候~ 一个很自然而然的方式就是通过批处理的方式来减少网络IO的创建与释放。另外一种很常见的技术就是通过socket, 这种方式就不是批处理了,而是streaming(数据流)的方式。数据流的方式很适合Cassandra这种write > read的数据库,但是这不在本文范围之内啦。
BatchStatement的用法也很简单,就是把之前的各种Statement通过Batch的方式执行。比如下面的例子:(发现官网python的例子很简明,拿过来用啦)
1 2 3 4 5 6 7 |
insert_user = session.prepare("INSERT INTO users (name, age) VALUES (?, ?)") batch = BatchStatement(consistency_level=ConsistencyLevel.QUORUM) for (name, age) in users_to_insert: batch.add(insert_user, (name, age)) session.execute(batch) |
上面的代码,
第1行: 通过session 生成一个PreparedStatement.
第2行: 创建一个BatchStatement, 并设置一致性级别(consistency_level)。 关于一致性的介绍,会在另外的文章介绍。
第5行: 批量的加入需要执行的操作与数据。注意:batch statement 可以加入不同的Statement 对象。 这个例子只是从最简单的角度出发说明使用方法
第7行: 还是让当前session 来执行。
如果你有JDBC里面批量处理数据的经验,你可能记得在批处理之前,我们可能要设置一个
1 |
setAutoCommit(false) |
执行完成之后,再设置
1 |
setAutoCommit(true); |
在Cassandra这个NoSQL之中,并没有事务的概念,只是相对的,有一个LWT(Lightweighted Transaction, 官网连接:点我).
具体讨论可以参考一下:stackoverflow 之中的讨论:Atomic Batches in Cassandra
问题大意:
如果我batch了100个插入,但是第40个插入失败了。请问前面39个查询会怎样? 比如会被自动删除或者复原吗?
采纳回答:
不会。因为Cassandra并没有roolback的机制。 只是会简单的告诉你:插入失败啦
这就是没有银弹的一个实际情况啦~ NoSQL 通过牺牲一些特性满足了高速写、高速读的需求。
笔者遇到这种情况很少,一般处理方法:重写一次。 当然,需要具体的数据模型逻辑保证不会因为多写一次而写错啦~
原文链接:http://www.flyml.net/2016/09/11/cassandra-tutorial-all-kinds-statements/
本文为原创文章,转载请注明出处

文章评论