keyspace_name ::=name
table_name ::= [keyspace_name
'.' ]name
name ::=unquoted_name
|quoted_name
unquoted_name ::= re('[a-zA-Z_0-9]{1, 48}') quoted_name ::= '"'unquoted_name
'"'
column_name ::= identifier
options ::=option
( ANDoption
)* option ::=identifier
'=' (identifier
|constant
|map_literal
)
create_keyspace_statement ::= CREATE KEYSPACE [ IF NOT EXISTS ]keyspace_name
WITHoptions
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;
名称 | 类型 | 强制性 | 默认值 | 描述 |
---|---|---|---|---|
replication |
map | yes | 复制策略和用于键空间的选项 | |
durable_writes |
simple | no | true | 是否使用提交日志来更新此键空间 |
use_statement ::= USE keyspace_name
alter_keyspace_statement ::= ALTER KEYSPACEkeyspace_name
WITHoptions
ALTER KEYSPACE Excelsior
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 4};
drop_keyspace_statement ::= DROP KEYSPACE [ IF EXISTS ] keyspace_name
DROP KEYSPACE Excelsior;
create_table_statement ::= CREATE TABLE [ IF NOT EXISTS ]table_name
'('column_definition
( ','column_definition
)* [ ',' PRIMARY KEY '('primary_key
')' ] ')' [ WITHtable_options
] column_definition ::=column_name
cql_type
[ STATIC ] [ PRIMARY KEY] primary_key ::=partition_key
[ ','clustering_columns
] partition_key ::=column_name
| '('column_name
( ','column_name
)* ')' clustering_columns ::=column_name
( ','column_name
)* table_options ::= COMPACT STORAGE [ ANDtable_options
] | CLUSTERING ORDER BY '('clustering_order
')' [ ANDtable_options
] |options
clustering_order ::=column_name
(ASC | DESC) ( ','column_name
(ASC | DESC) )*
CREATE TABLE monkeySpecies (
species text PRIMARY KEY,
common_name text,
population varint,
average_size int
) WITH comment='Important biological records'
AND read_repair_chance = 1.0;
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' };
CREATE TABLE loads (
machine inet,
cpu int,
mtime timeuuid,
load float,
PRIMARY KEY ((machine, cpu), mtime)
) WITH CLUSTERING ORDER BY (mtime DESC);
CQL表具有名称,并由一组行组成。创建表等于定义将哪些列组成行,哪些列组成主键,以及表的可选选项。
尝试创建已存在的表将返回错误,除非使用IF NOT EXISTS指令。如果使用它,如果表已经存在,语句将是一个无操作。
CQL表中的每一行都有一组在创建表时定义的预定义列(或稍后使用alter语句添加)。
列的定义主要由列的名称和列的类型组成,它限制该列接受哪些值。此外,列定义可以具有以下修饰符:
STATIC:
它将该列声明为静态列。
PRIMARYKEY:它声明该列是表的主键的唯一组件。
在表定义中,一些列可以声明为STATIC。属于静态的列将由属于同一分区(具有相同的分区键)的所有行“共享”。例如:
CREATE TABLE t (
pk int,
t int,
v text,
s text static,
PRIMARY KEY (pk, t)
);
INSERT INTO t (pk, t, v, s) VALUES (0, 0, 'val0', 'static0');
INSERT INTO t (pk, t, v, s) VALUES (0, 1, 'val1', 'static1');
SELECT * FROM t;
pk | t | v | s
----+---+--------+-----------
0 | 0 | 'val0' | 'static1'
0 | 1 | 'val1' | 'static1'
使用静态列的限制如下:
在表中,一行由其PRIMARY KEY唯一标识,因此所有表必须定义一个PRIMARY KEY(只有一个)。PRIMARY KEY的定义由表中的一个或多个列组成。在语法上,主键定义了关键字PRIMARY KEY,后跟逗号分隔的在括号中组成它的列名的列表,但是如果主键只有一列,则可以通过PRIMARY KEY关键字替代该列定义。主键定义中的列顺序很重要。
CQL主键由2部分组成:
分区键部分。 它是主键定义的第一个组件。它可以是单个列,可以是多个列。一个表总是至少有一个分区键,最小的可能表定义是:
CREATE TABLE t (k text PRIMARY KEY);
聚簇列。这些是主键定义的第一个组件之后的列,这些列的顺序定义了聚簇顺序。
主键定义的一些示例:
PRIMARY KEY (a)
: a
是分区键,并且没有聚簇列。PRIMARY KEY (a, b, c)
: a
是分区键,并且b和c是聚簇列。PRIMARY KEY ((a, b), c)
: a和b组成分区键(这通常称为复合分区键),c是聚类列。在表中,CQL定义了分区的概念。 分区只是它们的分区键具有相同值的一组行。注意,如果分区键由多个列组成,那么行属于同一分区,只有它们对所有这些分区键列具有相同的值。例如,给定下面的表定义和内容:
CREATE TABLE t (
a int,
b int,
c int,
d int,
PRIMARY KEY ((a, b), c, d)
);
SELECT * FROM t;
a | b | c | d
---+---+---+---
0 | 0 | 0 | 0 // row 1
0 | 0 | 1 | 1 // row 2
0 | 1 | 2 | 2 // row 3
0 | 1 | 3 | 3 // row 4
1 | 1 | 4 | 4 // row 5
第1行和第2行在同一个分区中,第3行和第4行也在同一个分区中(但是不同的一个),而第5行在另一个分区中。
注意,表始终具有分区键,并且如果表没有聚簇列,则该表的每个分区仅由单个行组成(因为主键唯一地标识行,并且主键等于分区键如果没有聚簇列)。
分区的最重要的属性是属于同一分区的所有行保证被存储在同一副本节点集合上。换句话说,表的分区键定义了哪些行将在集群中一起本地化,因此重要的是明智地选择分区键,以便需要一起提取的行在同一个分区中(因此一起查询这些行需要联系最少的节点)。
这种保证还有另一个方面:因为共享一个分区键的所有行都保证存储在同一副本节点集合上,分组太多数据的分区键可以创建一个热点。分区的另一个有用的属性是,当写入数据时,属于单个分区的所有更新是原子地并且隔离地完成的,而跨分区不是这样。
正确选择表的分区键和聚簇列可能是Cassandra中数据建模最重要的方面之一,它在很大程度上影响可以执行的查询以及它们的效率。
表的聚簇列定义了该表的分区的聚类顺序。 对于给定的分区,所有行在Cassandra内通过该聚类顺序物理排序。例如,给定:
CREATE TABLE t (
a int,
b int,
c int,
PRIMARY KEY (a, b, c)
);
SELECT * FROM t;
a | b | c
---+---+---
0 | 0 | 4 // row 1
0 | 1 | 9 // row 2
0 | 2 | 2 // row 3
0 | 3 | 3 // row 4
那么所有行(它们都属于同一分区)全部以它们的b列的值的顺序(它们在上面显示的顺序)在内部存储。因此,表的分区键允许对同一副本集上的行进行分组时,聚簇列控制这些行如何存储在副本上。该排序允许检索分区内的一定范围的行(例如,在上面的示例中,SELECT * FROM t WHERE a = 0 AND b> 1 AND b <= 3)非常有效。
CQL表具有可在创建时设置的多个选项(对于大多数选项可以在之后进行更改)。这些选项在WITH关键字后指定。
在这些选项中,两个重要的选项在创建后不能更改,并影响可以对表执行哪些查询:COMPACT STORAGE选项和CLUSTERING ORDER选项。这两个选项以及表的其他选项在以下部分中描述。
警告:从Cassandra 3.0开始,紧凑表在内部具有与非紧凑表相同的布局(对于相同的模式),并且为了确保与已弃用的ThriftAPI向后兼容声明表紧凑只会对表定义和使用造成人为限制。但是COMPACT STORAGE不能兼容,Cassandra 4.0之后将被删除,所以强烈建议不要使用COMPACT STORAGE选项创建新表。
表的聚簇顺序由该表的聚类列定义。 默认情况下,该排序基于这些聚簇顺序的自然顺序,但是CLUSTERING ORDER允许更改该聚类顺序以对某些(可能全部)列使用反向自然顺序。
CLUSTERING ORDER选项采用聚类列的逗号分隔列表,每个列都有一个ASC(升序)或DESC(降序)。特别要注意的是,默认值(如果不使用CLUSTERING ORDER选项)严格等同于使用ASC修改器在所有聚簇列中使用该选项。
请注意,此选项基本上是存储引擎更改存储行的顺序的提示,但它有3个可见的后果:
表支持以下选项:
选项 | 类型 | 默认值 | 描述 |
---|---|---|---|
comment |
simple | none | 表字段的注释 |
read_repair_chance |
simple | 0.1 | 为了读修复的目的查询额外节点(例如,比一致性级别所需的更多节点)的概率。 |
dclocal_read_repair_chance |
simple | 0 | 为了读修复的目的,查询属于与读协调器相同的数据中心的额外节点(例如,比一致性级别所需的更多节点)的概率。 |
gc_grace_seconds |
simple | 864000 | 在垃圾收集标记删除标记之前等待的时间。 |
bloom_filter_fp_chance |
simple | 0.00075 | sstables bloom过滤器的假阳性的目标概率。 所述bloom过滤器将被调整大小以提供所提供的概率(因此降低该值影响存储器和磁盘中的bloom过滤器的大小) |
default_time_to_live |
simple | 0 | 表的默认到期时间(“TTL”)(以秒为单位)。 |
compaction |
map | 见下文 | 见下文 |
compression |
map | 见下文 | 见下文 |
caching |
map | 见下文 | 见下文 |
压缩选项必须至少定义“class”子选项,该选项定义要使用的压缩策略类。默认支持的类是'SizeTieredCompactionStrategy'(STCS),'LeveledCompactionStrategy'(LCS)和'TimeWindowCompactionStrategy'(TWCS)('DateTieredCompactionStrategy'也支持,但不推荐使用'TimeWindowCompactionStrategy'。可以通过将完整类名称指定为字符串常量来提供自定义策略。
压缩选项定义是否以及如何压缩表的sstables。以下子选项区域可用:
选项 | 默认值 | 描述 |
---|---|---|
class |
LZ4Compressor | 使用的压缩算法。 默认压缩器是:LZ4Compressor,SnappyCompressor和DeflateCompressor。Use'enabled':false禁用压缩。可以通过将完整的类名指定为“字符串常量”来提供自定义压缩器:#constants。 |
enabled |
true | 启用/禁用sstable压缩。 |
chunk_length_in_kb |
64KB | 在磁盘上SSTables被块压缩(允许随机读取)。 这定义了所述块的大小(以KB计)。 较大的值可以提高压缩率,但增加从磁盘读取的数据的最小大小。 |
crc_check_chance |
1.0 | 当启用压缩时,每个压缩块包括该块的校验和,以便检测磁盘bitrot并避免将恶化传播到其他复制品。此选项定义在读取期间检查这些校验和的概率。默认情况下总是选中它。设置为0以禁用校验和检查,0.5设置为每隔一个读取检查它们。 |
缓存选项允许为表配置键高速缓存和行高速缓存。以下子选项可用:
选项 | 默认值 | 描述 |
---|---|---|
keys |
ALL | 是否缓存此表的键(“键缓存”)。有效值为:ALL和NONE。 |
rows_per_partition |
NONE | 每个分区缓存的行数(“行缓存”)。 如果指定了整数n,则将高速缓存分区的前n个查询的行。其他可能的选项是,缓存查询分区的所有行,或者禁用行缓存。 |
更改现有表使用ALTER TABLE语句:
alter_table_statement ::= ALTER TABLEtable_name
alter_table_instruction
alter_table_instruction ::= ALTERcolumn_name
TYPEcql_type
| ADDcolumn_name
cql_type
( ','column_name
cql_type
)* | DROPcolumn_name
(column_name
)* | WITHoptions
示例:
ALTER TABLE addamsFamily ALTER lastKnownLocation TYPE uuid;
ALTER TABLE addamsFamily ADD gravesite varchar;
ALTER TABLE addamsFamily
WITH comment = 'A most excellent and useful table'
AND read_repair_chance = 0.2;
ALTER TABLE语句可以:
警告:删除列假定用于此列的值的时间戳为“real”时间戳(以微秒为单位)。使用以微秒为单位的“真实”时间戳是默认值,并且强烈推荐,但Cassandra允许客户端在任何表上提供任何时间戳,理论上可以使用另一个规则。如果这样做,删除列将无法正常工作。
警告:删除列后,可以重新添加与删除的列名称相同的列,因为删除列的类型是(非冻结)列。
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语句:
drop_table_statement ::= DROP TABLE [ IF EXISTS ] table_name
删除表操作会立即执行,不可逆地删除表,包括其包含的所有数据。可以使用TRUNCATE语句截断表:
truncate_statement ::= TRUNCATE [ TABLE ] table_name
允许TRUNCATE TABLE foo与其他DDL语句的一致性,但是表是当前可以截断的唯一对象,因此可以省略TABLE关键字。
截断表永久删除表中的所有现有数据,但不删除表本身。