Cassandra 文档

版本

您正在查看预发布版本的文档。

Cassandra 查询语言 (CQL) v3.4.3

\{toc:maxLevel=3}

CQL 语法

前言

本文档描述了 Cassandra 查询语言 (CQL) 版本 3。CQL v3 与 CQL v2 不向后兼容,并且在许多方面与之不同。请注意,本文档描述了语言的最新版本。但是,更改部分提供了 CQL v3 不同版本之间的差异。

CQL v3 提供了一个非常接近 SQL 的模型,其含义是数据被放入包含中。因此,在本文档中使用时,这些术语(表、行和列)具有与 SQL 中相同的定义。但请注意,它们并不引用 Cassandra 内部实现以及 Thrift 和 CQL v2 API 中的行和列的概念。

惯例

为了帮助指定 CQL 语法,我们将在本文档中使用以下惯例

  • 语言规则将以类似 BNF 的符号表示

bc(syntax). ::= TERMINAL

  • 非终结符符号将使用<尖括号>

  • 作为 BNF 的其他快捷符号,我们将使用传统的正则表达式符号(?+*)来表示给定符号是可选的和/或可以重复。我们还允许括号对符号进行分组,并使用 [<字符>] 符号来表示 <字符> 中的任何一个。

  • 语法是为了文档目的而提供的,并省略了一些小细节。例如,CREATE TABLE 语句中的最后一个列定义是可选的,但如果存在,则受支持,即使本文档中提供的语法表明不受支持。

  • 示例代码将以代码块的形式提供

bc(sample). SELECT sample_usage FROM cql;

  • 在正文中对关键字或 CQL 代码片段的引用将以固定宽度字体显示。

标识符和关键字

CQL 语言使用标识符(或名称)来标识表、列和其他对象。标识符是一个与正则表达式 [a-zA-Z0-9_]* 匹配的标记。

许多这样的标识符(如 SELECTWITH)是关键字。它们对语言具有固定的含义,并且大多数是保留的。这些关键字的列表可以在 附录 A 中找到。

标识符和(未加引号的)关键字不区分大小写。因此,SELECTselectsElEcT 相同,例如,myIdmyidMYID 相同。经常使用的一种惯例(特别是本文档的示例)是为关键字使用大写,为其他标识符使用小写。

还有一种标识符,称为带引号的标识符,它通过用双引号 (") 括起任意字符序列来定义。带引号的标识符永远不是关键字。因此,"select" 不是保留关键字,可用于引用列,而 select 会引发解析错误。此外,与不带引号的标识符和关键字相反,带引号的标识符区分大小写("My Quoted Id""my quoted id"不同)。与 [a-zA-Z0-9_]* 匹配的全小写带引号标识符等效于通过删除双引号获得的不带引号标识符(因此,"myid" 等效于 myidmyId,但不同于 "myId")。在带引号的标识符内,可以重复双引号字符以对其进行转义,因此 "foo "" bar" 是一个有效的标识符。

警告带引号的标识符允许声明具有任意名称的列,这些名称有时会与服务器使用的特定名称冲突。例如,在使用条件更新时,服务器将响应包含名为 "[applied]" 的特殊结果的结果集。如果你已声明具有此类名称的列,这可能会混淆某些工具,因此应避免这样做。通常,应优先使用不带引号的标识符,但如果你使用带引号的标识符,则强烈建议避免任何用方括号括起来的名称(如 "[applied]")和任何看起来像函数调用的名称(如 "f(x)")。

常量

CQL 定义了以下类型的常量:字符串、整数、浮点数、布尔值、UUID 和 blob

  • 字符串常量是用单引号 (') 括起来的任意字符序列。可以通过重复单引号在字符串中包含单引号,例如 'It''s raining today'。这些不能与使用双引号的带引号标识符混淆。

  • 整数常量由 '-'?[0-9]+ 定义。

  • 浮点数常量由 '-'?[0-9]+('.'[0-9]*)?([eE][+-]?[0-9+])? 定义。除此之外,NaNInfinity 也是浮点数常量。

  • 布尔常量为 truefalse,不区分大小写(即 True 是一个有效的布尔常量)。

  • UUID 常量由 hex{8}-hex{4}-hex{4}-hex{4}-hex{12} 定义,其中 hex 是十六进制字符,例如 [0-9a-fA-F]{4} 是此类字符的数量。

  • blob 常量是由 0[xX](hex)+ 定义的十六进制数字,其中 hex 是十六进制字符,例如 [0-9a-fA-F]

有关如何对这些常量进行类型化,请参阅 数据类型部分

CQL 有的概念,它表示 CQL 支持的值的类型。项由以下定义

term::= constant | literal | function_call | arithmetic_operation | type_hint | bind_marker
literal::= collection_literal | vector_literal | udt_literal | tuple_literal
function_call::= identifier '(' [ term (',' term)* ] ')'
arithmetic_operation::= '-' term | term ('+' | '-' | '*' | '/' | '%') term
type_hint::= '(' cql_type ')' term
bind_marker::= '?' | ':' identifier

因此,项之一是

注释

CQL 中的注释是以双破折号 (--) 或双斜杠 (//) 开头的行。

多行注释也通过在 // 中包含支持(但不支持嵌套)。

bc(sample).
— 这是一个注释
/* 这是
多行注释 */

语句

CQL 由语句组成。与 SQL 中一样,这些语句可以分为 3 类

  • 数据定义语句,允许设置和更改数据存储方式。

  • 数据操作语句,允许更改数据

  • 查询,用于查找数据

所有语句都以分号 (;) 结尾,但在处理单个语句时可以省略该分号。支持的语句在以下部分中进行描述。在描述所述语句的语法时,我们将重复使用下面定义的非终结符号

bc(syntax)..
::= 任何带引号或不带引号的标识符,不包括保留关键字
::= ( `.')?

::= 字符串常量
::= 整数常量
::= 浮点数常量
::= |
::= uuid 常量
::= 布尔常量
::= blob 常量

::=
|
|
|
|
::= ?'
| `:'
::=
|
|
| `(' ( (
,' )*)? `)'

::=
|
|
::= `\{' ( `:' ( `,' `:' )* )? `}'
::= `\{' ( ( `,' )* )? `}'
::= `[' ( ( `,' )* )? `]'

::=

::= (AND )*
::= =' ( | | )
p.
请注意,上述语法并非所有可能的产生式在实践中都是有效的。最值得注意的是,目前不允许在 <collection-literal> 中使用 <variable> 和嵌套 <collection-literal>

<variable> 可以是匿名的(问号 (?))或命名的(标识符前加 :)。两者都为 预处理语句 声明绑定变量。匿名变量和命名变量之间的唯一区别是命名变量更容易引用(具体方式取决于所使用的客户端驱动程序)。

<properties> 产生式由创建和更改键空间和表的语句使用。每个 <property> 都是一个简单属性,在这种情况下它只具有一个值,或一个映射属性,在这种情况下它的值是一个对子选项进行分组的映射。以下将其中一个或另一个称为属性的类型简单映射)。

<tablename> 将用于标识表。这是一个表示表名的标识符,可以由键空间名称前缀。如果提供了键空间名称,则允许在当前活动键空间之外的另一个键空间中标识表(当前活动键空间通过 USE 语句设置)。

有关支持的 <function>,请参阅 函数 部分。

字符串可以用单引号或两个美元字符括起来。引入第二个语法是为了允许包含单引号的字符串。此类字符串的典型候选对象是用户定义函数的源代码片段。

样本

bc(sample)..
`some string value'

双美元字符串可以包含单引号 ’
p.

预处理语句

CQL 支持预处理语句。预处理语句是一种优化,它允许仅解析一次查询,但使用不同的具体值多次执行它。

在语句中,每次预期列值(在数据操作和查询语句中),都可以使用 <variable>(见上文)。然后必须准备包含绑定变量的语句。准备后,可以通过为绑定变量提供具体值来执行它。准备语句和执行已准备语句的确切过程取决于所使用的 CQL 驱动程序,并且超出了本文档的范围。

除了提供列值外,还可以使用绑定标记为 LIMITTIMESTAMPTTL 子句提供值。如果使用匿名绑定标记,则查询参数的名称将分别为 [limit][timestamp][ttl]

数据定义

CREATE KEYSPACE

语法

bc(syntax)..
::= CREATE KEYSPACE (IF NOT EXISTS)? WITH
p.
样本

bc(sample)..
CREATE KEYSPACE Excelsior
WITH replication = \{’class’: `SimpleStrategy', `replication_factor' : 3};

CREATE KEYSPACE Excalibur
WITH replication = \{’class’: NetworkTopologyStrategy', `DC1' : 1, `DC2' : 3}
AND durable_writes = false;
p.
`CREATE KEYSPACE
语句创建一个新的顶级键空间。键空间是一个定义复制策略和一组表的某些选项的命名空间。有效的键空间名称是仅由字母数字字符组成的标识符,其长度小于或等于 32。请注意,作为标识符,键空间名称不区分大小写:对区分大小写的键空间名称使用带引号的标识符。

CREATE KEYSPACE 支持的 <properties>

名称 类型 是否必须 默认值 说明

replication

映射

用于键空间的复制策略和选项。

durable_writes

简单

true

是否对该键空间上的更新使用提交日志(自行承担禁用此选项的风险!)。

replication <property> 是必须的。它至少必须包含定义要使用的复制策略类的 'class' 子选项。其余子选项取决于该复制策略类。默认情况下,Cassandra 支持以下 'class'

  • 'SimpleStrategy':一个简单的策略,为整个集群定义了一个简单的复制因子。支持的唯一子选项是 'replication_factor',用于定义该复制因子,并且是必须的。

  • 'NetworkTopologyStrategy':一个复制策略,允许为每个数据中心独立设置复制因子。其余子选项是键值对,其中每次键都是数据中心名称,值是该数据中心复制因子。

尝试创建已存在的键空间将返回错误,除非使用了 IF NOT EXISTS 选项。如果使用了该选项,如果键空间已存在,则该语句将为无操作。

USE

语法

bc(语法)。::= USE

样本

bc(示例)。USE myApp;

USE 语句将现有键空间名称作为参数,并将其设置为每个连接当前工作键空间。除非另有说明,否则所有后续键空间特定操作将在所选键空间的上下文中执行,直到发出另一个 USE 语句或连接终止。

ALTER KEYSPACE

语法

bc(syntax)..
::= ALTER KEYSPACE (IF EXISTS)? WITH
p.
样本

bc(sample)..
ALTER KEYSPACE Excelsior
WITH replication = \{’class’: `SimpleStrategy', `replication_factor' : 4};

ALTER KEYSPACE 语句更改现有键空间的属性。支持的 <properties>CREATE KEYSPACE 语句相同。

DROP KEYSPACE

语法

bc(语法)。::= DROP KEYSPACE ( IF EXISTS )?

样本

bc(示例)。DROP KEYSPACE myApp;

DROP KEYSPACE 语句会导致立即不可逆地删除现有键空间,包括其中的所有列族以及这些列族中包含的所有数据。

如果键空间不存在,该语句将返回一个错误,除非使用了 IF EXISTS,在这种情况下,操作将为无操作。

CREATE TABLE

语法

bc(syntax)..
::= CREATE ( TABLE | COLUMNFAMILY ) ( IF NOT EXISTS )?
`(' ( `,' )* `)'
( WITH ( AND )* )?

::= ( STATIC )? ( PRIMARY KEY )?
| PRIMARY KEY `(' ( `,' )* `)'

::=
| (' (,' )* `)'

::=
| COMPACT STORAGE
| CLUSTERING ORDER
p.
样本

bc(sample)..
CREATE TABLE monkeySpecies (
species text PRIMARY KEY,
common_name text,
population varint,
average_size int
) WITH comment=`Important biological records';

CREATE TABLE timeline (
userid uuid,
posted_month int,
posted_time uuid,
body text,
posted_by text,
PRIMARY KEY (userid, posted_month, posted_time)
) WITH compaction = \{ class' : `LeveledCompactionStrategy' };
p.
`CREATE TABLE
语句创建一个新表。每个此类表都是一组(通常表示相关实体),它为这些行定义了许多属性。表由 名称 定义,它定义构成表行的列,并具有多个 选项。请注意,CREATE COLUMNFAMILY 语法作为 CREATE TABLE 的别名(出于历史原因)受到支持。

尝试创建已存在的表将返回一个错误,除非使用了 IF NOT EXISTS 选项。如果使用了该选项,如果表已存在,该语句将为无操作。

<tablename>

有效的表名称与有效的 键空间名称 相同(长达 32 个字符的字母数字标识符)。如果仅提供了表名称,则在当前键空间(参见 USE)中创建表,但如果它由现有键空间名称作为前缀(参见 <tablename> 语法),它将在指定的键空间中创建(但不会更改当前键空间)。

<column-definition>

CREATE TABLE 语句定义表行可以拥有的列。由其名称(标识符)和类型定义(有关允许的类型及其属性的更多详细信息,请参见 数据类型 部分)。

在表中,行由其 PRIMARY KEY(或更简单的键)唯一标识,因此所有表定义必须定义一个 PRIMARY KEY(且仅定义一个)。PRIMARY KEY 由表中定义的一个或多个列组成。如果 PRIMARY KEY 仅为一列,则可以在列定义后直接指定该列。否则,必须通过在 PRIMARY KEY 后跟括号中由逗号分隔的组成键的列名称列表来指定它。请注意

bc(sample).
CREATE TABLE t (
k int PRIMARY KEY,
other text
)

等效于

bc(sample).
CREATE TABLE t (
k int,
other text,
PRIMARY KEY (k)
)

分区键和聚类列

在 CQL 中,为 PRIMARY KEY 定义列的顺序很重要。键的第一列称为分区键。它具有以下属性:所有共享相同分区键的行(实际上甚至跨表)都存储在同一物理节点上。此外,对给定表共享相同分区键的行进行插入/更新/删除操作时,这些操作将以原子方式和隔离方式执行。请注意,可以有复合分区键,即使用额外的圆括号集来定义形成分区键的列,从而形成由多列组成的分区键。

PRIMARY KEY 定义的剩余列(如果有)称为__聚类列。在给定的物理节点上,给定分区键的行按聚类列产生的顺序存储,从而使按该聚类顺序检索行特别高效(请参阅 SELECT)。

STATIC

在表定义中,某些列可以声明为 STATIC。静态列将由属于同一分区(具有相同分区键)的所有行“共享”。例如,在

bc(sample).
CREATE TABLE test (
pk int,
t int,
v text,
s text static,
PRIMARY KEY (pk, t)
);
INSERT INTO test(pk, t, v, s) VALUES (0, 0, `val0', `static0');
INSERT INTO test(pk, t, v, s) VALUES (0, 1, `val1', `static1');
SELECT * FROM test WHERE pk=0 AND t=0;

最后一个查询将返回 'static1' 作为 s 的值,因为 s 是静态的,因此第二次插入修改了这个“共享”值。但是请注意,静态列仅在给定的分区内是静态的,如果在上面的示例中两行来自不同的分区(即如果它们具有不同的 `pk` 值),则第二次插入不会修改第一行的 s 值。

允许静态列时会应用一些限制

  • 具有 COMPACT STORAGE 选项的表(请参阅下文)不能有它们

  • 没有聚类列的表不能有静态列(在没有聚类列的表中,每个分区只有一行,因此每列本质上都是静态的)。

  • 只有非 PRIMARY KEY 列可以是静态的

<option>

CREATE TABLE 语句支持许多选项,这些选项控制新表的配置。可以在 WITH 关键字后指定这些选项。

第一个选项是 COMPACT STORAGE。此选项主要针对在 CQL3 之前创建的定义向后兼容(有关更多详细信息,请参阅 www.datastax.com/dev/blog/thrift-to-cql3)。此选项还提供了稍微紧凑一些的磁盘数据布局,但代价是降低了表的灵活性和可扩展性。最值得注意的是,COMPACT STORAGE 表不能有集合或静态列,并且具有至少一个聚类列的 COMPACT STORAGE 表仅支持一列(而不是 0 或多于 1 列)不属于 PRIMARY KEY 定义(这尤其意味着您不能在创建后添加或删除列)。由于这些原因,除了上面提到的向后兼容性原因之外,不建议在其他情况下使用 COMPACT STORAGE

另一个选项是 CLUSTERING ORDER。它允许定义磁盘上的行顺序。它采用聚类列名称的列表,其中每个名称都带有磁盘上的顺序(升序或降序)。请注意,此选项会影响 SELECT 期间允许哪些 ORDER BY

表创建支持以下其他 <property>

选项 类型 默认值 说明

注释

简单

自由格式、可读的注释。

gc_grace_seconds

简单

864000

在垃圾回收墓碑(删除标记)之前等待的时间。

bloom_filter_fp_chance

简单

0.00075

sstable 布隆过滤器的目标误报概率。将调整布隆过滤器的尺寸以提供所提供的概率(因此降低该值会影响布隆过滤器在内存和磁盘中的尺寸)

default_time_to_live

简单

0

表中默认的过期时间(``TTL''),单位为秒。

compaction

映射

见下文

压缩选项,请参见下文

compression

映射

见下文

压缩选项,请参见下文

caching

映射

见下文

缓存选项,请参见下文

crc_check_chance

简单

1.0

此选项定义了在读取过程中检查校验和以检测位腐烂并防止损坏传播到其他副本的概率。默认值为 1,即在每次读取数据块时应用校验和。设置为 0 以禁用校验和检查,例如设置为 0.5 以检查每次读取。

由于技术限制,我们目前仅对压缩文件应用此选项。如果表中未启用压缩,则不会验证任何校验和。

压缩选项

compaction 属性至少必须定义 'class' 子选项,该选项定义要使用的压缩策略类。默认支持的类是 'SizeTieredCompactionStrategy''LeveledCompactionStrategy''TimeWindowCompactionStrategy'。可以通过将完整类名指定为字符串常量来提供自定义策略。其余子选项取决于所选的类。默认类支持的子选项是

选项 支持的压缩策略 默认值 说明

enabled

all

true

一个布尔值,表示是否应启用压缩。

tombstone_threshold

all

0.2

一个比率,如果 sstable 中可 GC 的墓碑超过所有包含列的该比率,则将压缩该 sstable(不带其他 sstable),以清除这些墓碑。

tombstone_compaction_interval

all

1 天

在考虑 sstable 创建时间的 tombstone compaction'' 之前等待的最短时间,其中 tombstone compaction'' 是在 sstable 中可 GC 的墓碑多于 tombstone_threshold 时触发的压缩。

unchecked_tombstone_compaction

all

false

将此设置为 true 将启用更激进的墓碑压缩 - 单个 sstable 墓碑压缩将在不检查其成功可能性有多大的情况下运行。

min_sstable_size

SizeTieredCompactionStrategy

50MB

按大小分层的策略将要压缩的 SSTable 分组到存储桶中。存储桶对大小相差不到 50% 的 SSTable 进行分组。但是,对于小尺寸,这会导致分桶过于细化。min_sstable_size 定义一个大小阈值(以字节为单位),低于该阈值的所有 SSTable 都属于一个唯一存储桶

min_threshold

SizeTieredCompactionStrategy

4

启动小压缩所需的最小 SSTable 数量。

max_threshold

SizeTieredCompactionStrategy

32

一个小的压缩处理的最大 SSTable 数量。

bucket_low

SizeTieredCompactionStrategy

0.5

如果 sstable 的大小在 [average_size * bucket_low, average_size * bucket_high ] 范围内,则按大小分层的 sstable 将其视为在同一存储桶中(即默认情况下,sstable 的大小最多相差 50%)

bucket_high

SizeTieredCompactionStrategy

1.5

大小分层将 sstable 视为在同一存储桶中,如果其大小在 [average_size * bucket_low, average_size * bucket_high ] 范围内(即默认组 sstable,其大小最多相差 50%)。

sstable_size_in_mb

LeveledCompactionStrategy

5MB

分层策略中 sstable 的目标大小(以 MB 为单位)。请注意,虽然 sstable 大小应保持小于或等于 sstable_size_in_mb,但在压缩期间,给定分区键的数据绝不会拆分为 2 个 sstable,因此可能会出现较大的 sstable。

timestamp_resolution

TimeWindowCompactionStrategy

MICROSECONDS

插入数据时使用的 timestamp 分辨率,可以是 MILLISECONDS、MICROSECONDS 等(Java TimeUnit 应可理解) - 除非您使用 USING TIMESTAMP(或直接在客户端中使用等效项)进行突变,否则不要更改此项。

compaction_window_unit

TimeWindowCompactionStrategy

DAYS

用于窗口大小的 Java TimeUnit,与 compaction_window_size 结合设置。必须为 DAYS、HOURS、MINUTES 之一。

compaction_window_size

TimeWindowCompactionStrategy

1

组成时间窗口的 compaction_window_unit 单位数。

unsafe_aggressive_sstable_expiration

TimeWindowCompactionStrategy

false

过期 sstable 将被删除,而无需检查其数据是否正在对其他 sstable 进行影子备份。这是一个潜在的危险选项,可能导致数据丢失或已删除的数据重新出现,超出了 unchecked_tombstone_compaction 对单个 sstable 压缩所做的操作。由于存在风险,还必须使用 -Dcassandra.unsafe_aggressive_sstable_expiration=true 启动 jvm。

压缩选项

对于 compression 属性,以下子选项可用

选项 默认值 说明

class

LZ4Compressor

要使用的压缩算法。默认压缩器为:LZ4Compressor、SnappyCompressor 和 DeflateCompressor。使用 'enabled' : false 禁用压缩。可以通过指定完全类名作为 字符串常量 来提供自定义压缩器。

enabled

true

默认情况下启用压缩。要禁用它,请将 enabled 设置为 false

chunk_length_in_kb

64KB

磁盘上的 SSTable 按块进行压缩(以允许随机读取)。这定义了所述块的大小(以 KB 为单位)。较大的值可能会提高压缩率,但会增加从磁盘读取数据的最小大小。

缓存选项

对于 caching 属性,以下子选项可用

选项 默认值 说明

keys

ALL

是否为此表缓存键(`key cache'')。有效值为:`ALL` 和 `NONE`。

rows_per_partition

NONE

每个分区要缓存的行数(`row cache'')。如果指定整数 `n`,则将缓存分区的首 `n` 个查询行。其他可能的选项是 `ALL`,以缓存查询分区的全部行,或 `NONE` 以禁用行缓存。

其他注意事项
  • 插入 / 更新 给定行时,并非所有列都需要定义(密钥部分除外),并且缺失的列在磁盘上不占用空间。此外,添加新列(参见 ALTER TABLE)是一个常量时间操作。因此,在创建表时无需尝试预测未来使用情况(或在没有预测时感到遗憾)。

ALTER TABLE

语法

bc(syntax)..
::= ALTER (TABLE | COLUMNFAMILY) (IF EXISTS)?

::= ADD (IF NOT EXISTS)?
| ADD (IF NOT EXISTS)? ( ( , )* )
| DROP (IF EXISTS)?
| DROP (IF EXISTS)? ( ( , )* )
| RENAME (IF EXISTS)? TO (AND TO)*
| WITH ( AND )*
p.
样本

bc(sample)..
ALTER TABLE addamsFamily

ALTER TABLE addamsFamily
ADD gravesite varchar;

ALTER TABLE addamsFamily
WITH comment = A most excellent and useful column family';
p.
`ALTER` 语句用于操作表定义。它允许添加新列、删除现有列或更新表选项。与创建表一样,`ALTER COLUMNFAMILY` 被允许作为 `ALTER TABLE` 的别名。如果表不存在,该语句将返回一个错误,除非使用了 `IF EXISTS`,在这种情况下,该操作将是一个空操作。

<tablename> 是表名,前面可以加上键空间名称。<instruction> 定义要执行的更改

  • ADD:向表中添加新列。新列的 <identifier> 不能与现有列冲突。此外,不能向使用 COMPACT STORAGE 选项定义的表中添加列。如果新列已经存在,该语句将返回一个错误,除非使用了 `IF NOT EXISTS`,在这种情况下,该操作将是一个空操作。

  • DROP:从表中删除一列。已删除的列将立即在查询中不可用,并且将来不会包含在压缩的 sstable 中。如果重新添加一列,查询将不会返回在该列上次删除之前写入的值。假设时间戳表示实际时间,因此如果不是这种情况,则不应读取先前删除的列。不能从使用 COMPACT STORAGE 选项定义的表中删除列。如果已删除的列不存在,该语句将返回一个错误,除非使用了 `IF EXISTS`,在这种情况下,该操作将是一个空操作。

  • RENAME 表的主键列。非主键列不能重命名。此外,不允许将列重命名为另一个已经存在的名称。重要的是要记住,重命名的列不应具有从属的二级索引。如果重命名的列不存在,该语句将返回一个错误,除非使用了 `IF EXISTS`,在这种情况下,该操作将是一个空操作。

  • WITH:允许更新表的选项。支持的 <option>(和语法)与 CREATE TABLE 语句相同,但 COMPACT STORAGE 不受支持。请注意,设置任何 compaction 子选项都会清除所有以前的 compaction 选项,因此如果您想保留它们,则需要重新指定所有子选项。相同的注意事项适用于 compression 子选项集。

CQL 类型兼容性

CQL 数据类型只能按以下表格转换。

数据类型可以更改为 数据类型

timestamp

bigint

ascii, bigint, boolean, date, decimal, double, float, inet, int, smallint, text, time, timestamp, timeuuid, tinyint, uuid, varchar, varint

blob

int

date

ascii, varchar

text

bigint

time

bigint

timestamp

timeuuid

uuid

ascii, text

varchar

bigint, int, timestamp

varint

群集列有更严格的要求,只允许以下转换。

数据类型可以更改为 数据类型

ascii, text, varchar

blob

ascii, varchar

text

ascii, text

varchar

DROP TABLE

语法

bc(syntax). ::= DROP TABLE ( IF EXISTS )?

样本

bc(sample). DROP TABLE worldSeriesAttendees;

DROP TABLE 语句会导致立即不可逆地删除一张表,包括其中包含的所有数据。对于表创建,允许将 DROP COLUMNFAMILY 作为 DROP TABLE 的别名。

如果表不存在,该语句将返回一个错误,除非使用 IF EXISTS,在这种情况下,该操作将为无操作。

TRUNCATE

语法

bc(语法)。::= TRUNCATE (TABLE | COLUMNFAMILY)?

样本

bc(示例)。TRUNCATE superImportantData;

TRUNCATE 语句永久删除表中的所有数据。

CREATE INDEX

CREATE INDEX 语句用于为给定表中给定(现有)列创建新的二级索引。如果需要,可以在 ON 关键字之前指定索引本身的名称。

语法

bc(syntax)..
::= CREATE (CUSTOM)?INDEX (IF NOT EXISTS)?()?
ON `(' `)'
(USING (WITH OPTIONS = )?)?

::=
| keys( )
p.
样本

bc(sample).
CREATE INDEX userIndex ON NerdMovies (user);
CREATE INDEX ON Mutants (abilityId);
CREATE INDEX ON users (keys(favs));
CREATE INDEX ON users (age) USING 'sai';
CREATE CUSTOM INDEX ON users (email) USING `path.to.the.IndexClass';
CREATE CUSTOM INDEX ON users (email) USING `path.to.the.IndexClass' WITH OPTIONS = \{’storage’: `/mnt/ssd/indexes/'};

如果列中已存在数据,它将异步编入索引。创建索引后,列的新数据将在插入时自动编入索引。尝试创建已存在的索引将返回一个错误,除非使用了 IF NOT EXISTS 选项。如果使用了该选项,如果索引已存在,该语句将为无操作。

索引类型

USING 关键字可以选择指定索引类型。有两种内置类型

  • legacy_local_table - (默认)旧式二级索引,实现为隐藏的本地表

  • sai - “存储附加”索引,通过优化的 SSTable/Memtable 附加索引实现

要创建自定义索引,必须指定一个完全限定的类名。

映射键上的索引

在为映射列创建索引时,你可以编入索引的键或值。如果列标识符放置在 keys() 函数中,索引将位于映射键上,允许你在 WHERE 子句中使用 CONTAINS KEY。否则,索引将位于映射值上。

DROP INDEX

语法

bc(语法)。::= DROP INDEX (IF EXISTS)?( `.' )?

样本

bc(sample)..
DROP INDEX userIndex;

DROP INDEX userkeyspace.address_index;
p.
DROP INDEX 语句用于删除现有的二级索引。该语句的参数是索引名称,它可以选择指定索引的键空间。

如果索引不存在,该语句将返回一个错误,除非使用 IF EXISTS,在这种情况下,该操作将为无操作。

CREATE MATERIALIZED VIEW

语法

bc(syntax)..
::= CREATE MATERIALIZED VIEW (IF NOT EXISTS)?AS
SELECT ( `(' ( `,' ) * `)' | `' )
FROM
(WHERE)?
PRIMARY KEY `(' ( `,' )
`)'
( WITH ( AND )* )?
p.
样本

bc(sample)..
CREATE MATERIALIZED VIEW monkeySpecies_by_population AS
SELECT *
FROM monkeySpecies
WHERE population IS NOT NULL AND species IS NOT NULL
PRIMARY KEY (population, species)
带注释=允许按种群查询,而不是物种';
p.
`CREATE MATERIALIZED VIEW` 语句创建一个新的物化视图。每个此类视图都是一组,对应于 `SELECT` 语句中指定的底层或基础表中存在的行。无法直接更新物化视图,但对基础表的更新将导致视图中相应的更新。

尝试创建已存在的物化视图将返回错误,除非使用 `IF NOT EXISTS` 选项。如果使用该选项,如果物化视图已存在,该语句将为无操作。

WHERE 子句

<where-clause> 类似于 SELECT 语句的 where 子句,但有少许差异。首先,where 子句必须包含一个表达式,该表达式不允许视图主键中的列中存在 NULL 值。如果不需要其他限制,可以使用 IS NOT NULL 表达式来实现此目的。其次,只有基础表主键中的列才能使用除 IS NOT NULL 以外的表达式进行限制。(请注意,第二个限制将来可能会取消。)

ALTER MATERIALIZED VIEW

语法

bc(syntax). ::= ALTER MATERIALIZED VIEW
WITH ( AND )*

ALTER MATERIALIZED VIEW 语句允许更新选项;这些选项与 CREATE TABLE 的选项相同。

DROP MATERIALIZED VIEW

语法

bc(syntax). ::= DROP MATERIALIZED VIEW ( IF EXISTS )?

样本

bc(sample). DROP MATERIALIZED VIEW monkeySpecies_by_population;

DROP MATERIALIZED VIEW 语句用于删除现有的物化视图。

如果物化视图不存在,该语句将返回错误,除非使用了 IF EXISTS,在这种情况下,该操作为无操作。

CREATE TYPE

语法

bc(syntax)..
::= CREATE TYPE ( IF NOT EXISTS )?
`(' ( `,' )* `)'

::= ( `.' )?

::=

样本

bc(sample)..
CREATE TYPE address (
street_name text,
street_number int,
city text,
state text,
zip int
)

CREATE TYPE work_and_home_addresses (
home_address address,
work_address address
)
p.
CREATE TYPE 语句创建一个新的用户定义类型。每个类型都是一组已命名、已键入的字段。字段类型可以是任何有效类型,包括集合和其他现有的用户定义类型。

尝试创建已存在的类型将导致错误,除非使用 IF NOT EXISTS 选项。如果使用该选项,如果类型已存在,该语句将为无操作。

<typename>

有效的类型名称是标识符。不能使用现有的 CQL 类型和 保留类型名称

如果仅提供类型名称,则使用当前键空间创建类型(请参见 USE)。如果它前面带有现有的键空间名称,则在指定键空间中创建类型,而不是在当前键空间中创建类型。

ALTER TYPE

语法

bc(syntax)..
::= ALTER TYPE (IF EXISTS)?

::= ADD (IF NOT EXISTS)?
| RENAME (IF EXISTS)? TO ( AND TO )*
p.
样本

bc(sample)..
ALTER TYPE address ADD country text

ALTER TYPE address RENAME zip TO zipcode AND street_name TO street
p.
ALTER TYPE 语句用于操作类型定义。它允许添加新字段、重命名现有字段或更改现有字段的类型。如果类型不存在,该语句将返回错误,除非使用了 IF EXISTS,在这种情况下,该操作为无操作。

DROP TYPE

语法

bc(syntax)..
::= DROP TYPE ( IF EXISTS )?
p.
DROP TYPE 语句会导致立即永久删除类型。尝试删除仍在被其他类型或表使用的类型将导致错误。

如果类型不存在,将返回错误,除非使用了 IF EXISTS,在这种情况下,操作为无操作。

CREATE TRIGGER

语法

bc(syntax)..
::= CREATE TRIGGER ( IF NOT EXISTS )? ( )?
ON
USING

样本

bc(sample).
CREATE TRIGGER myTrigger ON myTable USING `org.apache.cassandra.triggers.InvertedIndex';

构成触发器的实际逻辑可以用任何 Java (JVM) 语言编写,并且存在于数据库外部。将触发器代码放在 Cassandra 安装目录的 lib/triggers 子目录中,它会在集群启动期间加载,并存在于参与集群的每个节点上。在表上定义的触发器会在请求的 DML 语句发生之前触发,从而确保事务的原子性。

DROP TRIGGER

语法

bc(syntax)..
::= DROP TRIGGER ( IF EXISTS )? ( )?
ON
p.
样本

bc(sample).
DROP TRIGGER myTrigger ON myTable;

DROP TRIGGER 语句删除使用 CREATE TRIGGER 创建的触发器的注册。

CREATE FUNCTION

语法

bc(syntax)..
::= CREATE ( OR REPLACE )?
FUNCTION ( IF NOT EXISTS )?
( `.' )?
`(' ( `,' )* `)'
( CALLED | RETURNS NULL ) ON NULL INPUT
RETURNS
LANGUAGE
AS

样本

bc(sample).
CREATE OR REPLACE FUNCTION somefunction
( somearg int, anotherarg text, complexarg frozen, listarg list )
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS + ;
CREATE FUNCTION akeyspace.fname IF NOT EXISTS
( someArg int )
CALLED ON NULL INPUT
RETURNS text
LANGUAGE java
AS + ;

CREATE FUNCTION 创建或替换用户定义函数。

函数签名

签名用于区分各个函数。签名包括

  1. 完全限定的函数名 - 即 键空间 加上 函数名

  2. 所有参数类型的连接列表

请注意,键空间名称、函数名称和参数类型受默认命名约定和大写/小写敏感规则的约束。

带有可选 OR REPLACE 关键字的 CREATE FUNCTION 要么创建函数,要么用具有相同签名的现有函数替换它。如果没有 OR REPLACECREATE FUNCTION 会在已经存在具有相同签名的函数时失败。

必须为每个函数定义使用 null 值时的调用行为。有两个选项

  1. RETURNS NULL ON NULL INPUT 声明如果任何输入参数为 null,函数将始终返回 null

  2. CALLED ON NULL INPUT 声明函数将始终执行。

如果使用了可选的 IF NOT EXISTS 关键字,则只有在具有相同签名的其他函数不存在时才会创建函数。

OR REPLACEIF NOT EXIST 不能一起使用。

函数属于键空间。如果在 <function-name> 中未指定键空间,则使用当前键空间(即使用 USE 语句指定的键空间)。无法在某个系统键空间中创建用户自定义函数。

有关详细信息,请参阅 用户自定义函数 部分。

DROP FUNCTION

语法

bc(syntax)..
::= DROP FUNCTION ( IF EXISTS )?
( `.' )?
( `(' ( `,' )* `)' )?

样本

bc(sample).
DROP FUNCTION myfunction;
DROP FUNCTION mykeyspace.afunction;
DROP FUNCTION afunction ( int );
DROP FUNCTION afunction ( text );

DROP FUNCTION 语句删除使用 CREATE FUNCTION 创建的函数。
如果存在多个同名但签名不同的函数(重载函数),则必须指定要删除函数的参数类型(签名)。

带有可选 IF EXISTS 关键字的 DROP FUNCTION 会在函数存在时删除该函数。

CREATE AGGREGATE

语法

bc(syntax)..
::= CREATE ( OR REPLACE )?
AGGREGATE ( IF NOT EXISTS )?
( `.' )?
`(' ( `,' )* `)'
SFUNC
STYPE
( FINALFUNC )?
( INITCOND )?
p.
样本

bc(sample).
CREATE AGGREGATE myaggregate ( val text )
SFUNC myaggregate_state
STYPE text
FINALFUNC myaggregate_final
INITCOND `foo';

有关完整示例,请参阅 用户自定义聚合 部分。

CREATE AGGREGATE 创建或替换用户自定义聚合。

带有可选 OR REPLACE 关键字的 CREATE AGGREGATE 既可以创建聚合,也可以替换具有相同签名的现有聚合。如果已存在具有相同签名的聚合,则不带 OR REPLACECREATE AGGREGATE 会失败。

带有可选 IF NOT EXISTS 关键字的 CREATE AGGREGATE 会在聚合不存在时创建聚合。

OR REPLACEIF NOT EXIST 不能一起使用。

聚合属于键空间。如果在 <aggregate-name> 中未指定键空间,则使用当前键空间(即使用 USE 语句指定的键空间)。无法在某个系统键空间中创建用户自定义聚合。

用户自定义聚合的签名遵循与 用户自定义函数 相同的 规则

STYPE 定义状态值类型,必须指定。

可选的 INITCOND 定义聚合的初始状态值。其默认值为 null。对于使用 RETURNS NULL ON NULL INPUT 声明的状态函数,必须指定非 nullINITCOND

SFUNC 引用一个现有函数,以用作状态修改函数。状态函数的第一个参数类型必须与 STYPE 匹配。状态函数的其余参数类型必须与聚合函数的参数类型匹配。对于使用 RETURNS NULL ON NULL INPUT 声明并使用 null 调用的状态函数,不会更新状态。

可选的 FINALFUNC 在返回聚合结果之前调用。它必须只接受一个类型为 STYPE 的参数。FINALFUNC 的返回类型可以是不同的类型。使用 RETURNS NULL ON NULL INPUT 声明的最终函数表示如果最后一个状态为 null,则聚合的返回值将为 null

如果未定义 FINALFUNC,聚合函数的总体返回类型为 STYPE。如果定义了 FINALFUNC,它就是该函数的返回类型。

请参阅 用户定义聚合 部分以了解更多信息。

DROP AGGREGATE

语法

bc(syntax)..
::= DROP AGGREGATE ( IF EXISTS )?
( `.' )?
( `(' ( `,' )* `)' )?
p.

样本

bc(sample).
DROP AGGREGATE myAggregate;
DROP AGGREGATE myKeyspace.anAggregate;
DROP AGGREGATE someAggregate ( int );
DROP AGGREGATE someAggregate ( text );

DROP AGGREGATE 语句删除使用 CREATE AGGREGATE 创建的聚合。如果有多个具有相同名称但签名不同的聚合(重载的聚合),则必须指定要删除的聚合的参数类型。

带有可选 IF EXISTS 关键字的 DROP AGGREGATE 会删除存在的聚合,如果具有该签名的函数不存在,则不执行任何操作。

用户自定义聚合的签名遵循与 用户自定义函数 相同的 规则

数据操作

INSERT

语法

bc(syntax)..
::= INSERT INTO
( ( VALUES )
| ( JSON ))
( IF NOT EXISTS )?
( USING ( AND )* )?

::= `(' ( `,' )* `)'

::= `(' ( `,' )* `)'

::= TIMESTAMP
| TTL
p.
样本

bc(sample)..
INSERT INTO NerdMovies (movie, director, main_actor, year)
VALUES (`Serenity', `Joss Whedon', `Nathan Fillion', 2005)
USING TTL 86400;

INSERT INTO NerdMovies JSON \{movie'': Serenity'', director'': Joss Whedon'', ``year'': 2005}'
p.
`INSERT
语句为表中的给定行写入一列或多列。请注意,由于行由其 PRIMARY KEY 标识,因此必须至少指定组成它的列。使用 VALUES 语法时,必须提供要插入到的列列表。使用 JSON 语法时,它们是可选的。有关更多详细信息,请参阅 INSERT JSON 部分。

请注意,与 SQL 不同,INSERT 默认情况下不会检查行的先前存在:如果之前不存在行,则创建行,否则更新行。此外,没有办法知道发生了创建还是更新。

但是,可以使用 IF NOT EXISTS 条件仅在插入之前不存在行时才插入。但请注意,使用 IF NOT EXISTS 会产生不可忽略的性能开销(在内部,将使用 Paxos),因此应谨慎使用。

INSERT 的所有更新都以原子方式和隔离方式应用。

请参阅 UPDATE 部分以了解可用的 <option>,并参阅 集合 部分以了解 <collection-literal> 的用法。另请注意,INSERT 不支持计数器,而 UPDATE 支持。

UPDATE

语法

bc(syntax)..
::= UPDATE
( USING ( AND )* )?
SET ( `,' )*
WHERE
( IF ( AND condition )* )?

::= ='
| `=' (
+' | `-') ( | | )
| `=' `+'
| `[' `]' `='
| `.' `='

::=
| CONTAINS (KEY)?
| IN
| `[' `]'
| `[' `]' IN
| `.'
| `.' IN

::= `<' | `⇐' | `=' | `!=' | `>=' | `>'
::= ( | `(' ( ( `,' )* )? `)')

::= ( AND )*

::= ='
| `(' (
,' )* )' `='
| IN `(' ( ( `,' )* )? `)'
| IN
| `(' (
,' )* )' IN `(' ( ( `,' )* )? `)'
| `(' (
,' )* `)' IN

::= TIMESTAMP
| TTL
p.
样本

bc(sample)..
UPDATE NerdMovies USING TTL 400
SET director = `Joss Whedon',
main_actor = `Nathan Fillion',
year = 2005
WHERE movie = `Serenity';

UPDATE UserActions SET total = total + 2 WHERE user = B70DE1D0-9908-4AE3-BE34-5573E5B09F14 AND action = click';
p.
`UPDATE` 语句为表中的给定行写入一个或多个列。<where-clause> 用于选择要更新的行,并且必须包括构成 PRIMARY KEY 的所有列。其他列值通过 SET 关键字后的 <assignment> 指定。

请注意,与 SQL 不同,UPDATE 默认情况下不检查行的先前存在(除非通过使用 <condition>,请参见下文):如果之前不存在行,则创建该行,否则更新该行。此外,没有办法知道是否发生了创建或更新。

然而,可以通过 IF 对某些列使用条件,在这种情况下,除非满足条件,否则不会更新行。但是,请注意,使用 IF 条件会产生不可忽略的性能开销(在内部,Paxos 将被使用),因此应谨慎使用。

UPDATE 语句中,同一分区键内的所有更新都会以原子方式和隔离方式应用。

<assignment>c = c + 3 形式用于递增/递减计数器。'=' 符号后的标识符必须'=' 符号前的标识符相同(仅支持对计数器进行递增/递减,不支持分配特定值)。

<assignment>id = id + <collection-literal>id[value1] = value2 形式适用于集合。有关更多详细信息,请参阅 相关部分

<assignemt>id.field = <term> 形式用于设置非冻结用户定义类型上单个字段的值。

<options>

UPDATEINSERT 语句支持以下选项

  • TIMESTAMP:设置操作的时间戳。如果未指定,协调器将在语句执行开始时使用当前时间(以微秒为单位)作为时间戳。这通常是一个合适的默认值。

  • TTL:为插入的值指定可选的生存时间(以秒为单位)。如果设置,插入的值将在指定时间后自动从数据库中删除。请注意,TTL 涉及插入的值,而不是列本身。这意味着对列的任何后续更新也将重置 TTL(重置为该更新中指定的任何 TTL)。默认情况下,值永不过期。TTL 为 0 等效于没有 TTL。如果表具有 default_time_to_live,则 TTL 为 0 将删除插入或更新的值的 TTL。

DELETE

语法

bc(syntax)..
::= DELETE ( ( `,' )* )?
FROM
( USING TIMESTAMP )?
WHERE
( IF ( EXISTS | ( ( AND )*) ) )?

::=
| `[' `]'
| `.'

::= ( AND )*

::=
| (' (,' )* )'
| IN `(' ( ( `,' )* )? `)'
| IN
| `(' (
,' )* )' IN `(' ( ( `,' )* )? `)'
| `(' (
,' )* `)' IN

::= `=' | `<' | `>' | `⇐' | `>='
::= ( | `(' ( ( `,' )* )? `)')

::= ( | `!=')
| CONTAINS (KEY)?
| IN
| `[' `]' ( | `!=')
| `[' `]' IN
| `.' ( | `!=')
| `.' IN

样本

bc(sample)..
DELETE FROM NerdMovies USING TIMESTAMP 1240003134 WHERE movie = `Serenity';

DELETE phone FROM Users WHERE userid IN (C73DE1D3-AF08-40F3-B124-3FF3E5109F22, B70DE1D0-9908-4AE3-BE34-5573E5B09F14);
p.
DELETE 语句删除列和行。如果在 DELETE 关键字后直接提供列名,则仅从 <where-clause> 指示的行中删除这些列。<selection> 中的 id[value] 语法用于非冻结集合(有关更多详细信息,请参阅 集合部分)。id.field 语法用于删除非冻结用户定义类型。否则,将删除整行。<where-clause> 指定要删除哪些行。可以使用 IN 子句通过一条语句删除多行。可以使用不等式运算符(例如 >=)删除一系列行。

DELETE 支持 TIMESTAMP 选项,其语义与 UPDATE 语句相同。

DELETE 语句中,同一分区键内的所有删除操作都会以原子方式和隔离方式应用。

可以通过使用 IF 子句对 DELETE 操作进行条件设置,类似于 UPDATEINSERT 语句。但是,与 INSERTUPDATE 语句一样,这将产生不可忽略的性能成本(在内部,将使用 Paxos),因此应谨慎使用。

BATCH

语法

bc(syntax)..
::= BEGIN ( UNLOGGED | COUNTER ) BATCH
( USING ( AND )* )?
( `;' )*
APPLY BATCH

::=
|
|

::= TIMESTAMP
p.
样本

bc(sample).
BEGIN BATCH
INSERT INTO users (userid, password, name) VALUES (`user2', `ch@ngem3b', `second user');
UPDATE users SET password = `ps22dhds' WHERE userid = `user3';
INSERT INTO users (userid, password) VALUES (`user4', `ch@ngem3c');
DELETE name FROM users WHERE userid = `user1';
APPLY BATCH;

BATCH 语句将多个修改语句(插入/更新和删除)组合到一条语句中。它有几个用途

  1. 在批处理多个更新时,它可以节省客户端和服务器(有时是服务器协调器和副本)之间的网络往返。

  2. 属于给定分区键的 BATCH 中的所有更新都以隔离方式执行。

  3. 默认情况下,批处理中的所有操作都作为 LOGGED 执行,以确保所有突变最终完成(或没有一个完成)。有关更多详细信息,请参阅 UNLOGGED 的注释。

请注意

  • BATCH 语句只能包含 UPDATEINSERTDELETE 语句。

  • 批处理不是 SQL 事务的完全类似物。

  • 如果未为每个操作指定时间戳,则所有操作都将使用相同的时间戳应用。由于 Cassandra 在 时间戳相同时进行冲突解决程序,因此操作的应用顺序可能与在 BATCH 语句中列出的顺序不同。要强制执行特定的操作顺序,您必须指定每个操作的时间戳。

UNLOGGED

默认情况下,Cassandra 使用批处理日志来确保批处理中的所有操作最终完成,或者没有一个操作完成(但请注意,操作仅在单个分区内隔离)。

当批处理跨越多个分区时,批处理原子性会产生性能损失。如果您不想承担此损失,则可以使用 UNLOGGED 选项告诉 Cassandra 跳过批处理日志。如果使用了 UNLOGGED 选项,则失败的批处理可能会使补丁仅部分应用。

COUNTER

对于批次计数器更新,使用 COUNTER 选项。与 Cassandra 中的其他更新不同,计数器更新不是幂等的。

<option>

BATCH 同时支持 TIMESTAMP 选项,其语义与 UPDATE 语句中描述的语义类似(时间戳适用于批次中的所有语句)。但是,如果使用,则 不得 在批次中的语句中使用 TIMESTAMP

查询

SELECT

语法

bc(syntax)..
::= SELECT ( JSON )?
FROM
( WHERE )?
( GROUP BY )?
( ORDER BY )?
( PER PARTITION LIMIT )?
( LIMIT )?
( ALLOW FILTERING )?

::= DISTINCT?

::= (AS )? ( `,' (AS )? )*
| `*'

::=
|
| WRITETIME (' `)'
| MAXWRITETIME `(' `)'
| COUNT `(' `' `)'
| TTL `(' `)'
| CAST `(' AS `)'
| `(' ( (
,' ))? `)'
| `.'
| `[' `]'
| `[' ? .. ? `]'

::= ( AND )*

::=
| (' (,' )* )'
| IN `(' ( ( `,' )* )? `)'
| `(' (
,' )* `)' IN `(' ( ( `,' )* )? `)'
| TOKEN `(' ( `,' )* `)'

::= =' | `<' | `>' | `⇐' | `>=' | CONTAINS | CONTAINS KEY
::= (
,' )*
::= ( ,' )*
::= ( ASC | DESC )?
::= `(' (
,' )* `)'
p.
样本

bc(sample)..
SELECT name, occupation FROM users WHERE userid IN (199, 200, 207);

SELECT JSON name, occupation FROM users WHERE userid = 199;

SELECT name AS user_name, occupation AS user_occupation FROM users;

SELECT time, value
FROM events
WHERE event_type = `myEvent'
AND time > `2011-02-03'
AND time ⇐ `2012-01-01'

SELECT COUNT (*) FROM users;

SELECT COUNT (*) AS user_count FROM users;

SELECT 语句读取表中一行或多行的一列或多列。它返回一个行结果集,其中每行包含与查询相对应的列集合。如果使用 JSON 关键字,则每行的结果将只包含一个名为 `json'' 的列。有关详细信息,请参阅 `SELECT JSON 部分。

<select-clause>

<select-clause> 确定需要在结果集中查询和返回哪些列。它由逗号分隔的列表或通配符 (*) 组成,以选择为表定义的所有列。请注意,对于通配符 SELECT 查询,返回的列的顺序未指定,并且不能保证在 Cassandra 版本之间保持稳定。

<selector> 是要检索的列名或一个或多个 <term><function>。允许的函数与 <term> 相同,并在 函数部分 中进行了描述。除了这些通用函数之外,WRITETIMEMAXWRITETIME(分别为 TTL)函数允许选择列插入的时间戳(分别为列的生存时间(以秒为单位)(或如果列没有设置过期时间,则为 null))和 CAST 函数可用于将一种数据类型转换为另一种数据类型。WRITETIMETTL 函数不能用于多单元格列,例如非冻结集合或非冻结用户定义类型。

此外,可以使用 [ <term> ] 选择映射和集合的各个值。对于映射,如果存在这样的条目,这将返回与键对应的值。对于集合,如果存在,这将返回所选的键,因此主要是一种检查元素是否存在的方法。还可以使用 `[ <term> …​ <term> `] 选择集合或映射的切片,其中可以省略两个边界。

可以使用 AS 关键字对任何 <selector> 进行别名处理(请参见示例)。请注意,<where-clause><order-by> 子句应按其原始名称引用列,而不是按其别名引用列。

COUNT 关键字可以与括在 * 中的括号一起使用。如果是这样,查询将返回单个结果:与查询匹配的行数。请注意,COUNT(1) 受支持作为别名。

<where-clause>

<where-clause> 指定必须查询哪些行。它由 PRIMARY KEY 的一部分的列上的关系组成,和/或在它们上定义了 辅助索引

并非所有关系都允许在查询中。例如,分区键上的非相等关系(其中 IN 被视为相等关系)不受支持(但请参见下面使用 TOKEN 方法对分区键执行非相等查询)。此外,对于给定的分区键,群集列会引起行的排序,并且对它们的限制关系只能选择一组连续的(对于排序)行。例如,给定

bc(sample).
CREATE TABLE posts (
userid text,
blog_title text,
posted_at timestamp,
entry_title text,
content text,
category int,
PRIMARY KEY (userid, blog_title, posted_at)
)

允许以下查询

bc(sample).
SELECT entry_title, content FROM posts WHERE userid=`john doe' AND blog_title=`John'`s Blog' AND posted_at >= `2012-01-01' AND posted_at < `2012-01-31'

但以下查询不允许,因为它没有选择一组连续的行(并且我们假设没有设置辅助索引)

bc(sample).
SELECT entry_title, content FROM posts WHERE userid=`john doe' AND posted_at >= `2012-01-01' AND posted_at < `2012-01-31'

在指定关系时,可以在 PARTITION KEY 列上使用 TOKEN 函数进行查询。在这种情况下,将根据其 PARTITION_KEY 的令牌而不是值来选择行。请注意,键的令牌取决于所使用的分区器,特别是 RandomPartitioner 不会产生有意义的顺序。还要注意,排序分区器始终按字节对令牌值进行排序(因此,即使分区键的类型为 int,token(-1) > token(0))。示例

bc(sample).
SELECT * FROM posts WHERE token(userid) > token(`tom') AND token(userid) < token(`bob')

此外,IN 关系仅允许在分区键的最后一列和完整主键的最后一列上使用。

还可以使用元组表示法将关系中的`group'' `CLUSTERING COLUMNS`组合在一起。例如

bc(sample).
SELECT * FROM posts WHERE userid=`john doe' AND (blog_title, posted_at) > (`John'`s Blog', `2012-01-01')

将请求在群集顺序中将`John’s Blog'' 作为 `blog_tile`2012-01-01' 作为 `posted_at`的记录之后排序的所有行。特别是,只要它们的blog_title > 'John''s Blog',就会返回post_at ⇐ '2012-01-01'的记录,而对于

bc(sample).
SELECT * FROM posts WHERE userid=`john doe' AND blog_title > `John'`s Blog' AND posted_at > `2012-01-01'

元组表示法还可以用于CLUSTERING COLUMNS上的IN子句

bc(sample).
SELECT * FROM posts WHERE userid=`john doe' AND (blog_title, posted_at) IN `John'`s Blog', `2012-01-01), (’Extreme Chess', `2014-06-01'

CONTAINS运算符只能用于集合列(列表、集合和映射)。对于映射,CONTAINS适用于映射值。CONTAINS KEY运算符只能用于映射列,并适用于映射键。

<order-by>

ORDER BY选项允许选择返回结果的顺序。它以列名列表作为参数,以及列的顺序(ASC表示升序,DESC表示降序,省略顺序等同于ASC)。当前可能的顺序是有限的(取决于表CLUSTERING ORDER

  • 如果表在没有任何特定CLUSTERING ORDER的情况下被定义,那么允许的顺序是群集列引起的顺序及其逆序。

  • 否则,允许的顺序是CLUSTERING ORDER选项的顺序及其逆序。

<group-by>

GROUP BY选项允许将所有对于一组列共享相同值的选择行浓缩到一行中。

使用GROUP BY选项,只能在分区键级别或群集列级别对行进行分组。因此,GROUP BY选项只接受主键顺序中的主键列名作为参数。如果主键列受到相等性限制,则不需要它出现在GROUP BY子句中。

聚合函数将为每个组生成一个单独的值。如果没有指定GROUP BY子句,聚合函数将为所有行生成一个值。

如果在包含GROUP BY的语句中选择列而没有聚合函数,则将返回每个组中遇到的第一个值。

LIMITPER PARTITION LIMIT

SELECT语句的LIMIT选项限制查询返回的行数,而PER PARTITION LIMIT选项限制查询为给定分区返回的行数。请注意,两种类型的限制都可以在同一个语句中使用。

ALLOW FILTERING

默认情况下,CQL只允许不涉及filtering'' 服务器端的select查询,即我们知道所有(实时)读取的记录将(部分)返回在结果集中。其原因是这些非过滤''查询具有可预测的性能,因为它们将在与查询返回的数据量成正比的时间内执行(可以通过LIMIT控制)。

ALLOW FILTERING 选项允许明确允许(一些)需要过滤的查询。请注意,使用 ALLOW FILTERING 的查询可能因此具有不可预测的性能(对于上述定义),即,即使是选择少量记录的查询也可能表现出取决于集群中存储的数据总量的性能。

例如,考虑以下包含用户个人资料及其出生年份(带有辅助索引)和居住国家的表

bc(sample)..
CREATE TABLE users (
username text PRIMARY KEY,
firstname text,
lastname text,
birth_year int,
country text
)

CREATE INDEX ON users(birth_year);
p.

那么以下查询有效

bc(sample).
SELECT * FROM users;
SELECT firstname, lastname FROM users WHERE birth_year = 1981;

因为在这两种情况下,Cassandra 保证这些查询的性能将与返回的数据量成正比。特别是,如果没有用户出生于 1981 年,则第二个查询的性能将不取决于数据库中存储的用户个人资料的数量(至少不是直接取决于:由于辅助索引实现考虑因素,此查询可能仍然取决于集群中的节点数,而节点数间接取决于存储的数据量。然而,节点数将始终比存储的用户个人资料的数量低多个数量级)。当然,这两个查询实际上都可能返回非常大的结果集,但始终可以通过添加 LIMIT 来控制返回的数据量。

但是,将拒绝以下查询

bc(sample).
SELECT firstname, lastname FROM users WHERE birth_year = 1981 AND country = `FR';

因为 Cassandra 无法保证即使查询结果很小,它也不必扫描大量数据。通常,它将扫描所有出生于 1981 年的用户索引条目,即使实际上只有少数用户来自法国。但是,如果您`知道自己在做什么'',您可以使用 `ALLOW FILTERING 强制执行此查询,因此以下查询有效

bc(sample).
SELECT firstname, lastname FROM users WHERE birth_year = 1981 AND country = `FR' ALLOW FILTERING;

数据库角色

CREATE ROLE

语法

bc(syntax)..
::= CREATE ROLE ( IF NOT EXISTS )? ( WITH ( AND )* )?

::= PASSWORD =
| LOGIN =
| SUPERUSER =
| OPTIONS =
p.

样本

bc(sample).
CREATE ROLE new_role;
CREATE ROLE alice WITH PASSWORD = `password_a' AND LOGIN = true;
CREATE ROLE bob WITH PASSWORD = `password_b' AND LOGIN = true AND SUPERUSER = true;
CREATE ROLE carlos WITH OPTIONS = \{ `custom_option1' : `option1_value', `custom_option2' : 99 };

默认情况下,角色不拥有LOGIN 权限或SUPERUSER 状态。

数据库资源上的权限授予角色;资源类型包括键空间、表、函数和角色本身。可以将角色授予其他角色以创建分层权限结构;在这些层次结构中,权限和SUPERUSER 状态被继承,但LOGIN 权限不被继承。

如果角色具有LOGIN 权限,则客户端在连接时可以识别为该角色。在该连接期间,客户端将获得授予该角色的任何角色和权限。

只有具有数据库角色资源的CREATE 权限的客户端才能发出CREATE ROLE 请求(请参见下面的相关部分),除非客户端是SUPERUSER。Cassandra 中的角色管理是可插拔的,并且自定义实现可能仅支持所列选项的子集。

如果角色名称包含非字母数字字符,则应引用角色名称。

设置内部身份验证的凭据

使用 WITH PASSWORD 子句为内部身份验证设置密码,并将密码用单引号括起来。
如果尚未设置内部身份验证或角色没有LOGIN 权限,则 WITH PASSWORD 子句不是必需的。

有条件地创建角色

尝试创建现有角色会导致无效的查询条件,除非使用 IF NOT EXISTS 选项。如果使用该选项且角色存在,则该语句将为 no-op。

bc(sample).
CREATE ROLE other_role;
CREATE ROLE IF NOT EXISTS other_role;

ALTER ROLE

语法

bc(syntax)..
::= ALTER ROLE (IF EXISTS)? ( WITH ( AND )* )?

::= PASSWORD =
| LOGIN =
| SUPERUSER =
| OPTIONS =
p.

样本

bc(sample).
ALTER ROLE bob WITH PASSWORD = `PASSWORD_B' AND SUPERUSER = false;

如果角色不存在,该语句将返回错误,除非使用 IF EXISTS,在这种情况下,该操作将为 no-op。

执行 ALTER ROLE 语句的条件

  • 客户端必须具有 SUPERUSER 状态才能更改其他角色的 SUPERUSER 状态

  • 客户端不能更改其当前持有的任何角色的 SUPERUSER 状态

  • 客户端只能修改其在登录时标识的角色的某些属性(例如 PASSWORD

  • 要修改角色的属性,客户端必须被授予该角色的 ALTER 权限

DROP ROLE

语法

bc(syntax)..
::= DROP ROLE ( IF EXISTS )?
p.

样本

bc(sample).
DROP ROLE alice;
DROP ROLE IF EXISTS bob;

DROP ROLE 要求客户端对相关角色拥有 DROP 权限。此外,客户端不能 DROP 其在登录时标识的角色。最后,只有具有 SUPERUSER 状态的客户端才能 DROP 另一个 SUPERUSER 角色。
尝试删除不存在的角色会导致无效的查询条件,除非使用 IF EXISTS 选项。如果使用该选项且角色不存在,则该语句将为 no-op。

GRANT ROLE

语法

bc(syntax)。
::= GRANT TO

样本

bc(sample).
GRANT report_writer TO alice;

此语句将 report_writer 角色授予 alice。授予 report_writer 的任何权限也将被 alice 获取。
角色被建模为有向无环图,因此不允许循环授予。以下示例会导致错误条件

bc(sample).
GRANT role_a TO role_b;
GRANT role_b TO role_a;

bc(sample).
GRANT role_a TO role_b;
GRANT role_b TO role_c;
GRANT role_c TO role_a;

REVOKE ROLE

语法

bc(syntax)。
::= REVOKE FROM

样本

bc(sample).
REVOKE report_writer FROM alice;

此语句撤销 alicereport_writer 角色。alice 通过 report_writer 角色获取的任何权限也将被撤销。

LIST ROLES

语法

bc(syntax)。
::= LIST ROLES ( OF )? ( NORECURSIVE )?

样本

bc(sample).
LIST ROLES;

返回系统中所有已知角色,这需要对数据库角色资源具有 DESCRIBE 权限。

bc(sample).
LIST ROLES OF alice;

枚举授予 alice 的所有角色,包括通过传递获取的角色。

bc(sample).
LIST ROLES OF bob NORECURSIVE

列出直接授予 bob 的所有角色。

CREATE USER

在 Cassandra 2.2 中引入角色之前,身份验证和授权基于 USER 的概念。为了向后兼容,保留了旧语法,以 USER 为中心的语句成为 ROLE 为基础的同义词。

语法

bc(syntax)..
::= 创建用户(如果不存在)? (使用密码)? ()?

::= 超级用户
| 非超级用户
p.

样本

bc(sample).
使用密码 `password_a` 创建用户 alice 为超级用户;
使用密码 `password_b` 创建用户 bob 为非超级用户;

创建用户 等同于 创建角色,其中 登录 选项为 true。因此,以下语句对等效

bc(sample)..
使用密码 `password_a` 创建用户 alice 为超级用户;
使用密码 = `password_a` 和登录 = true 以及超级用户 = true 创建角色 alice;

如果不存在,则使用密码 `password_a` 创建用户 alice 为超级用户;
如果不存在,则使用密码 = `password_a` 和登录 = true 以及超级用户 = true 创建角色 alice;

使用密码 `password_a` 创建用户 alice 为非超级用户;
使用密码 = `password_a` 和登录 = true 以及超级用户 = false 创建角色 alice;

使用密码 `password_a` 创建用户 alice 为非超级用户;
CREATE ROLE alice WITH PASSWORD = `password_a' AND LOGIN = true;

使用密码 `password_a` 创建用户 alice;
CREATE ROLE alice WITH PASSWORD = `password_a' AND LOGIN = true;
p.

修改用户

语法

bc(syntax)..
::= 修改用户(如果存在)? (使用密码)? ()?

::= 超级用户
| 非超级用户
p.

bc(sample).
使用密码 `PASSWORD_A` 修改用户 alice;
将用户 bob 修改为超级用户;

如果用户不存在,则该语句将返回错误,除非使用 如果存在,在这种情况下,操作为无操作。

删除用户

语法

bc(syntax)..
::= 删除用户(如果存在)?
p.

样本

bc(sample).
删除用户 alice;
如果存在,则删除用户 bob;

列出用户

语法

bc(syntax)。
::= 列出用户;

样本

bc(sample).
列出用户;

此语句等效于

bc(sample).
LIST ROLES;

但仅具有 登录 权限的角色包含在输出中。

数据库标识

添加标识

语法

bc(syntax)..
::= 添加标识(如果不存在)? 到角色?

样本

bc(sample).
将标识 'id1' 添加到角色 'role1';

只有具有添加角色权限的用户才能添加标识

如果角色名称和标识名称包含非字母数字字符,则应引用它们。

有条件地添加标识

除非使用 如果不存在 选项,否则尝试添加现有标识会导致无效的查询条件。如果使用该选项且标识存在,则该语句为无操作。

bc(sample).
如果不存在,则添加标识 'id1' 到角色 'role1';

删除标识

语法

bc(syntax)..
::= 删除标识(如果存在)?
p.

样本

bc(sample).
删除标识 'testIdentity';
如果存在,则删除标识 'testIdentity';

只有具有删除角色权限的用户才能删除标识

除非使用 如果存在 选项,否则尝试删除不存在的标识会导致无效的查询条件。如果使用该选项且标识不存在,则该语句为无操作。

数据控制

权限

资源的权限授予角色;Cassandra 中有几种不同类型的资源,每种类型都以分层方式建模

  • 数据资源、键空间和表的层次结构具有以下结构:所有键空间键空间

  • 函数资源具有以下结构:所有函数键空间函数

  • 表示角色的资源具有以下结构:所有角色角色

  • 表示 JMX ObjectName 的资源(映射到 MBean/MXBean 集)具有以下结构:所有 MBEANMBEAN

权限可以在这些层次结构的任何级别授予,并且向下流动。因此,在链中较高的资源上授予权限会自动在所有较低资源上授予相同的权限。例如,在 KEYSPACE 上授予 SELECT 会自动在该 KEYSPACE 中的所有 TABLES 上授予该权限。同样,在 ALL FUNCTIONS 上授予权限会授予每个已定义函数权限,无论其作用域在哪个键空间中。也可以在作用域为特定键空间的所有函数上授予权限。

对权限的修改对现有客户端会话可见;也就是说,在权限更改后不必重新建立连接。

可用权限的完整集合是

  • CREATE

  • ALTER

  • DROP

  • SELECT

  • MODIFY

  • AUTHORIZE

  • DESCRIBE

  • EXECUTE

  • UNMASK

  • SELECT_MASKED

并非所有权限都适用于每种类型的资源。例如,EXECUTE 仅与函数或 mbean 相关;在表示表的资源上授予 EXECUTE 是没有意义的。尝试对无法应用权限的资源GRANT权限会导致错误响应。以下说明了哪些权限可以授予哪些类型的资源,以及该权限启用了哪些语句。

权限 资源 操作

CREATE

ALL KEYSPACES

CREATE KEYSPACE <br> 在任何键空间中CREATE TABLE

CREATE

KEYSPACE

在指定的键空间中CREATE TABLE

CREATE

ALL FUNCTIONS

在任何键空间中CREATE FUNCTION <br> 在任何键空间中CREATE AGGREGATE

CREATE

ALL FUNCTIONS IN KEYSPACE

在键空间中CREATE FUNCTION <br> 在键空间中CREATE AGGREGATE

CREATE

ALL ROLES

CREATE ROLE

ALTER

ALL KEYSPACES

ALTER KEYSPACE <br> 在任何键空间中ALTER TABLE

ALTER

KEYSPACE

ALTER KEYSPACE <br> 在键空间中ALTER TABLE

ALTER

TABLE

ALTER TABLE

ALTER

ALL FUNCTIONS

替换任何现有CREATE FUNCTION <br> 替换任何现有CREATE AGGREGATE

ALTER

ALL FUNCTIONS IN KEYSPACE

替换键空间中存在的CREATE FUNCTION <br> 替换键空间中存在的CREATE AGGREGATE

ALTER

FUNCTION

替换任何现有CREATE FUNCTION <br> 替换任何现有CREATE AGGREGATE

ALTER

ALL ROLES

在任何角色上ALTER ROLE

ALTER

ROLE

ALTER ROLE

DROP

ALL KEYSPACES

DROP KEYSPACE <br> 在任何键空间中DROP TABLE

DROP

KEYSPACE

在指定的键空间中DROP TABLE

DROP

TABLE

DROP TABLE

DROP

ALL FUNCTIONS

在任何键空间中DROP FUNCTION <br> 在任何现有键空间中DROP AGGREGATE

DROP

ALL FUNCTIONS IN KEYSPACE

在键空间中DROP FUNCTION <br> 在现有键空间中DROP AGGREGATE

DROP

FUNCTION

DROP FUNCTION

DROP

ALL ROLES

在任何角色上DROP ROLE

DROP

ROLE

DROP ROLE

SELECT

ALL KEYSPACES

在任何表上SELECT

SELECT

KEYSPACE

在键空间中的任何表上SELECT

SELECT

TABLE

在指定的表上SELECT

SELECT

ALL MBEANS

调用任何 mbean 上的 getter 方法

SELECT

MBEANS

调用与通配符模式匹配的任何 mbean 上的 getter 方法

SELECT

MBEAN

调用已命名 mbean 上的 getter 方法

MODIFY

ALL KEYSPACES

在任何表上INSERT <br> 在任何表上UPDATE <br> 在任何表上DELETE <br> 在任何表上TRUNCATE

MODIFY

KEYSPACE

在键空间中的任何表上INSERT <br> 在键空间中的任何表上UPDATE <br> 在键空间中的任何表上DELETE <br> 在键空间中的任何表上TRUNCATE

MODIFY

TABLE

INSERT <br> UPDATE <br> DELETE <br> TRUNCATE

MODIFY

ALL MBEANS

调用任何 mbean 上的 setter 方法

MODIFY

MBEANS

调用与通配符模式匹配的任何 mbean 上的 setter 方法

MODIFY

MBEAN

调用已命名 mbean 上的 setter 方法

AUTHORIZE

ALL KEYSPACES

GRANT PERMISSION 在任何表上 <br> REVOKE PERMISSION 在任何表上

AUTHORIZE

KEYSPACE

GRANT PERMISSION 在键空间中的表上 <br> REVOKE PERMISSION 在键空间中的表上

AUTHORIZE

TABLE

GRANT PERMISSION <br> REVOKE PERMISSION

AUTHORIZE

ALL FUNCTIONS

GRANT PERMISSION 在任何函数上 <br> REVOKE PERMISSION 在任何函数上

AUTHORIZE

ALL FUNCTIONS IN KEYSPACE

GRANT PERMISSION 在键空间中 <br> REVOKE PERMISSION 在键空间中

AUTHORIZE

ALL FUNCTIONS IN KEYSPACE

GRANT PERMISSION 在键空间中 <br> REVOKE PERMISSION 在键空间中

AUTHORIZE

FUNCTION

GRANT PERMISSION <br> REVOKE PERMISSION

AUTHORIZE

ALL MBEANS

GRANT PERMISSION 在任何 mbean 上 <br> REVOKE PERMISSION 在任何 mbean 上

AUTHORIZE

MBEANS

GRANT PERMISSION 在与通配符模式匹配的任何 mbean 上 <br> REVOKE PERMISSION 在与通配符模式匹配的任何 mbean 上

AUTHORIZE

MBEAN

GRANT PERMISSION 在已命名 mbean 上 <br> REVOKE PERMISSION 在已命名 mbean 上

AUTHORIZE

ALL ROLES

GRANT ROLE 授予任何角色 <br> REVOKE ROLE 撤销任何角色

AUTHORIZE

角色

GRANT ROLE 授予角色 <br> REVOKE ROLE 撤销角色

DESCRIBE

ALL ROLES

LIST ROLES 所有角色或仅授予另一个指定角色的角色

DESCRIBE

@ALL MBEANS

从平台的 MBeanServer 检索有关任何 mbean 的元数据

DESCRIBE

@MBEANS

从平台的 MBeanServer 检索有关与通配符模式匹配的任何 mbean 的元数据

DESCRIBE

@MBEAN

从平台的 MBeanServer 检索有关已命名 mbean 的元数据

EXECUTE

ALL FUNCTIONS

SELECTINSERTUPDATE 使用任何函数 <br> 在 CREATE AGGREGATE 中使用任何函数

EXECUTE

ALL FUNCTIONS IN KEYSPACE

SELECTINSERTUPDATE 使用键空间中的任何函数 <br> 在 CREATE AGGREGATE 中使用键空间中的任何函数

EXECUTE

FUNCTION

SELECTINSERTUPDATE 使用函数 <br> 在 CREATE AGGREGATE 中使用函数

EXECUTE

ALL MBEANS

在任何 mbean 上执行操作

EXECUTE

MBEANS

在与通配符模式匹配的任何 mbean 上执行操作

EXECUTE

MBEAN

在已命名 mbean 上执行操作

UNMASK

ALL KEYSPACES

查看任何表上屏蔽列的清除内容

UNMASK

KEYSPACE

查看键空间中任何表上屏蔽列的清除内容

UNMASK

TABLE

查看指定表上屏蔽列的清除内容

SELECT_MASKED

ALL KEYSPACES

SELECT 限制任何表上的屏蔽列

SELECT_MASKED

KEYSPACE

SELECT 限制指定键空间中任何表上的屏蔽列

SELECT_MASKED

TABLE

SELECT 限制指定表上的屏蔽列

GRANT PERMISSION

语法

bc(syntax)..
::= GRANT ( ALL ( PERMISSIONS )? | ( PERMISSION )? ) ON TO

::= CREATE | ALTER | DROP | SELECT | MODIFY | AUTHORIZE | DESCRIBE | UNMASK | SELECT_MASKED EXECUTE

::= ALL KEYSPACES
| KEYSPACE
| ( TABLE )?
| ALL ROLES
| ROLE
| ALL FUNCTIONS ( IN KEYSPACE )?
| FUNCTION
| ALL MBEANS
| ( MBEAN | MBEANS )
p.

样本

bc(sample).
GRANT SELECT ON ALL KEYSPACES TO data_reader;

这使具有角色 data_reader 的任何用户都有权限对所有键空间中的任何表执行 SELECT 语句

bc(sample).
GRANT MODIFY ON KEYSPACE keyspace1 TO data_writer;

这使具有角色 data_writer 的任何用户都有权限对 keyspace1 键空间中的所有表执行 UPDATEINSERTUPDATEDELETETRUNCATE 查询

bc(sample).
GRANT DROP ON keyspace1.table1 TO schema_owner;

这使具有 schema_owner 角色的任何用户都有权限 DROP keyspace1.table1

bc(sample).
GRANT EXECUTE ON FUNCTION keyspace1.user_function( int ) TO report_writer;

这使具有 report_writer 角色的任何用户都有权限执行使用函数 keyspace1.user_function( int )SELECTINSERTUPDATE 查询

bc(sample).
授予 role_admin 对所有角色的 DESCRIBE 权限;

这将授予任何具有 role_admin 角色的用户使用 LIST ROLES 语句查看系统中任何和所有角色的权限

授予所有

当使用 GRANT ALL 表单时,将根据目标资源自动确定适当的权限集。

自动授予

当通过 CREATE KEYSPACECREATE TABLECREATE FUNCTIONCREATE AGGREGATECREATE ROLE 语句创建资源时,创建者(即标识发出该语句的数据库用户的角色)将自动获得对新资源的所有适用权限。

撤销权限

语法

bc(syntax)..
::= REVOKE ( ALL ( PERMISSIONS )? | ( PERMISSION )? ) ON FROM

::= CREATE | ALTER | DROP | SELECT | MODIFY | AUTHORIZE | DESCRIBE | UNMASK | SELECT_MASKED EXECUTE

::= ALL KEYSPACES
| KEYSPACE
| ( TABLE )?
| ALL ROLES
| ROLE
| ALL FUNCTIONS ( IN KEYSPACE )?
| FUNCTION
| ALL MBEANS
| ( MBEAN | MBEANS )
p.

样本

bc(sample)..
REVOKE SELECT ON ALL KEYSPACES FROM data_reader;
REVOKE MODIFY ON KEYSPACE keyspace1 FROM data_writer;
REVOKE DROP ON keyspace1.table1 FROM schema_owner;
REVOKE EXECUTE ON FUNCTION keyspace1.user_function( int ) FROM report_writer;
REVOKE DESCRIBE ON ALL ROLES FROM role_admin;
p.

列出权限

语法

bc(syntax)..
::= LIST ( ALL ( PERMISSIONS )? | )
( ON )?
( OF ( NORECURSIVE )? )?

::= ALL KEYSPACES
| KEYSPACE
| ( TABLE )?
| ALL ROLES
| ROLE
| ALL FUNCTIONS ( IN KEYSPACE )?
| FUNCTION
| ALL MBEANS
| ( MBEAN | MBEANS )
p.

样本

bc(sample).
LIST ALL PERMISSIONS OF alice;

显示授予 alice 的所有权限,包括从任何其他角色间接获得的权限。

bc(sample).
LIST ALL PERMISSIONS ON keyspace1.table1 OF bob;

显示授予 bobkeyspace1.table1 上的所有权限,包括从任何其他角色间接获得的权限。这也包括可以应用于 keyspace1.table1 的资源层次结构中的任何权限。例如,如果 bobkeyspace1 拥有 ALTER 权限,则该权限将包含在此查询的结果中。添加 NORECURSIVE 开关会将结果限制为仅直接授予 bobbob 的角色的权限。

bc(sample).
LIST SELECT PERMISSIONS OF carlos;

显示授予 carloscarlos 的任何角色的任何权限,仅限于对任何资源的 SELECT 权限。

数据类型

CQL 支持一组丰富的表中定义的列数据类型,包括集合类型。除了这些本机
和集合类型外,用户还可以提供自定义类型(通过扩展 AbstractType 的 JAVA 类,由
Cassandra 加载)。因此,类型的语法如下

bc(syntax)..
::=
|
|
| // 用于自定义类型。JAVA 类的完全限定名称

::= ascii
| bigint
| blob
| boolean
| counter
| date
| decimal
| double
| float
| inet
| int
| smallint
| text
| time
| timestamp
| timeuuid
| tinyint
| uuid
| varchar
| varint

::= list <' `>'
| set `<' `>'
| map `<' `,' `>'
::= tuple `<' (
,' )* `>'
p. 请注意,本机类型是关键字,因此不区分大小写。然而,它们不是保留关键字。

下表提供了有关本机数据类型的其他信息,以及每种类型支持的 常量 类型

类型 支持的常量 说明

ascii

字符串

ASCII 字符串

bigint

整数

64 位有符号长整型

blob

blob

任意字节(无验证)

boolean

布尔值

true 或 false

counter

整数

计数器列(64 位有符号值)。有关详细信息,请参见 计数器

date

整数、字符串

日期(无对应时间值)。有关详细信息,请参见下文的 使用日期

十进制

整数、浮点数

可变精度十进制

double

整数

64 位 IEEE-754 浮点数

float

整数、浮点数

32 位 IEEE-754 浮点数

inet

字符串

IP 地址。可以是 4 字节长(IPv4)或 16 字节长(IPv6)。没有 inet 常量,IP 地址应作为字符串输入

int

整数

32 位有符号 int

smallint

整数

16 位有符号 int

text

字符串

UTF8 编码字符串

time

整数、字符串

具有纳秒精度的时刻。有关详细信息,请参见下文的 使用时间

timestamp

整数、字符串

时间戳。字符串常量允许将时间戳作为日期输入,有关详细信息,请参见下文的 使用时间戳

timeuuid

uuids

类型 1 UUID。这通常用作“无冲突”时间戳。另请参见 Timeuuid 的函数

tinyint

整数

8 位有符号 int

uuid

uuids

类型 1 或类型 4 UUID

varchar

字符串

UTF8 编码字符串

varint

整数

任意精度整数

有关如何使用集合类型的信息,请参见下文的 使用集合 部分。

使用时间戳

timestamp 类型的编码方式为 64 位有符号整数,表示自标准基准时间(称为“历元”)以来的毫秒数:1970 年 1 月 1 日格林威治标准时间 00:00:00。

时间戳可以在 CQL 中作为简单的长整数输入,给出如上定义的历元以来的毫秒数。

它们还可以作为字符串文字输入,采用以下任何 ISO 8601 格式,每个格式都表示时间和日期 2011 年 3 月 2 日格林威治标准时间上午 04:05:00。

  • 2011-02-03 04:05+0000

  • 2011-02-03 04:05:00+0000

  • 2011-02-03 04:05:00.000+0000

  • 2011-02-03T04:05+0000

  • 2011-02-03T04:05:00+0000

  • 2011-02-03T04:05:00.000+0000

上面的 +0000 是 RFC 822 4 位时区规范;+0000 指格林威治标准时间。美国太平洋标准时间是 -0800。如果需要,可以省略时区——日期将被解释为协调 Cassandra 节点配置下的时区。

  • 2011-02-03 04:05

  • 2011-02-03 04:05:00

  • 2011-02-03 04:05:00.000

  • 2011-02-03T04:05

  • 2011-02-03T04:05:00

  • 2011-02-03T04:05:00.000

然而,依赖于预期的时间区配置显然存在困难,因此建议在可行的情况下始终为时间戳指定时区。

如果日期是唯一重要的部分,也可以省略一天中的时间

  • 2011-02-03

  • 2011-02-03+0000

在这种情况下,一天中的时间将默认为 00:00:00,在指定或默认时区中。

使用日期

date 类型的编码方式为 32 位无符号整数,表示以“历元”(范围的中心,2^31)为中心的日期数。历元是 1970 年 1 月 1 日

日期可以在 CQL 中作为如上定义的无符号整数输入。

它们还可以采用以下格式作为字符串文字输入

  • 2014-01-01

使用时间

time 类型的编码方式为 64 位有符号整数,表示自午夜以来的纳秒数。

时间可以在 CQL 中作为简单的长整数输入,给出自午夜以来的纳秒数。

它们还可以作为字符串文字输入,采用以下任何格式

  • 08:12:54

  • 08:12:54.123

  • 08:12:54.123456

  • 08:12:54.123456789

计数器

counter 类型用于定义计数器列。计数器列是一列,其值是一个 64 位有符号整数,并且支持 2 个操作:增量和减量(有关语法,请参见 UPDATE)。请注意,计数器的值不能设置。计数器在首次增量/减量之前不存在,并且首次增量/减量将之前的值为 0。支持删除计数器列,但有一些限制(有关详细信息,请参见 Cassandra Wiki)。

计数器类型的使用受到以下方式的限制

  • 它不能用于作为表的 PRIMARY KEY 一部分的列。

  • 包含计数器的表只能包含计数器。换句话说,表中 PRIMARY KEY 之外的所有列都具有计数器类型,或者没有列具有计数器类型。

使用集合

值得注意的特性

集合用于存储/反规范化相对较少的数据量。它们适用于诸如给定用户的电话号码''、应用于电子邮件的标签''等事物。但是,当预计项目会无限增长(给定用户发送的所有消息''、传感器注册的事件'',…)时,集合就不再合适,而应该使用特定表(带群集列)。具体来说,集合具有以下限制

  • 集合总是整体读取(并且在内部不会分页读取)。

  • 集合不能包含超过 65535 个元素。更准确地说,虽然可以插入超过 65535 个元素,但不能读取超过 65535 个第一个元素(有关详细信息,请参见 CASSANDRA-5428)。

  • 虽然对集合和映射的插入操作在内部永远不会产生读写前操作,但对列表的一些操作会产生读写前操作(有关详细信息,请参见下面的列表部分)。因此,建议尽可能优先使用集合而不是列表。

请注意,虽然将来可能会放松其中一些限制,但集合用于反规范化少量数据的总体规则将保持不变。

映射

map 是一个 类型化 的键值对集合,其中键是唯一的。此外,请注意,映射在内部按其键排序,因此总是按该顺序返回。要创建 map 类型的列,请使用 map 关键字,后跟用尖括号括起来的逗号分隔的键和值类型。例如

bc(sample).
CREATE TABLE users (
id text PRIMARY KEY,
given text,
surname text,
favs map<text, text> // 文本键和文本值的映射
)

使用受 JSON 启发的语法编写 map 数据。要使用 INSERT 编写记录,请将整个映射指定为 JSON 样式关联数组。注意:此表单将始终替换整个映射。

bc(sample).
INSERT INTO users (id, given, surname, favs)
VALUES (`jsmith', `John', `Smith', \{ `fruit' : `apple', `band' : `Beatles' })

可以通过在UPDATE语句中对映射列进行标注或添加新的映射文本来添加或更新(可能)存在的映射的键值

bc(sample).
UPDATE users SET favs[`author'] = `Ed Poe' WHERE id = `jsmith'
UPDATE users SET favs = favs + \{ `movie' : `Cassablanca' } WHERE id = `jsmith'

请注意,INSERTUPDATE都允许使用TTL,但在两种情况下,TTL设置仅适用于新插入/更新的。换句话说,

bc(sample).
UPDATE users USING TTL 10 SET favs[`color'] = `green' WHERE id = `jsmith'

只会将TTL应用于{ 'color' : 'green' }记录,映射的其余部分不受影响。

使用以下方法删除映射记录

bc(sample).
DELETE favs[`author'] FROM users WHERE id = `jsmith'

集合

set是唯一值的类型化集合。集合按其值排序。要创建类型为set的列,请使用set关键字,后跟用尖括号括起来的类型值。例如

bc(sample).
CREATE TABLE images (
name text PRIMARY KEY,
owner text,
date timestamp,
tags set
);

通过用逗号分隔集合值并在花括号中括起来来编写set注意:INSERT始终会替换整个集合。

bc(sample).
INSERT INTO images (name, owner, date, tags)
VALUES (`cat.jpg', `jsmith', `now', \{ `kitten', `cat', `pet' });

可以通过向现有set列添加/移除新集合值,使用UPDATE来添加和移除集合的值。

bc(sample).
UPDATE images SET tags = tags + \{ `cute', `cuddly' } WHERE name = `cat.jpg';
UPDATE images SET tags = tags - \{ `lame' } WHERE name = `cat.jpg';

映射一样,如果使用TTL,则仅适用于新插入/更新的

列表

list是无唯一值的类型化集合,其中元素按其在列表中的位置排序。要创建类型为list的列,请使用list关键字,后跟用尖括号括起来的类型值。例如

bc(sample).
CREATE TABLE plays (
id text PRIMARY KEY,
game text,
players int,
scores list
)

请注意,如下所述,列表有一些限制和性能考虑因素需要考虑,并且建议在可能的情况下优先使用集合而不是列表。

使用JSON样式语法编写list数据。要使用INSERT编写记录,请将整个列表指定为JSON数组。注意:INSERT始终会替换整个列表。

bc(sample).
INSERT INTO plays (id, game, players, scores)
VALUES (`123-afde', `quake', 3, [17, 4, 2]);

可以通过向现有list列添加新的JSON样式数组,将值添加到列表(追加或前置)中。

bc(sample).
UPDATE plays SET players = 5, scores = scores + [ 14, 21 ] WHERE id = `123-afde';
UPDATE plays SET players = 5, scores = [ 12 ] + scores WHERE id = `123-afde';

需要注意的是,追加和前置不是幂等操作。这意味着如果在追加或前置期间操作超时,则并不总是可以安全地重试操作(因为这可能导致记录被追加或前置两次)。

列表还提供了以下操作:按列表中的位置设置元素、按列表中的位置删除元素以及删除列表中给定值的所有出现。但是,与所有其他集合操作相反,这三个操作在更新之前会引起内部读取,因此通常具有较慢的性能特征。这些操作具有以下语法

bc(sample).
UPDATE plays SET scores[1] = 7 WHERE id = `123-afde'; // 将 scores 的第 2 个元素设置为 7(如果 scores 少于 2 个元素,则会引发错误)
DELETE scores[1] FROM plays WHERE id = `123-afde'; // 删除 scores 的第 2 个元素(如果 scores 少于 2 个元素,则会引发错误)
UPDATE plays SET scores = scores - [ 12, 21 ] WHERE id = `123-afde'; // 从 scores 中删除所有 12 和 21 的出现

映射一样,如果使用TTL,则仅适用于新插入/更新的

使用向量

向量是特定数据类型的非空值的固定大小序列。它们使用与列表相同的文字。

您可以使用以下方法定义、插入和更新向量

CREATE TABLE plays (
    id text PRIMARY KEY,
    game text,
    players int,
    scores vector<int, 3> // A vector of 3 integers
)

INSERT INTO plays (id, game, players, scores)
           VALUES ('123-afde', 'quake', 3, [17, 4, 2]);

// Replace the existing vector entirely
UPDATE plays SET scores = [ 3, 9, 4] WHERE id = '123-afde';

请注意,无法更改向量的各个值,也无法选择向量的各个元素。

函数

CQL3 区分内置函数(所谓的“本机函数”)和 用户定义函数。CQL3 包含以下所述的几个本机函数

转换

cast 函数可用于将一种本机数据类型转换为另一种本机数据类型。

下表描述了 cast 函数支持的转换。Cassandra 会忽略将数据类型转换为其自身数据类型的任何转换。

ascii

textvarchar

bigint

tinyintsmallintintfloatdoubledecimalvarinttextvarchar

boolean

textvarchar

counter

tinyintsmallintintbigintfloatdoubledecimalvarinttextvarchar

date

timestamp

十进制

tinyintsmallintintbigintfloatdoublevarinttextvarchar

double

tinyintsmallintintbigintfloatdecimalvarinttextvarchar

float

tinyintsmallintintbigintdoubledecimalvarinttextvarchar

inet

textvarchar

int

tinyintsmallintbigintfloatdoubledecimalvarinttextvarchar

smallint

tinyintintbigintfloatdoubledecimalvarinttextvarchar

time

textvarchar

timestamp

datetextvarchar

timeuuid

timestampdatetextvarchar

tinyint

tinyintsmallintintbigintfloatdoubledecimalvarinttextvarchar

uuid

textvarchar

varint

tinyintsmallintintbigintfloatdoubledecimaltextvarchar

转换严格依赖于 Java 的语义。例如,双精度值 1 将转换为文本值 `1.0'。

bc(sample).
SELECT avg(cast(count as double)) FROM myTable

令牌

token 函数允许计算给定分区键的令牌。token 函数的确切签名取决于所涉及的表和集群使用的分区器。

token 的参数类型取决于分区键列的类型。返回类型取决于正在使用的分区器

  • 对于 Murmur3Partitioner,返回类型为 bigint

  • 对于 RandomPartitioner,返回类型为 varint

  • 对于 ByteOrderedPartitioner,返回类型为 blob

例如,在使用默认 Murmur3Partitioner 的集群中,如果表由以下内容定义:

bc(sample).
CREATE TABLE users (
userid text PRIMARY KEY,
username text,

)

那么 token 函数将采用类型为 text 的单个参数(在这种情况下,分区键为 userid(没有聚类列,因此分区键与主键相同)),并且返回类型将为 bigint

Uuid

uuid 函数不采用任何参数,并生成适用于在 INSERT 或 SET 语句中使用的随机类型 4 uuid。

Timeuuid 函数

now

now 函数不采用任何参数,并在协调器节点上生成一个新的唯一 timeuuid(在使用它的语句执行时)。请注意,此方法对于插入很有用,但在 WHERE 子句中基本上没有意义。例如,以下形式的查询

bc(sample).
SELECT * FROM myTable WHERE t = now()

根据设计永远不会返回任何结果,因为 now() 返回的值保证是唯一的。

min_timeuuidmax_timeuuid

min_timeuuid(分别为 max_timeuuid)函数采用 timestampt(可以 是时间戳或日期字符串),并返回一个 timeuuid,该 timeuuid 对应于具有时间戳 t最小(分别为最大)可能的 timeuuid。例如

bc(sample).
SELECT * FROM myTable WHERE t > max_timeuuid(`2013-01-01 00:05+0000') AND t < min_timeuuid(`2013-02-02 10:00+0000')

将选择 timeuuidt 严格早于 2013-01-01 00:05+0000' 但严格晚于 `2013-02-02 10:00+0000' 的所有行。请注意,`t >= max_timeuuid('2013-01-01 00:05+0000') 仍然不会选择在 2013-01-01 00:05+0000' 确切生成的 `timeuuid,并且基本上等同于 `t > max_timeuuid('2013-01-01 00:05+0000')

警告:我们称由 min_timeuuidmax_timeuuid 生成的值 UUID,因为它们不尊重 RFC 4122 指定的基于时间的 UUID 生成过程。特别是,这 2 个方法返回的值不会是唯一的。这意味着你应该仅将这些方法用于查询(如上面的示例)。插入这些方法的结果几乎肯定是个坏主意

时间转换函数

提供许多函数来将 `timeuuid'' 转换为 `timestamp' 或 `date',或将 `timestamp' 或 `date' 转换为另一个 `native' 类型。

函数名称 输入类型 说明

to_date

timeuuid

timeuuid 参数转换为 date 类型

to_date

timestamp

timestamp 参数转换为 date 类型

to_timestamp

timeuuid

timeuuid 参数转换为 timestamp 类型

to_timestamp

date

date 参数转换为 timestamp 类型

to_unix_timestamp

timeuuid

timeuuid 参数转换为 bigInt 原始值

to_unix_timestamp

timestamp

timestamp 参数转换为 bigInt 原始值

to_unix_timestamp

date

date 参数转换为 bigInt 原始值

Blob 转换函数

提供了一些函数来将本机类型“`转换'' 为二进制数据(`blob)。对于 CQL3 支持的每个<native-type>type(显而易见的是,blob除外),函数type_as_blob采用类型为type的参数,并将其作为blob返回。相反,函数blob_as_type采用 64 位blob参数,并将其转换为bigint值。因此,例如,bigint_as_blob(3)0x0000000000000003,而blob_as_bigint(0x0000000000000003)3

聚合

聚合函数作用于一组行。它们接收每行的值,并为整个集合返回一个值。
如果将“`正常'' 列、`标量函数''、`UDT'' 字段、`writetime''、`maxwritetime'' 或`ttl'' 与聚合函数一起选择,则为它们返回的值将是与查询匹配的第一行的值。

CQL3 区分内置聚合(所谓的“`本机聚合'')和用户定义的聚合。CQL3 包含几个本机聚合,如下所述

计数

count函数可用于统计查询返回的行数。示例

bc(sample).
SELECT COUNT (*) FROM plays;
SELECT COUNT (1) FROM plays;

它还可用于统计给定列的非空值。示例

bc(sample).
SELECT COUNT (scores) FROM plays;

最大值和最小值

maxmin函数可用于计算查询针对给定列返回的最大值和最小值。

bc(sample).
SELECT MIN (players), MAX (players) FROM plays WHERE game = `quake';

求和

sum函数可用于对查询针对给定列返回的所有值求和。

bc(sample).
SELECT SUM (players) FROM plays;

平均值

avg函数可用于计算查询针对给定列返回的所有值的平均值。

bc(sample).
SELECT AVG (players) FROM plays;

用户定义的函数

用户定义的函数允许在 Cassandra 中执行用户提供的代码。默认情况下,Cassandra 支持在JavaJavaScript中定义函数。在 3.0.11 中已删除对其他 JSR 223 兼容脚本语言(如 Python、Ruby 和 Scala)的支持。

UDF 是 Cassandra 架构的一部分。因此,它们会自动传播到群集中的所有节点。

UDF 可以“`重载'' - 即具有不同参数类型但函数名称相同的多个 UDF。示例

bc(sample).
CREATE FUNCTION sample ( arg int ) …;
CREATE FUNCTION sample ( arg text ) …;

用户定义的函数容易出现所选编程语言的所有常见问题。因此,实现应针对空指针异常、非法参数或任何其他潜在异常来源保持安全。函数执行期间发生的异常会导致整个语句失败。

复杂类型(如集合、元组类型和用户定义的类型)用作参数和返回类型是有效的。元组类型和用户定义的类型由 DataStax Java 驱动程序的转换函数处理。有关处理元组类型和用户定义类型的详细信息,请参阅 Java 驱动程序的文档。

函数的参数可以是文字或术语。也可以使用已准备的语句占位符。

请注意,可以使用双引号字符串语法来括起 UDF 源代码。例如

bc(sample)..
CREATE FUNCTION some_function ( arg int )
RETURNS NULL ON NULL INPUT
RETURNS int
LANGUAGE java
AS return arg; ;

SELECT some_function(column) FROM atable …;
UPDATE atable SET col = some_function(?) …;
p.

bc(sample).
CREATE TYPE custom_type (txt text, i int);
CREATE FUNCTION fct_using_udt ( udtarg frozen )
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS return udtarg.getString(``txt''); ;

用户自定义函数可用于 SELECTINSERTUPDATE 语句。

隐式可用的 udfContext 字段(或脚本 UDF 的绑定)提供了创建新 UDT 和元组值所需的功能。

bc(sample).
CREATE TYPE custom_type (txt text, i int);
CREATE FUNCTION fct_using_udt ( somearg int )
RETURNS NULL ON NULL INPUT
RETURNS custom_type
LANGUAGE java
AS + UDTValue udt = udfContext.newReturnUDTValue(); + udt.setString(``txt'', ``some string''); + udt.setInt(``i'', 42); + return udt; + ;

UDFContext 接口的定义可在 org.apache.cassandra.cql3.functions.UDFContext 的 Apache Cassandra 源代码中找到。

bc(sample).
public interface UDFContext
\{
UDTValue newArgUDTValue(String argName);
UDTValue newArgUDTValue(int argNum);
UDTValue newReturnUDTValue();
UDTValue newUDTValue(String udtName);
TupleValue newArgTupleValue(String argName);
TupleValue newArgTupleValue(int argNum);
TupleValue newReturnTupleValue();
TupleValue newTupleValue(String cqlDefinition);
}

Java UDF 已为定义的通用接口和类进行了一些导入。这些导入是
请注意,脚本 UDF 不提供这些便利导入。

bc(sample).
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cassandra.cql3.functions.UDFContext;
import com.datastax.driver.core.TypeCodec;
import com.datastax.driver.core.TupleValue;
import com.datastax.driver.core.UDTValue;

请参阅 CREATE FUNCTIONDROP FUNCTION

用户自定义聚合

用户自定义聚合允许使用 UDF 创建自定义聚合函数。聚合函数的常见示例包括countminmax

每个聚合都需要一个初始状态INITCOND,默认为 null)类型为 STYPE。状态函数的第一个参数必须为 STYPE 类型。状态函数的其余参数必须与用户自定义聚合参数的类型匹配。状态函数对每一行调用一次,状态函数返回的值变为新状态。在处理完所有行后,将使用最后一个状态值作为其参数执行可选的 FINALFUNC

STYPE 是强制性的,以便能够区分状态和/或最终函数的可能重载版本(因为重载可能在创建聚合后出现)。

用户自定义聚合可用于 SELECT 语句。

用户自定义聚合的完整工作示例(假设已使用 USE 语句选择了键空间)

bc(sample)..
CREATE OR REPLACE FUNCTION averageState ( state tuple<int,bigint>, val int )
CALLED ON NULL INPUT
RETURNS tuple<int,bigint>
LANGUAGE java
AS ’
if (val != null) \{
state.setInt(0, state.getInt(0)+1);
state.setLong(1, state.getLong(1)+val.intValue());
}
return state;
’;

CREATE OR REPLACE FUNCTION averageFinal ( state tuple<int,bigint> )
CALLED ON NULL INPUT
RETURNS double
LANGUAGE java
AS ’
double r = 0;
if (state.getInt(0) == 0) return null;
r = state.getLong(1);
r /= state.getInt(0);
return Double.valueOf®;
’;

CREATE OR REPLACE AGGREGATE average ( int )
SFUNC averageState
STYPE tuple<int,bigint>
FINALFUNC averageFinal
INITCOND (0, 0);

CREATE TABLE atable (
pk int PRIMARY KEY,
val int);
INSERT INTO atable (pk, val) VALUES (1,1);
将 INSERT INTO atable (pk, val) VALUES (2,2);
将 INSERT INTO atable (pk, val) VALUES (3,3);
将 INSERT INTO atable (pk, val) VALUES (4,4);
SELECT average(val) FROM atable;
p.

请参见 CREATE AGGREGATEDROP AGGREGATE

JSON 支持

Cassandra 2.2 为 SELECTINSERT 语句引入了 JSON 支持。此支持不会从根本上改变 CQL API(例如,仍然强制执行架构),它只是提供了一种使用 JSON 文档的便捷方式。

SELECT JSON

对于 SELECT 语句,可以使用新的 JSON 关键字将每一行返回为一个单一的 JSON 编码映射。SELECT 语句行为的其余部分保持不变。

结果映射键与普通结果集中的列名相同。例如,类似于 SELECT JSON a, ttl(b) FROM …​’' 的语句将生成一个键为 `"a""ttl(b)" 的映射。但是,有一个值得注意的例外:为了与 INSERT JSON 行为保持对称,大小写敏感且包含大写字母的列名将被双引号包围。例如,SELECT JSON myColumn FROM …​’' 将生成一个映射键 `"\"myColumn\""(注意转义引号)。

映射值将是结果集值的 JSON 编码表示(如下所述)。

INSERT JSON

对于 INSERT 语句,可以使用新的 JSON 关键字将 JSON 编码映射作为单行插入。JSON 映射的格式通常应与在同一表上执行 SELECT JSON 语句返回的格式相匹配。特别是,大小写敏感的列名应被双引号包围。例如,要插入到一个名为 myKey'' 和 value'' 的两列的表中,您需要执行以下操作

bc(sample).
将 INSERT INTO mytable JSON `\{\''myKey\'': 0, ``value'': 0}'

JSON 映射中省略的任何列将默认为 NULL 值(这将导致创建墓碑)。

Cassandra 数据类型的 JSON 编码

在可能的情况下,Cassandra 将以其本机 JSON 表示形式表示和接受数据类型。Cassandra 还将接受与所有单字段类型的 CQL 文字格式匹配的字符串表示形式。例如,浮点数、整数、UUID 和日期可以用 CQL 文字字符串表示。但是,复合类型(例如集合、元组和用户定义类型)必须由本机 JSON 集合(映射和列表)或集合的 JSON 编码字符串表示形式表示。

下表描述了 Cassandra 将在 INSERT JSON 值(和 from_json() 参数)中接受的编码,以及 Cassandra 在为 SELECT JSON 语句(和 from_json())返回数据时将使用的格式

类型 接受的格式 返回格式 注释

ascii

字符串

字符串

使用 JSON 的 \u 字符转义

bigint

整数、字符串

整数

字符串必须是有效的 64 位整数

blob

字符串

字符串

字符串应为 0x 后跟偶数个十六进制数字

boolean

布尔值、字符串

boolean

字符串必须为 true'' 或 false''

date

字符串

字符串

日期格式为 YYYY-MM-DD,时区为 UTC

十进制

整数、浮点数、字符串

float

可能超出客户端解码器中的 32 或 64 位 IEEE-754 浮点精度

double

整数、浮点数、字符串

float

字符串必须是有效的整数或浮点数

float

整数、浮点数、字符串

float

字符串必须是有效的整数或浮点数

inet

字符串

字符串

IPv4 或 IPv6 地址

int

整数、字符串

整数

字符串必须是有效的 32 位整数

列表

列表、字符串

列表

使用 JSON 的本机列表表示法

映射

映射、字符串

映射

使用 JSON 的本机映射表示法

smallint

整数、字符串

整数

字符串必须是有效的 16 位整数

集合

列表、字符串

列表

使用 JSON 的本机列表表示法

text

字符串

字符串

使用 JSON 的 \u 字符转义

time

字符串

字符串

时间格式为 HH-MM-SS[.fffffffff]

timestamp

整数、字符串

字符串

时间戳。允许将字符串常量作为日期输入时间戳,有关更多信息,请参阅下面的 使用日期。返回格式为 YYYY-MM-DD HH:MM:SS.SSS 的日期时间戳。

timeuuid

字符串

字符串

类型 1 UUID。有关 UUID 格式,请参阅 常量

tinyint

整数、字符串

整数

字符串必须是有效的 8 位整数

元组

列表、字符串

列表

使用 JSON 的本机列表表示法

UDT

映射、字符串

映射

使用 JSON 的本机映射表示法,其中字段名称作为键

uuid

字符串

字符串

有关 UUID 格式,请参阅 常量

varchar

字符串

字符串

使用 JSON 的 \u 字符转义

varint

整数、字符串

整数

可变长度;可能溢出客户端解码器中的 32 或 64 位整数

from_json() 函数

from_json() 函数的使用方式可能与 INSERT JSON 类似,但适用于单个列值。它只能在 INSERT 语句的 VALUES 子句中使用,或作为 UPDATEDELETESELECT 语句中的列值之一。例如,它不能用于 SELECT 语句的选择子句中。

to_json() 函数

to_json() 函数的使用方式可能与 SELECT JSON 类似,但适用于单个列值。它只能在 SELECT 语句的选择子句中使用。

附录 A:CQL 关键字

CQL 区分保留关键字和非保留关键字。保留关键字不能用作标识符,它们真正保留给该语言(但可以用双引号将保留关键字括起来,以将其用作标识符)。然而,非保留关键字仅在特定上下文中具有特定含义,但在其他情况下可以用作标识符。这些非保留关键字存在的唯一理由是方便:当解析器始终可以轻松判断它们是作为关键字还是非关键字使用时,一些关键字是非保留的。

关键字 保留?

ADD

AGGREGATE

ALL

ALLOW

ALTER

AND

APPLY

AS

ASC

ASCII

AUTHORIZE

BATCH

BEGIN

BIGINT

BLOB

BOOLEAN

BY

CALLED

CAST

CLUSTERING

COLUMNFAMILY

COMPACT

CONTAINS

COUNT

COUNTER

CREATE

CUSTOM

DATE

DECIMAL

DEFAULT

DELETE

DESC

DESCRIBE

DISTINCT

DOUBLE

DROP

DURATION

ENTRIES

EXECUTE

EXISTS

FILTERING

FINALFUNC

FLOAT

FROM

FROZEN

FULL

FUNCTION

FUNCTIONS

GRANT

GROUP

IF

IN

INDEX

INET

INFINITY

INITCOND

INPUT

INSERT

INT

INTO

IS

JSON

KEY

KEYS

KEYSPACE

KEYSPACES

LANGUAGE

LIKE

LIMIT

LIST

LOGIN

MAP

MASKED

MATERIALIZED

MBEAN

MBEANS

MODIFY

NAN

NOLOGIN

NORECURSIVE

NOSUPERUSER

NOT

NULL

OF

ON

OPTIONS

OR

ORDER

PARTITION

PASSWORD

PER

PERMISSION

PERMISSIONS

PRIMARY

RENAME

REPLACE

RETURNS

REVOKE

ROLE

角色

SCHEMA

SELECT

SELECT_MASKED

SET

SFUNC

SMALLINT

STATIC

STORAGE

STYPE

SUPERUSER

TABLE

TEXT

TIME

TIMESTAMP

TIMEUUID

TINYINT

TO

TOKEN

TRIGGER

TRUNCATE

TTL

TUPLE

TYPE

UNLOGGED

UNMASK

UNSET

UPDATE

USE

USER

USERS

USING

UUID

VALUES

VARCHAR

VARINT

VIEW

WHERE

WITH

WRITETIME

附录 B:CQL 保留类型

以下类型名称目前未被 CQL 使用,但已保留以备将来使用。用户定义类型不得使用保留类型名称作为其名称。

类型

bitstring

byte

complex

date

enum

interval

macaddr

更改

以下描述了 CQL 各个版本中的更改。

3.4.3

3.4.2

3.4.2

3.4.1

  • 添加 CAST 函数。参见 Cast

3.4.0

  • 支持 物化视图

  • DELETE 支持对任何主键列的不等式表达式和 IN 限制

  • UPDATE 支持对任何主键列的 IN 限制

3.3.1

  • 现在接受语法 TRUNCATE TABLE X 作为 TRUNCATE X 的别名

3.3.0

  • 添加新的 聚合

  • 现在通过 CREATE FUNCTIONDROP FUNCTION 支持用户定义函数。

  • 现在通过 CREATE AGGREGATEDROP AGGREGATE 支持用户定义聚合。

  • 允许双美元符号括起来的字符串文字作为单引号括起来的字符串的替代。

  • 引入角色来取代基于用户的身份验证和访问控制

  • 已添加 DateTime 数据类型

  • 已添加 JSON 支持

  • 已添加 TinyintSmallint 数据类型

  • 添加新的时间转换函数,并弃用 dateOfunixTimestampOf。参见 时间转换函数

3.2.0

  • 现在通过 CREATE TYPEALTER TYPEDROP TYPE 支持用户定义类型

  • CREATE INDEX 现在支持索引集合列,包括通过 keys() 函数索引映射集合的键

  • 可以使用新的 CONTAINSCONTAINS KEY 运算符查询集合上的索引

  • 添加元组类型以保存固定长度的类型化位置字段集(请参阅 类型 部分)

  • DROP INDEX 现在支持选择性指定键空间

3.1.7

  • SELECT 语句现在支持使用组合聚类列上的 IN 子句在单个分区中选择多行。请参阅 SELECT WHERE 子句。

  • IF NOT EXISTSIF EXISTS 语法现在分别受 CREATE USERDROP USER 语句支持。

3.1.6

  • 已添加一个新的 uuid 方法

  • 支持 DELETE …​ IF EXISTS 语法。

3.1.5

3.1.4

  • CREATE INDEX 现在允许在创建 CUSTOM 索引时指定选项(请参阅 CREATE INDEX 参考 )。

3.1.3

  • 已将毫秒精度格式添加到时间戳解析器(请参阅 使用日期 )。

3.1.2

  • NaNInfinity 已被添加为有效的浮点数常量。它们现在是保留关键字。在不太可能将它们用作列标识符(或键空间/表标识符)的情况下,现在需要用双引号将它们引起来(请参阅 引用标识符 )。

3.1.1

  • SELECT 语句现在允许列出分区键(使用 DISTINCT 修饰符)。请参阅 CASSANDRA-4536

  • 现在在 WHERE 子句中支持 c IN ? 语法。在这种情况下,绑定变量的预期值将是 c 类型的列表。

  • 现在可以使用命名绑定变量(使用 :name 代替 ?)。

3.1.0

  • ALTER TABLE DROP 选项已重新启用 CQL3 表,现在具有新的语义:以前由已删除列使用的空间现在将最终回收(压缩后)。除非使用具有微秒精度的时戳,否则不应重新添加以前删除的列(有关更多详细信息,请参阅 CASSANDRA-3919)。

  • SELECT 语句现在支持选择子句中的别名。不支持 WHERE 和 ORDER BY 子句中的别名。有关详细信息,请参阅 选择部分

  • KEYSPACETABLEINDEXCREATE 语句现在支持 IF NOT EXISTS 条件。类似地,DROP 语句支持 IF EXISTS 条件。

  • INSERT 语句选择性地支持 IF NOT EXISTS 条件,UPDATE 支持 IF 条件。

3.0.5

  • SELECTUPDATEDELETE 语句现在允许空 IN 关系(请参阅 CASSANDRA-5626)。

3.0.4

  • 更新了自定义 辅助索引 的语法。

  • 现在永远不支持分区键上的非相等条件,即使对于排序分区器也是如此,因为这是不正确的(顺序不是分区键类型的顺序)。相反,token 方法应始终用于分区键上的范围查询(请参阅 WHERE 子句 )。

3.0.3

3.0.2

  • 已修复常量的类型验证。例如,该实现过去允许将 '2' 作为 int 列的有效值(将其解释为 2 的等效值),或将 42 作为有效的 blob 值(在这种情况下,将 42 解释为 blob 的十六进制表示形式)。现在不再是这样,常量的类型验证现在更加严格。有关哪些常量允许用于哪种类型的详细信息,请参阅数据类型部分。

  • 前一点中修复的类型验证已导致引入blob 常量以允许输入 blob。请注意,虽然此版本仍支持将 blob 输入为字符串常量(以允许更平滑地过渡到 blob 常量),但现在已弃用(特别是数据类型部分未将字符串常量列为有效的 blob)并且将被未来版本删除。如果您将字符串用作 blob,则应尽快更新您的客户端代码以切换 blob 常量。

  • 还引入了一些将本机类型转换为 blob 的函数。此外,现在还允许在选择子句中使用令牌函数。有关详细信息,请参阅函数部分

3.0.1

  • 日期字符串(和时间戳)不再被接受为有效的 timeuuid 值。这样做是一个错误,因为日期字符串不是有效的 timeuuid,因此导致令人困惑的行为。但是,已添加以下新方法来帮助使用 timeuuidnowminTimeuuidmaxTimeuuiddateOfunixTimestampOf。有关更多详细信息,请参阅专门介绍这些方法的部分

  • `浮点常量''#constants 现在支持指数表示法。换句话说,`4.2E10` 现在是一个有效的浮点值。

版本控制

CQL 语言的版本控制遵循语义版本控制准则。版本采用 X.Y.Z 形式,其中 X、Y 和 Z 是分别表示主版本、次版本和修补程序级别的整数值。Cassandra 发布版本与 CQL 语言版本之间没有相关性。

版本 说明

主版本

当引入向后不兼容的更改时,必须增加主版本。这种情况很少发生。

次版本

当引入新的但向后兼容的功能时,会增加次版本。

修补程序

当修复错误时,会增加修补程序版本。