1

想象一下我有一个简单的 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]。如果这是真的,对 [bytes] 值的任何解释都留给服务器(转换为 int、short、text ......)?

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

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

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

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

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

4

2 回答 2

1

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

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

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

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

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

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

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

空列插入被解释为删除。

于 2014-04-18T18:45:56.513 回答
0

根据我描述的原则,我试图实现的目标已经完成(见这里)。

于 2014-04-28T15:51:45.300 回答