cql二进制协议和准备好的查询中的命名绑定变量

时间:2014-04-17 06:50:35

标签: cassandra cql datastax-java-driver

想象一下,我有一个简单的CQL表

CREATE TABLE test (
k int PRIMARY KEY,
v1 text,
v2 int,
v3 float
)

在很多情况下,人们会想要使用Cassandra的无模式本质,只设置一些值,例如,

INSERT into test (k, v1) VALUES (1, 'something');

当编写应用程序以写入Cassandra集群中的此类CQL表时,出于性能原因,需要立即使用预准备语句执行此操作。

不同的驱动程序以不同的方式处理。例如,Java驱动程序(在CQL二进制协议的修改的帮助下)引入了使用命名绑定变量的机会。非常实用:CASSANDRA-6033

我想知道的是,从二进制协议的角度来看,为准备好的查询中的绑定变量的子集提供值的正确方法是什么?

实际上,值通过构建值列表提供给准备好的查询,如

中所述
4.1.4. QUERY 
[...]
Values. In that case, a [short] <n> followed by <n> [bytes]
values are provided. Those value are used for bound variables in
the query.

请注意[bytes]

的定义
[bytes]        A [int] n, followed by n bytes if n >= 0. If n < 0,
               no byte should follow and the value represented is `null`.

根据这个描述,我得到以下内容:

  1. QUERY中的“值”无法为特定列提供值 。它只是一个有序的值列表。我猜[short]必须对应于准备好的查询中绑定变量的确切数量?
  2. 所有值,无论它们是什么类型,都表示为[字节]。如果这是真的,那么[bytes]值的任何解释都留给服务器(转换为int,short,text,......)?
  3. 假设我没问题,我想知道'null'[bytes]值是否可用于“跳过”绑定变量而不为其赋值。

    我尝试了这个并修补了cpp驱动程序(这是我感兴趣的)。查询被执行但是当我从clqsh执行SELECT时,我没有看到空字段的'null'字符串表示,所以我想知道这是否是一个hack,由于某些原因不仅仅是崩溃或预期的方式来执行此操作

    很抱歉,我真的不认为我可以下载java驱动程序,看看如何实现命名绑定变量! :(

    ----------编辑 - 已解决----------

    我的假设是正确的,现在支持跳过准备好的查询中的字段已经通过使用null [字节值]添加到cpp驱动程序(请参阅here)。

2 个答案:

答案 0 :(得分:1)

  

我想知道的是,从二进制协议的角度来看,为准备好的查询中的绑定变量的子集提供值的正确方法是什么?

您需要准备一个只插入/更新您感兴趣的列子集的查询。

   QUERY中的“值”无法为特定列提供值。它只是一个有序的值列表。我猜[short]必须对应于准备好的查询中绑定变量的确切数量?

这是对的。排序由Cassandra在准备查询时返回的列元数据确定。

  

所有值,无论它们是什么类型,都表示为[字节]。如果是这样,那么[bytes]值的任何解释都留给服务器(转换为int,short,text,......)?

这也是正确的。驱动程序将使用返回的列元数据来确定如何将本机值(字符串,UUIDS,整数等)转换为二进制(字节)格式。 Cassandra与服务器端的操作相反。

  

假设我没问题,我想知道'null'[bytes]值是否可用于“跳过”绑定变量而不为其赋值。

空列插入被解释为删除。

答案 1 :(得分:0)

基于我所描述的原则,已经完成了我想要实现的目标(参见here)。