Cassandra Query Language (CQL)v3.3.0
1. Cql语法
1.1. 前言
本文档描述了CQL v3。CQL v3与CQL v2不兼容且在很多地方不同。
CQL v3提供了非常类似于SQL的数据模型,数据放在了包含rows和columns的tables中。因此,当使用此文档时,这些内容(tables,rows,columns)与SQL定义相同。但是rows和columns其内部实现的原理不同。
1.2. 约定
为了介绍CQL语法,文档使用以下约定:
语言规则使用类BNF符号:
<start> ::= TERMINAL<non-terminal1> <non-terminal1>
非终结符号<尖括号>。
作为额外的BNF快捷符号,使用传统的正则表达式的符号(?+and*)表示是可选的,and/or可以重复。 [<characters>]符号表示任意一个<characters>。
code块提供了简单code
SELECT sample_usage FROM cql;
1.3. 标识符和关键字
CQL语言使用标识符(或名称)来标识tables,columns和其他对象。一个标识符是一个令牌,与正则表达式一致[a-zA-Z][a-zA-Z0-9_]*。
一些标识符,比如SELECT或WITH,是关键字。他们有固定的意义且被保留的。
标识符和关键字是大小写不敏感的。因此SELECT与select,sElEcT相同。使用的常常约定关键字大写,标识符小写。
1.4. 常量
CQL定义了下面类型的常量:strings,integers,floats,booleans,uuids和blobs:
1.5. 注释
CQL使用注释:--或//
多行注释:/* */
-
-- This is a comment
-
// This is a
comment too
-
/* This is
-
a multi-line comment */
1.6. 语句
SQL语句可以分为3类:
DDL:改变和设置数据存储方式
DML:改变数据
Queries:查询数据
所有语句以分号(;)结束,除了单条语句外。支持的语句如下:
-
<identifier> ::= any quoted or unquoted identifier, excluding reserved keywords
-
<tablename> ::= (<identifier> '.')? <identifier>
-
-
<string> ::= a string constant
-
<integer> ::= an integer constant
-
<float> ::= a float constant
-
<number> ::= <integer> | <float>
-
<uuid> ::= a uuid constant
-
<boolean> ::= a boolean constant
-
<hex> ::= a blob constant
-
-
<constant> ::= <string> | <number>| <uuid>| <boolean> | <hex>
-
<variable> ::= '?' | ':' <identifier>
-
<term> ::= <constant>| <collection-literal> | <variable> | <function> '(' (<term> (',' <term>)*)? ')'
-
-
<collection-literal> ::= <map-literal>
-
| <
set-literal>
-
| <
list-literal>
-
<
map-literal> ::=
'{' ( <term>
':' <term> (
',' <term>
':' <term> )* )?
'}'
-
<
set-literal> ::=
'{' ( <term> (
',' <term> )* )?
'}'
-
<
list-literal> ::=
'[' ( <term> (
',' <term> )* )?
']'
-
-
<
function> ::= <ident>
-
-
<properties> ::= <property> (
AND <property>)*
-
<property> ::= <identifier>
'=' ( <identifier> | <
constant> | <
map-literal> )
上面语法在实际中并不是所有的都是合法的。最显著的是,<variable>和嵌套<collection-literal>在<collection-literal>中是不被允许的。
<variable>可以是匿名(一个问号?)也可以命名(在:之前的一个标识)。唯一区别就是命名更容易被引用。
<properties>用来创建或修改keyspaces和tables。每一个<properties>类型可以是simple或map。
<tablename>用来标识一个table。表示一个表名。
1.7. Prepared Statement
CQL支持prepared statements。
支持LIMIT,TIMESTAMP和TTL从句
2. DDL
2.1. CREATE KEYSPACE
语法:
<create-keyspace-stmt> ::= CREATE KEYSPACE (IF NOT EXISTS)? <identifier> WITH <properties>
样例:
-
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
CREATE KEYSPACE语句用来创建一个新的顶级keyspace。Keyspace是一个命名空间,定义了复制策略和tables的其他选项集合。合法的keyspaces名称是由数字和字母组成的,长度小于32为的标识。注意,keyspace命名是大小写不敏感的。
CREATE KEYSPACE支持的<properties>:
name | kind | mandatory | default | description |
replication | map | yes | 复制策略和使用keyspace选项 | |
durable_writes | simple | no | true | 是否使用commit log对于更新keyspace |
replication <property>是必选的。Cassandra支持以下的‘class’
‘SimpleStrategy’:一个简单策略,定义了简单的复制因子在整个集群集群中。只支持‘replication_factor’一个子选项,定义复制因子且是必选项。
l ‘NetworkTopologyStrategy’:可以为每个数据中心定义单独的复制因子。子选项以key-value方式定义,key表示数据中心名称,value表示此数据中心的复制因子。
‘OldNetworkTopologyStrategy’: 遗留的复制策略。应该避免使用,而尽量使用‘NetworkTopologyStrategy’。
试图创建一个已经存在的keyspace将返回一个错误,除非使用IF NOT EXISTS选项。如果使用它,语句将是空操作如果keyspace已经存在。
2.2. USE
语法:
<use-stmt> ::= USE <identifier>
样例:
USE myApp
USE语句使用已经存在的keyspace名称作为参数,设置此keyspace作为每次连接的当前工作keyspace。
2.3. ALTER KEYSPACE
语法:
<create-keyspace-stmt> ::= ALTER KEYSPACE <identifier> WITH <properties>
样例:
-
ALTER KEYSPACE Excelsior
-
WITH
replication = {
'class':
'SimpleStrategy',
'replication_factor' :
4};
ALTERKEYSPACE语句修改keyspace的属性。支持的<properties>与CREATE KEYSPACE相同。
2.4. DROP KEYSPACE
语法:
<drop-keyspace-stmt> ::= DROP KEYSPACE ( IF EXISTS )? <identifier>
样例:
DROP KEYSPACE myApp;
DROP KEYSPACE语句执行结果是,及时且不可逆的删除keyspace,包括keyspace中的所有column families,以及包含在column families中的所有数据。
2.5. CREATE TABLE
语法:
-
<
create-
table-stmt> ::=
CREATE (
TABLE | COLUMNFAMILY ) (
IF
NOT
EXISTS )? <tablename>
-
'(' <
column-definition> (
',' <
column-definition> )*
')'
-
(
WITH <
option> (
AND <
option>)* )?
-
-
<
column-definition> ::= <identifier> <
type> (
STATIC )? ( PRIMARY
KEY )?
-
| PRIMARY
KEY
'(' <
partition-
key> (
',' <identifier> )*
')'
-
-
<
partition-
key> ::= <identifier>
-
|
'(' <identifier> (
',' <identifier> )*
')'
-
-
<
option> ::= <property>
-
|
COMPACT
STORAGE
-
|
CLUSTERING
ORDER
样例:
-
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语句创建一个新的table。每个table都是rows的集合(常常表示相关实体),定义了一些属性。注意,CREATE COLUMNFAMILY语法是支持的,作为CREATE TABLE的别名(由于历史原因)。
试图创建一个已经存在的table将返回一个错误,除非使用IF NOT EXISTS选项。如果使用它,语句将是空操作如果table已经存在。
2.5.1. <tablename>
合法的table名称与keyspace名称规则相同(长度到32字符的字母数字标识符)。
2.5.2. <column-definition>
CREATETABLE语句定义了table的rows所拥有的columns。column由它的名称和类型定义。
在table内,row由PRIMARY KEY唯一标识。所以所有的table必须定义一个PRIMARY KEY。一个PRIMARY KEY可以由一个或多个columns组成。如果PRIMARY KEY只有一个column,则可以直接在此column之后定义。否则PRIMARY KEY必须逗号分割,以括号包含多个columns来定义。注意:
-
CREATE
TABLE t (
-
kint PRIMARY
KEY,
-
other
text
-
)
等价于
-
CREATE
TABLE t (
-
kint,
-
other
text,
-
PRIMARY
KEY (k)
-
)
2.5.3. Partition key 和clusteringcolumns
在CQL中,列的顺序定义了主键。第一个column的key称为partition key。所有的rows共享相同的partition key(甚至在跨表中),则存储在相同的物理节点上。注意,可能会存在复合partition key,比如partition key由多个columns组成,使用括号包含多个columns组成partition key。
PRIMARYKEY中剩下的columns,则成为clustering columns。在给定的物理节点和给定的partition key上,clustering columns决定了存储的顺序,使得在clustering columns查询时效率很高。
2.5.4. STATIC columns
一些columns可以声明为STATIC,column声明为static将被拥有相同partition的所有rows共享(即拥有相同的partition key)。例如:
-
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;
最后查询语句,s的值为‘static1’
使用static columns有以下限制:
table中COMPACT STORAGE项不能为static
一个table如果没有clustering columns,则不能有static columns(因为table没有clustering columns,则每个partition有且仅有一行,则每个column都是static)
只有非PRIMARY KEY的columns才能为static
<option>
CREATETABLE语句支持一些options来配置新的table。这些options被定义在WITH之后。
第一个option是COMPACT STORAGE。这个选项主要是针对向后兼容性,对于定义CQL3之前创建的table。这个选项提供了在磁盘上更紧凑的布局,但代价是减少了table的灵活性和可扩展性。最显著的是,COMPACT STORAGE不支持collections和static columns,且COMPACT STORAGE表至少有一个clustering columns。由于这些原因,COMPACT STORAGE不建议使用。
另一个option是CLUSTERING ORDER。它允许定义rows在磁盘的顺序。
表的创建支持以下的<property>:
option | kind | default | description |
comment | simple | none | 注释 |
read_repair_chance | simple | 0.1 | 查询额外节点的概率对于read repairs |
dclocal_read_repair_chance | simple | 0 | 查询额外节点的概率对于本地数据中心的read repairs |
gc_grace_seconds | simple | 864000 | 等待垃圾回收的时间 |
bloom_filter_fp_chance | simple | 0.00075 | SSTable bloom filter的false positive的目标概率(降低此值将会影响bloom filter在内存和磁盘的大小) |
compaction | simple | see below | The compaction options to use, see below. |
compression | simple | see below | Compression options, see below. |
caching | simple | keys_only | 是否缓存keys(“key cache”)和rows(“row cache”)对于此table。合法的值为:all,keys_only,rows_only和none |
default_time_to_live | simple | 0 | 此table缺省的过期时间,单位为秒 |
2.5.6. compaction options
compaction属性为’class’子选项,定义了压缩策略。默认支持的class为'SizeTieredCompactionStrategy' 和'LeveledCompactionStrategy'
option | supported compaction strategy | default | description |
enabled | all | true | Boolean表示compaction是否开启 |
tombstone_threshold | all | 0.2 | 如果SSTable的gcable tombstones超过这个比率,则SSTable将会进行压缩来清楚这些tombstones |
tombstone_compaction_interval | all | 1 day | SSTable等待时间对于“tombstone compaction”,其中“tombstone compaction”会促发压缩,如果SSTable的gcable tombstones查过tombstone_threshold |
unchecked_tombstone_compaction | all | false | 设置true则开启更激进的tombstone compaction,单个SSTable的tombstone compaction运行将不会检查 |
min_sstable_size | SizeTieredCompactionStrategy | 50MB | SSTable压缩的大小分层策略 |
min_threshold | SizeTieredCompactionStrategy | 4 | SSTable最小数量,需要开启次要compaction |
max_threshold | SizeTieredCompactionStrategy | 32 | SSTable通过次要compaction处理的最大数量 |
bucket_low | SizeTieredCompactionStrategy | 0.5 | SSTable的bucket大小在[average_size * bucket_low, average_size * bucket_high] |
bucket_high | SizeTieredCompactionStrategy | 1.5 | SSTable的bucket大小在[average_size * bucket_low, average_size * bucket_high] |
sstable_size_in_mb | LeveledCompactionStrategy | 5MB | SSTable在leveled strategy中的大小。注意SSTable大小应该小于或等于sstable_size_in_mb |
2.5.7. Compression属性
option | default | description |
sstable_compression | LZ4Compressor | Compression算法,默认有:LZ4Compressor,SnappyCompressor和DeflateCompressor。使用string(’’)关闭Compression |
chunk_length_kb | 64KB | SSTable压缩的块大小。增大此值可以提高压缩效率,但增加了从磁盘读取数据的最小数量 |
crc_check_chance | 1.0 | 启用压缩时,每个压缩块包含一个校验,目的是为了检测磁盘bitrot,避免脏数据的传播到其他副本。默认总是检查,设置为0则关闭检查,0.5则每隔一个读检查一次 |
2.6. ALTER TABLE
语法:
-
<
alter-
table-stmt> ::=
ALTER (
TABLE | COLUMNFAMILY) <tablename> <instruction>
-
-
<instruction> ::=
ALTER <identifier>
TYPE <
type>
-
|
ADD <identifier> <
type>
-
|
DROP <identifier>
-
|
WITH <
option> (
AND <
option> )*
样例:
-
ALTER
TABLE addamsFamily
-
ALTER lastKnownLocation
TYPE
uuid;
-
-
ALTER
TABLE addamsFamily
-
ADD gravesite
varchar;
-
-
ALTER
TABLE addamsFamily
-
WITH
comment =
'A most excellent and useful column family'
-
AND read_repair_chance =
0.2;
2.7. DROP TABLE
语法:
<drop-table-stmt> ::= DROP TABLE ( IF EXISTS )? <tablename>
样例:
DROP TABLE worldSeriesAttendees;
2.8. TRUNCATE
语法:
<truncate-stmt> ::= TRUNCATE <tablename>
样例:
TRUNCATE superImportantData;
TRUNCATE语句将会完全删除所有table的数据
2.9. CREATE INDEX
语法:
-
<
create-
index-stmt> ::=
CREATE ( CUSTOM )?
INDEX (
IF
NOT
EXISTS )? ( <indexname> )?
-
ON <tablename>
'(' <
index-identifier>
')'
-
(
USING <
string> (
WITH OPTIONS = <
map-literal> )? )?
-
-
<
index-identifier> ::= <identifier>
-
|
keys( <identifier> )
样例:
-
CREATE
INDEX userIndex
ON NerdMovies (
user);
-
CREATE
INDEX
ON Mutants (abilityId);
-
CREATE
INDEX
ON
users (
keys(favs));
-
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/'};
使用CREATE INDEX语句创建二次索引对于给定的column。索引的名称可以在ON关键字之前定义。如果数据已经存在对于此column,则将会异步创建索引。在索引创建之后,新插入的数据将会自动索引。
试图创建一个已经存在的index将返回一个错误,除非使用IF NOT EXISTS选项。如果使用它,语句将是空操作如果index已经存在。
2.9.1. Indexes on Map Keys
当在map column上创建索引时,可以索引keys或values。如果column标识符放在keys()函数中,则将会在map keys上创建索引,允许在WHERE从句中使用CONTAINS KEY,否则索引将在map values上。
2.10.DROP INDEX
语法:
<drop-index-stmt> ::= DROP INDEX ( IF EXISTS )? ( <keyspace> '.' )? <identifier>
样例:
-
DROP
INDEX userIndex;
-
DROP
INDEX userkeyspace.address_index;
2.11.CREATE TYPE
语法:
-
<
create-
type-stmt> ::=
CREATE
TYPE (
IF
NOT
EXISTS )? <typename>
-
'(' <
field-definition> (
',' <
field-definition> )*
')'
-
<typename> ::= ( <keyspace-
name>
'.' )? <identifier>
-
<
field-definition> ::= <identifier> <
type>
样例:
-
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
-
)
CREATETYPE语句创建新的用户定义类型。每个类型都是一组名称,类型字段的集合。字段类型可以是任何合法类型,包含集合和其他存在的用户定义类型
试图创建一个已经存在的type将返回一个错误,除非使用IF NOT EXISTS选项。如果使用它,语句将是空操作如果type已经存在
2.12.ALTER TYPE
语法:
-
<
alter-
type-stmt> ::=
ALTER
TYPE <typename> <instruction>
-
-
<instruction> ::=
ALTER <
field-
name>
TYPE <
type>
-
|
ADD <
field-
name> <
type>
-
|
RENAME <
field-
name>
TO <
field-
name> (
AND <
field-
name>
TO <
field-
name> )*
样例:
-
ALTER
TYPE address
ALTER zip
TYPE varint
-
ALTER
TYPE address
ADD country
text
-
ALTER
TYPE address
RENAME zip
TO zipcode
AND street_name
TO street
2.13.DROP TYPE
语法:
<drop-type-stmt> ::= DROP TYPE ( IF EXISTS )? <typename>
2.14. CREATE TRIGGER
语法:
-
<
create-
trigger-stmt> ::=
CREATE
TRIGGER (
IF
NOT
EXISTS )? ( <triggername> )?
-
ON <tablename>
-
USING <
string>
样例:
CREATE TRIGGER myTrigger ON myTable USING 'org.apache.cassandra.triggers.InvertedIndex';
trigger的逻辑可以使用java语言编写,存在与外部数据库中。放入trigger代码在Cassandra的lib/triggers的子目录下,当集群启动时,会自动加载此trigger。在执行DML语句时trigger将被触发,请确保事物的原子性。
2.15.DROP TRIGGER
语法:
-
<
drop-
trigger-stmt> ::=
DROP
TRIGGER (
IF
EXISTS )? ( <triggername> )?
-
ON <tablename>
样例:
DROP TRIGGER myTrigger ON myTable;
2.16.CREATE FUNCTION
语法:
-
<
create-
function-stmt> ::=
CREATE (
OR
REPLACE )?
-
FUNCTION (
IF
NOT
EXISTS )?
-
( <keyspace>
'.' )? <
function-
name>
-
'(' <arg-
name> <arg-
type> (
',' <arg-
name> <arg-
type> )*
')'
-
( CALLED |
RETURNS
NULL )
ON
NULL
INPUT
-
RETURNS <
type>
-
LANGUAGE <
language>
-
AS <
body>
样例:
-
CREATE
OR
REPLACE
FUNCTION somefunction
-
( somearg
int, anotherarg
text, complexarg frozen<someUDT>, listarg
list<
bigint> )
-
RETURNS
NULL
ON
NULL
INPUT
-
RETURNS
text
-
LANGUAGE
java
-
AS $$
-
//
some
Java code
-
$$;
-
CREATE
FUNCTION akeyspace.fname
IF
NOT
EXISTS
-
( someArg
int )
-
CALLED
ON
NULL
INPUT
-
RETURNS
text
-
LANGUAGE
java
-
AS $$
-
//
some
Java code
-
$$;
CREATEFUNCTION会创建或替换一个用户自定义函数。
2.16.1. Function Signature
keyspace名称,函数名称,参数类型是主体,大小写敏感
CREATEFUNCTION带着OR REPLACE选项表示创建或替换已经存在的signature。CREATE FUNCTION不带OR REPLACE,则已经存在相同的signature会失败。
调用带有null的值必须在函数中声明。有两种选项:
RETURNS NULL ON NULL INPUT声明函数总是返回null,如果存在任何参数为null。
CALLED ON NULL INPUT声明函数总是会执行。
如果IF NOT EXISTS选项存在,则函数只会被创建,如果相同函数签名不存在。
ORREPLACE和IF NOT EXISTS不能同时使用。
更多详情请查看user-defined functions
2.17.DROP FUNCTION
语法:
-
<
drop-
function-stmt>::=
DROP
FUNCTION (
IF
EXISTS )?
-
( <keyspace>
'.')? <
function-
name>
-
(
'(' <arg-
type>(
',' <arg-
type> )*
')' )?
样例:
-
DROP FUNCTIONmyfunction;
-
DROP FUNCTIONmykeyspace.afunction;
-
DROP FUNCTIONafunction (
int );
-
DROP FUNCTIONafunction (
text );
2.18.CREATE AGGREGATE
语法:
-
<
create-
aggregate-stmt> ::=
CREATE (
OR
REPLACE )?
-
AGGREGATE (
IF
NOT
EXISTS )?
-
( <keyspace>
'.' )? <
aggregate-
name>
-
'(' <arg-
type> (
',' <arg-
type> )*
')'
-
SFUNC ( <keyspace>
'.' )? <state-functionname>
-
STYPE <state-
type>
-
( FINALFUNC ( <keyspace>
'.' )? <
final-functionname> )?
-
( INITCOND <init-cond> )?
样例:
-
CREATE
AGGREGATE myaggregate ( val
text )
-
SFUNC myaggregate_state
-
STYPE
text
-
FINALFUNC myaggregate_final
-
INITCOND
'foo';
更多详情请查看user-defined aggregates
STYPE定义了正式的值的类型,必须被声明。
选项INITCOND定义了aggregate的初始化状态值。默认为null。
SFUNC引用现有的函数作为正式的修改函数。函数第一个参数类型必须与STYPE匹配。函数剩下的参数类型必须匹配聚合函数的参数类型。
FINALFUNC在聚合结果返回之前调用。它必须带有一个STYPE类型的参数。FINALFUNC返回类型可以是不同的类型。FINALFUNC函数声明带有RETURNS NULL ON NULL INPUT意味着聚合返回值将会是null。
如果没有定义FINALFUNC,聚合函数返回类型为STYPE。如果定义了FINALFUNC,则返回此函数类型
2.19.DROP AGGREGATE
语法:
-
<
drop-
aggregate-stmt> ::=
DROP
AGGREGATE (
IF
EXISTS )?
-
( <keyspace>
'.' )? <
aggregate-
name>
-
(
'(' <arg-
type> (
',' <arg-
type> )*
')' )?
样例:
-
DROP
AGGREGATE myAggregate;
-
DROP
AGGREGATE myKeyspace.anAggregate;
-
DROP
AGGREGATE someAggregate (
int );
-
DROP
AGGREGATE someAggregate (
text );
3. DML
3.1. INSERT
语法:
-
<insertStatement> ::=
INSERT
INTO <tablename>
-
( ( <
name-
list>
VALUES <
value-
list> )
-
| (
JSON <
string> ))
-
(
IF
NOT
EXISTS )?
-
(
USING <
option> (
AND <
option> )* )?
-
<
names-
list> ::=
'(' <identifier> (
',' <identifier> )*
')'
-
-
<
value-
list> ::=
'(' <term-
or-literal> (
',' <term-
or-literal> )*
')'
-
-
<term-
or-literal> ::= <term>
-
| <collection-literal>
-
-
<
option> ::=
TIMESTAMP <
integer>
-
| TTL <
integer>
样例:
-
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}'
INSERT语句写入一个或多个columns对于在table中给定的row。
当使用VALUES语法时,columns列表必须提供。当使用JSON语法时,columns列表是可选的。
注意,与SQL不同,INSERT不会检查row是否存在:当不存在则创建,否则更新。
但是当使用IF NOT EXISTS时,只会进行插入操作当row不存在时。注意,使用IF NOT EXISTS将会引来不可忽略的性能问题(内部使用Paxos算法),所以尽量少用
<option>请参考update部分。同样注意INSERT不支持counters,而UPDATE支持。
3.2. UPDATE
语法:
-
<
update-stmt> ::=
UPDATE <tablename>
-
(
USING <
option> (
AND <
option> )* )?
-
SET <assignment> (
',' <assignment> )*
-
WHERE <
where-clause>
-
(
IF <condition> (
AND condition )* )?
-
-
<assignment> ::= <identifier>
'=' <term>
-
| <identifier>
'=' <identifier> (
'+' |
'-') (<
int-term> | <
set-literal> | <
list-literal>)
-
| <identifier>
'=' <identifier>
'+' <
map-literal>
-
| <identifier>
'[' <term>
']'
'=' <term>
-
-
<condition> ::= <identifier>
'=' <term>
-
| <identifier>
'[' <term>
']'
'=' <term>
-
-
<
where-clause> ::= <relation> (
AND <relation> )*
-
-
<relation> ::= <identifier>
'=' <term>
-
| <identifier>
IN
'(' ( <term> (
',' <term> )* )?
')'
-
| <identifier>
IN
'?'
-
-
<
option> ::=
TIMESTAMP <
integer>
-
| TTL <
integer>
样例:
-
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';
UPDATE语句写入一个或多个columns对于给定的row。<where-clause>用来查询更新的row,必须包含组成PRIMARY KEY的所有的columns(IN只支持partition key的最后一个column)。其他columns值通过<assignment>指定在SET关键字之后。
注意,与SQL不同,UPDATE不会检查row是否存在:当不存在则创建,否则更新。
如果使用了IF条件,则必须同时满足IF条件才会更新。使用IF将会引来不可忽略的性能问题(内部使用Paxos算法),所以尽量少用
<assignment>的c = c + 3的格式表示增加/减少counters(counters只支持增加/减少,而不支持赋予特定的值)。
3.2.1. <options>
UPDATE和INSERT支持下面的选项:
TIMESTAMP:设置操作的timestamp。如果没有指定,则coordinator将会使用当前时间(单位毫秒)。
TTL:允许指定插入值的存活事件(单位秒)。如果设置了,则在指定时间之后,数据库将自动删除。注意,TTL关注点为插入的值,这意味着后面的更新将会重置TTL。默认地,值永远不会过期。TTL为0或负数等价于没有TTL。
DELETE
语法:
-
<
delete-stmt> ::=
DELETE ( <selection> (
',' <selection> )* )?
-
FROM <tablename>
-
(
USING
TIMESTAMP <
integer>)?
-
WHERE <
where-clause>
-
(
IF (
EXISTS | ( <condition> (
AND <condition> )*) ) )?
-
-
<selection> ::= <identifier> (
'[' <term>
']' )?
-
-
<
where-clause> ::= <relation> (
AND <relation> )*
-
-
<relation> ::= <identifier>
'=' <term>
-
| <identifier>
IN
'(' ( <term> (
',' <term> )* )?
')'
-
| <identifier>
IN
'?'
-
-
<condition> ::= <identifier>
'=' <term>
-
| <identifier>
'[' <term>
']'
'=' <term>
样例:
-
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);
DELETE语句删除columns和rows。<where-clause>可以指定key的rows被删除(IN只支持partition key的最后一个column)。
DELETE支持的TIMESTAMP选项与UPDATE相同。
DELETE操作可以使用与UPDATE和INSERT类似IF条件。但是注意,使用IF将会引来不可忽略的性能问题(内部使用Paxos算法),所以尽量少用
3.4. BATCH
语法:
-
<batch-stmt> ::=
BEGIN ( UNLOGGED | COUNTER ) BATCH
-
(
USING <
option> (
AND <
option> )* )?
-
<
modification-stmt> (
';' <
modification-stmt> )*
-
APPLY BATCH
-
-
<
modification-stmt> ::= <
insert-stmt>
-
| <
update-stmt>
-
| <
delete-stmt>
-
-
<
option> ::=
TIMESTAMP <
integer>
样例:
-
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语句组合多个语句(插入,修改和删除)到一条语句中。有以下一个目的:
当批量更新时,保存了client和server网络连接
所有的批量更新属于给定的partition key,被单独执行。
默认,所有批量操作被自动完成。
注意:
BATCH语句只能包含UPDATE,INSERT和DELETE语句。
Batches不完全类似与SQL事物。
如果每个操作没有指定timestamp,则所有操作将使用同一个timestamp。
UNLOGGED
默认地,Cassandra使用batch log来确保所有的操作自动批处理执行。
当batch跨越多个partitions时,会带来性能损失。如果你不想引来此损失,可以使用UNLOGGED选项来告诉Cassandra跳过batch log。如果使用UNLOGGED,则操作将会在一个partition中执行。
3.4.2. COUNTER
使用COUNTER选项来批量更新counter。不像Cassandra的其他更新,counter更新不是幂等的。
3.4.3. <option>
BATCH也支持TIMESTAMP选项,与UPDATE语句描述类似。但是如果使用的话,TIMESTAMP则不能够在batch内部的语句使用
转载于:https://blog.51cto.com/eric100/1697169