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_]*。

一些标识符,比如SELECTWITH,是关键字。他们有固定的意义且被保留的。

标识符和关键字是大小写不敏感的。因此SELECTselectsElEcT相同。使用的常常约定关键字大写,标识符小写。

1.4.    常量

CQL定义了下面类型的常量:strings,integers,floats,booleans,uuids和blobs:

1.5.    注释

CQL使用注释:--或//

多行注释:/*   */


     
     
  1. -- This is a comment
  2. // This is a  comment too
  3. /* This is
  4.    a multi-line comment */

1.6.    语句

SQL语句可以分为3类:

  • DDL:改变和设置数据存储方式

  • DML:改变数据

  • Queries:查询数据

所有语句以分号(;)结束,除了单条语句外。支持的语句如下:


     
     
  1. <identifier> ::= any quoted or unquoted identifier, excluding reserved keywords
  2.  <tablename> ::= (<identifier> '.')? <identifier>
  3.  
  4.     <string> ::= a string constant
  5.    <integer> ::= an integer constant
  6.      <float> ::= a float constant
  7.     <number> ::= <integer> | <float>
  8.       <uuid> ::= a uuid constant
  9.    <boolean> ::= a boolean constant
  10.        <hex> ::= a blob constant
  11.  
  12.   <constant> ::= <string> | <number>| <uuid>| <boolean> | <hex>
  13.   <variable> ::= '?' | ':' <identifier>
  14.       <term> ::= <constant>| <collection-literal> | <variable> | <function> '(' (<term> (',' <term>)*)? ')'
  15.  
  16.   <collection-literal> ::= <map-literal>
  17.                          | < set-literal>
  18.                          | < list-literal>
  19.          < map-literal> ::=  '{' ( <term>  ':' <term> (  ',' <term>  ':' <term> )* )?  '}'
  20.          < set-literal> ::=  '{' ( <term> (  ',' <term> )* )?  '}'
  21.         < list-literal> ::=  '[' ( <term> (  ',' <term> )* )?  ']'
  22.  
  23.     < function> ::= <ident>
  24.  
  25.   <properties> ::= <property> ( AND <property>)*
  26.     <property> ::= <identifier>  '=' ( <identifier> | < constant> | < map-literal> )


上面语法在实际中并不是所有的都是合法的。最显著的是,<variable>和嵌套<collection-literal>在<collection-literal>中是不被允许的。

<variable>可以是匿名(一个问号?)也可以命名(在:之前的一个标识)。唯一区别就是命名更容易被引用。

<properties>用来创建或修改keyspaces和tables。每一个<properties>类型可以是simplemap

<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>
     
     

样例:


     
     
  1. CREATE KEYSPACE Excelsior
  2.             WITH  replication = { 'class''SimpleStrategy''replication_factor' :  3};
  3.  
  4. CREATE KEYSPACE Excalibur
  5.             WITH  replication = { 'class''NetworkTopologyStrategy''DC1' :  1'DC2' :  3}
  6.              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>
     
     


样例:


     
     
  1. ALTER KEYSPACE Excelsior
  2.            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

语法:


     
     
  1. < create- table-stmt> ::=  CREATE (  TABLE | COLUMNFAMILY ) (  IF  NOT  EXISTS )? <tablename>
  2.                            '(' < column-definition> (  ',' < column-definition> )*  ')'
  3.                           (  WITH < option> (  AND < option>)* )?
  4.  
  5. < column-definition> ::= <identifier> < type> (  STATIC )? ( PRIMARY  KEY )?
  6.                       | PRIMARY  KEY  '(' < partition- key> (  ',' <identifier> )*  ')'
  7.  
  8. < partition- key> ::= <identifier>
  9.                   |  '(' <identifier> ( ',' <identifier> )*  ')'
  10.  
  11. < option> ::= <property>
  12.            |  COMPACT  STORAGE
  13.            |  CLUSTERING  ORDER


样例:


     
     
  1. CREATE  TABLE monkeySpecies (
  2.     species  text PRIMARY  KEY,
  3.     common_name  text,
  4.     population varint,
  5.     average_size  int
  6. WITH  comment= 'Important biological records'
  7.     AND read_repair_chance =  1.0;
  8.  
  9. CREATE  TABLE timeline (
  10.     userid  uuid,
  11.     posted_month  int,
  12.     posted_time  uuid,
  13.      body  text,
  14.     posted_by  text,
  15.     PRIMARY  KEY (userid, posted_month, posted_time)
  16. 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来定义。注意:


     
     
  1. CREATE  TABLE t (
  2.     kint PRIMARY  KEY,
  3.    other  text
  4. )


等价于


     
     
  1. CREATE  TABLE t (
  2.     kint,
  3.    other  text,
  4.    PRIMARY  KEY (k)
  5. )


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)。例如:


     
     
  1. CREATE  TABLE  test (
  2.     pk  int,
  3.     t  int,
  4.     v  text,
  5.     s  text  static,
  6.     PRIMARY  KEY (pk, t)
  7. );
  8. INSERT  INTO  test(pk, t, v, s)  VALUES ( 00'val0''static0');
  9. INSERT  INTO  test(pk, t, v, s)  VALUES ( 01'val1''static1');
  10. 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

语法:


     
     
  1. < alter- table-stmt> ::=  ALTER ( TABLE | COLUMNFAMILY) <tablename> <instruction>
  2.  
  3. <instruction> ::=  ALTER <identifier>  TYPE < type>
  4.                 |  ADD   <identifier> < type>
  5.                 |  DROP  <identifier>
  6.                 |  WITH  < option> (  AND < option> )*


样例:


     
     
  1. ALTER  TABLE addamsFamily
  2. ALTER lastKnownLocation  TYPE  uuid;
  3.  
  4. ALTER  TABLE addamsFamily
  5. ADD gravesite  varchar;
  6.  
  7. ALTER  TABLE addamsFamily
  8. WITH  comment =  'A most excellent and useful column family'
  9.   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

语法:


     
     
  1. < create- index-stmt> ::=  CREATE ( CUSTOM )?  INDEX (  IF  NOT  EXISTS )? ( <indexname> )?
  2.                              ON <tablename>  '(' < index-identifier>  ')'
  3.                             (  USING < string> (  WITH OPTIONS = < map-literal> )? )?
  4.  
  5. < index-identifier> ::= <identifier>
  6.                      |  keys( <identifier> )


样例:


     
     
  1. CREATE  INDEX userIndex  ON NerdMovies ( user);
  2. CREATE  INDEX  ON Mutants (abilityId);
  3. CREATE  INDEX  ON  users ( keys(favs));
  4. CREATE CUSTOM  INDEX  ON  users (email)  USING  'path.to.the.IndexClass';
  5. 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>
     
     


样例:


     
     
  1. DROP  INDEX userIndex;
  2. DROP  INDEX userkeyspace.address_index;


2.11.CREATE TYPE

语法:


     
     
  1. < create- type-stmt> ::=  CREATE  TYPE (  IF  NOT  EXISTS )? <typename>
  2.                           '(' < field-definition> (  ',' < field-definition> )*  ')'
  3. <typename> ::= ( <keyspace- name'.' )? <identifier>
  4. < field-definition> ::= <identifier> < type>


样例:


     
     
  1. CREATE  TYPE address (
  2.     street_name  text,
  3.     street_number  int,
  4.     city  text,
  5.     state  text,
  6.     zip  int
  7. )
  8. CREATE  TYPE work_and_home_addresses (
  9.     home_address address,
  10.     work_address address
  11. )



        CREATETYPE语句创建新的用户定义类型。每个类型都是一组名称,类型字段的集合。字段类型可以是任何合法类型,包含集合和其他存在的用户定义类型

    试图创建一个已经存在的type将返回一个错误,除非使用IF NOT EXISTS选项。如果使用它,语句将是空操作如果type已经存在

2.12.ALTER TYPE

语法:


     
     
  1. < alter- type-stmt> ::=  ALTER  TYPE <typename> <instruction>
  2.  
  3. <instruction> ::=  ALTER < field- nameTYPE < type>
  4.                 |  ADD < field- name> < type>
  5.                 |  RENAME < field- nameTO < field- name> (  AND < field- nameTO < field- name> )*


样例:


     
     
  1. ALTER  TYPE address  ALTER zip  TYPE varint
  2. ALTER  TYPE address  ADD country  text
  3. 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

语法:


     
     
  1. < create- trigger-stmt> ::=  CREATE  TRIGGER (  IF  NOT  EXISTS )? ( <triggername> )?
  2.                              ON <tablename> 
  3.                              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

语法:


     
     
  1. < drop- trigger-stmt> ::=  DROP  TRIGGER (  IF  EXISTS )? ( <triggername> )?
  2.                              ON <tablename>


样例:

DROP TRIGGER myTrigger ON myTable;
     
     


2.16.CREATE FUNCTION

语法:


     
     
  1. < create- function-stmt> ::=  CREATE (  OR  REPLACE )? 
  2.                              FUNCTION (  IF  NOT  EXISTS )?
  3.                             ( <keyspace>  '.' )? < function- name>
  4.                              '(' <arg- name> <arg- type> (  ',' <arg- name> <arg- type> )*  ')'
  5.                             ( CALLED |  RETURNS  NULL )  ON  NULL  INPUT
  6.                              RETURNS < type>
  7.                              LANGUAGE < language>
  8.                              AS < body>


样例:


     
     
  1. CREATE  OR  REPLACE  FUNCTION somefunction
  2.     ( somearg  int, anotherarg  text, complexarg frozen<someUDT>, listarg  list< bigint> )
  3.      RETURNS  NULL  ON  NULL  INPUT
  4.      RETURNS  text
  5.      LANGUAGE  java
  6.      AS $$
  7.        //  some  Java code
  8.     $$;
  9. CREATE  FUNCTION akeyspace.fname  IF  NOT  EXISTS
  10.     ( someArg  int )
  11.     CALLED  ON  NULL  INPUT
  12.      RETURNS  text
  13.      LANGUAGE  java
  14.      AS $$
  15.        //  some  Java code
  16.     $$;


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

语法:


     
     
  1. < drop- function-stmt>::=  DROP  FUNCTION (  IF  EXISTS )?
  2.                          ( <keyspace>  '.')? < function- name>
  3.                          (  '(' <arg- type>(  ',' <arg- type> )*  ')' )?


样例:


     
     
  1. DROP FUNCTIONmyfunction;
  2. DROP FUNCTIONmykeyspace.afunction;
  3. DROP FUNCTIONafunction (  int );
  4. DROP FUNCTIONafunction (  text );


2.18.CREATE AGGREGATE

语法:


     
     
  1. < create- aggregate-stmt> ::=  CREATE (  OR  REPLACE )? 
  2.                              AGGREGATE (  IF  NOT  EXISTS )?
  3.                             ( <keyspace>  '.' )? < aggregate- name>
  4.                              '(' <arg- type> (  ',' <arg- type> )*  ')'
  5.                             SFUNC ( <keyspace>  '.' )? <state-functionname>
  6.                             STYPE <state- type>
  7.                             ( FINALFUNC ( <keyspace>  '.' )? < final-functionname> )?
  8.                             ( INITCOND <init-cond> )?


样例:


     
     
  1. CREATE  AGGREGATE myaggregate ( val  text )
  2.   SFUNC myaggregate_state
  3.   STYPE  text
  4.   FINALFUNC myaggregate_final
  5.   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

语法:


     
     
  1. < drop- aggregate-stmt> ::=  DROP  AGGREGATE (  IF  EXISTS )?
  2.                          ( <keyspace>  '.' )? < aggregate- name>
  3.                          (  '(' <arg- type> (  ',' <arg- type> )*  ')' )?


样例:


     
     
  1. DROP  AGGREGATE myAggregate;
  2. DROP  AGGREGATE myKeyspace.anAggregate;
  3. DROP  AGGREGATE someAggregate (  int );
  4. DROP  AGGREGATE someAggregate (  text );


3.  DML

3.1.    INSERT

语法:


     
     
  1. <insertStatement> ::=  INSERT  INTO <tablename>
  2.                       ( ( < name- listVALUES < value- list> )
  3.                       | (  JSON < string> ))
  4.                       (  IF  NOT  EXISTS )?
  5.                       (  USING < option> (  AND < option> )* )?
  6. < names- list> ::=  '(' <identifier> (  ',' <identifier> )*  ')'
  7.  
  8. < value- list> ::=  '(' <term- or-literal> (  ',' <term- or-literal> )*  ')'
  9.  
  10. <term- or-literal> ::= <term>
  11.                     | <collection-literal>
  12.  
  13. < option> ::=  TIMESTAMP < integer>
  14.            | TTL < integer>


样例:


     
     
  1. INSERT  INTO NerdMovies (movie, director, main_actor,  year)
  2.                  VALUES ( 'Serenity''Joss Whedon''Nathan Fillion'2005USING TTL  86400;
  3. 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

语法:


     
     
  1. < update-stmt> ::=  UPDATE <tablename>
  2.                   (  USING < option> (  AND < option> )* )?
  3.                    SET <assignment> (  ',' <assignment> )*
  4.                    WHERE < where-clause>
  5.                   (  IF <condition> (  AND condition )* )?
  6.  
  7. <assignment> ::= <identifier>  '=' <term>
  8.                | <identifier>  '=' <identifier> ( '+' |  '-') (< int-term> | < set-literal> | < list-literal>)
  9.                | <identifier>  '=' <identifier>  '+' < map-literal>
  10.                | <identifier>  '[' <term>  ']'  '=' <term>
  11.  
  12. <condition> ::= <identifier>  '=' <term>
  13.               | <identifier>  '[' <term>  ']'  '=' <term>
  14.  
  15. < where-clause> ::= <relation> (  AND <relation> )*
  16.  
  17. <relation> ::= <identifier>  '=' <term>
  18.              | <identifier>  IN  '(' ( <term> (  ',' <term> )* )?  ')'
  19.              | <identifier>  IN  '?'
  20.  
  21. < option> ::=  TIMESTAMP < integer>
  22.            | TTL < integer>


样例:


     
     
  1. UPDATE NerdMovies  USING TTL  400
  2. SET director =  'Joss Whedon',
  3.     main_actor =  'Nathan Fillion',
  4.      year =  2005
  5. WHERE movie =  'Serenity';
  6. UPDATE UserActions  SET total = total +  2 
  7. 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

语法:


     
     
  1. < delete-stmt> ::=  DELETE ( <selection> (  ',' <selection> )* )?
  2.                    FROM <tablename>
  3.                   (  USING  TIMESTAMP < integer>)?
  4.                    WHERE < where-clause>
  5.                   (  IF (  EXISTS | ( <condition> (  AND <condition> )*) ) )?
  6.  
  7. <selection> ::= <identifier> (  '[' <term>  ']' )?
  8.  
  9. < where-clause> ::= <relation> (  AND <relation> )*
  10.  
  11. <relation> ::= <identifier>  '=' <term>
  12.              | <identifier>  IN  '(' ( <term> (  ',' <term> )* )?  ')'
  13.              | <identifier>  IN  '?'
  14.  
  15. <condition> ::= <identifier>  '=' <term>
  16.               | <identifier>  '[' <term>  ']'  '=' <term>


样例:


     
     
  1. DELETE  FROM NerdMovies  USING  TIMESTAMP  1240003134  WHERE movie =  'Serenity';
  2. 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

语法:


     
     
  1. <batch-stmt> ::=  BEGIN ( UNLOGGED | COUNTER ) BATCH
  2.                  (  USING < option> (  AND < option> )* )?
  3.                     < modification-stmt> (  ';' < modification-stmt> )*
  4.                   APPLY BATCH
  5.  
  6. < modification-stmt> ::= < insert-stmt>
  7.                       | < update-stmt>
  8.                       | < delete-stmt>
  9.  
  10. < option> ::=  TIMESTAMP < integer>


样例:


     
     
  1. BEGIN BATCH
  2.    INSERT  INTO  users (userid,  passwordnameVALUES ( 'user2''ch@ngem3b''second user');
  3.    UPDATE  users  SET  password =  'ps22dhds'  WHERE userid =  'user3';
  4.    INSERT  INTO  users (userid,  passwordVALUES ( 'user4''ch@ngem3c');
  5.    DELETE  name  FROM  users  WHERE userid =  'user1';
  6. 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内部的语句使用