cql_type ::=native_type
|collection_type
|user_defined_type
|tuple_type
|custom_type
1.本地类型
CQL支持的本地类型有:
native_type ::= ASCII
| BIGINT
| BLOB
| BOOLEAN
| COUNTER
| DATE
| DECIMAL
| DOUBLE
| FLOAT
| INET
| INT
| SMALLINT
| TEXT
| TIME
| TIMESTAMP
| TIMEUUID
| TINYINT
| UUID
| VARCHAR
| VARINT
下表提供了本地数据类型的其他信息,以及每种类型支持的常量类型:
type | constants supported | description |
---|---|---|
ascii |
string |
ASCII字符串 |
bigint |
integer |
64位有符号长 |
blob |
blob |
任意字节(无验证) |
boolean |
boolean |
true或false
|
counter |
integer |
计数器列(64位有符号值) |
date |
integer ,string |
日期(没有相应的时间值) |
decimal |
integer ,float |
可变精度十进制 |
double |
integer float |
64位IEEE-754浮点 |
float |
integer ,float |
32位IEEE-754浮点 |
inet |
string |
IP地址,IPv4(4字节长)或IPv6(16字节长)。 注意,没有inet常量,IP地址应该作为字符串输入 |
int |
integer |
32位有符号长 |
smallint |
integer |
16位有符号长 |
text |
string |
UTF8编码字符串 |
time |
integer ,string |
一个具有纳秒精度的时间(没有相应的日期值) |
timestamp |
integer ,string |
时间戳(日期和时间),精度为毫秒 |
timeuuid |
uuid |
版本1 UUID,通常用作“无冲突”时间戳 |
tinyint |
integer |
8位有符号长int |
uuid |
uuid |
UUID(任何版本) |
varchar |
string |
UTF8编码字符串 |
varint |
integer |
任意精度整数 |
2.计数器
计数器类型用于定义计数器列。 计数器列是其值为64位有符号整数且支持2个操作的列:递增和递减(请参见语法的UPDATE语句)。 注意,不能设置计数器的值:在第一次递增/递减之前不存在计数器,并且第一次递增/递减被假定为先前值为0。
计数器有一些重要的限制
3.使用时间戳
时间戳类型的值被编码为64位有符号整数,表示标准基本时间(1970年1月1日00:00:00 GMT)以来的毫秒数。可以把时间戳的值作为整数或使用表示ISO 8601日期的字符串输入CQL使用。 例如,以下所有值都是2011年3月2日上午04:05:00 GMT的有效时间戳值:
1299038700000
'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'
4.使用日期
日期类型的值被编码为表示距离1970年1月1日的天数的32位无符号整数,其范围为2 ^ 31。
对于时间戳,日期可以作为整数或使用日期字符串输入。 在后一种情况下,格式应为yyyy-mm-dd(例如“2011-02-03”)。
5.使用时间
'08:12:54'
'08:12:54.123'
'08:12:54.123456'
'08:12:54.123456789'
6.集合
collection_type ::= MAP '<'并且可以使用字面量集合作为它们的输入值:cql_type
','cql_type
'>' | SET '<'cql_type
'>' | LIST '<'cql_type
'>'
collection_literal ::=请注意,在字面量集合中不支持bind_marker和NULL。map_literal
|set_literal
|list_literal
map_literal ::= '{' [term
':'term
(','term
:term
)* ] '}' set_literal ::= '{' [term
(','term
)* ] '}' list_literal ::= '[' [term
(','term
)* ] ']'
6-1.值得注意的特点
集合用于存储/反规范化数量相对较少的数据。 它们对于诸如“给定用户的电话号码”,“应用于电子邮件的标签”等的事物工作良好。但是当存储的数据无限增长的时候(“由用户发送的所有消息”,“由传感器注册的事件 “...),那么集合是不合适的,并且应该使用特定的表(具有聚类列)。 具体来说,(非冻结)集合具有以下值得注意的特征和限制:
6-2.Maps
CREATE TABLE users ( id text PRIMARY KEY, name text, favs map<text, text> // A map of text keys, and text values ); INSERT INTO users (id, name, favs) VALUES ('jsmith', 'John Smith', { 'fruit' : 'Apple', 'band' : 'Beatles' }); // Replace the existing map entirely. UPDATE users SET favs = { 'fruit' : 'Banana' } WHERE id = 'jsmith';
此外,map支持
UPDATE users SET favs['author'] = 'Ed Poe' WHERE id = 'jsmith'; UPDATE users SET favs = favs + { 'movie' : 'Cassablanca', 'band' : 'ZZ Top' } WHERE id = 'jsmith';
DELETE favs['author'] FROM users WHERE id = 'jsmith'; UPDATE users SET favs = favs - { 'movie', 'band'} WHERE id = 'jsmith';最后,需要说明的是对于插入和更新操作都允许TTL,但是在这两种情况下,TTL集合仅适用于新插入/更新的元素。换一种说法下面的语句将仅仅只是把TTL应用于{'color':'green'}记录,其余的map不受影响:
UPDATE users USING TTL 10 SET favs['color'] = 'green' WHERE id = 'jsmith';
6-3.Sets
CREATE TABLE images ( name text PRIMARY KEY, owner text, tags set<text> // A set of text values ); INSERT INTO images (name, owner, tags) VALUES ('cat.jpg', 'jsmith', { 'pet', 'cute' }); // Replace the existing set entirely UPDATE images SET tags = { 'kitten', 'cat', 'lol' } WHERE name = 'cat.jpg';
此外,set支持
UPDATE images SET tags = tags + { 'gray', 'cuddly' } WHERE name = 'cat.jpg';
UPDATE images SET tags = tags - { 'cat' } WHERE name = 'cat.jpg';最后,和map相同,TTL只适用于新插入的值。
6-4.Lists
列表是非唯一值的(排序)集合,其中元素按列表中的位置排序。您可以定义和插入一个list:
CREATE TABLE plays ( id text PRIMARY KEY, game text, players int, scores list<int> // A list of integers ) INSERT INTO plays (id, game, players, scores) VALUES ('123-afde', 'quake', 3, [17, 4, 2]); // Replace the existing list entirely UPDATE plays SET scores = [ 3, 9, 4] WHERE id = '123-afde';
此外,list支持
UPDATE plays SET players = 5, scores = scores + [ 14, 21 ] WHERE id = '123-afde';UPDATE plays SET players = 6, scores = [ 3 ] + scores WHERE id = '123-afde';
UPDATE plays SET scores[1] = 7 WHERE id = '123-afde';
DELETE scores[1] FROM plays WHERE id = '123-afde';
UPDATE plays SET scores = scores - [ 12, 21 ] WHERE id = '123-afde';警告:附加和前置操作本质上不是幂等的。 因此,如果操作超时,则重试操作是不安全并且它有可能导致附加/前置值两次。
警告:通过位置设置和移除元素并移除特定值会在内部产生先读后写。因此,它们将比常规的更新耗费更多的资源,运行得更慢。
最后,和map相同,TTL只适用于新插入的值。
7.用户自定义类型
user_defined_type ::=UDT有一个名称(用于该类型的声明列),并且是一组命名和类型的字段。字段名称可以是任何类型,包括集合或其他UDT。例如:udt_name
udt_name ::= [keyspace_name
'.' ]identifier
CREATE TYPE phone ( country_code int, number text, ) CREATE TYPE address ( street text, city text, zip text, phones map<text, phone> ) CREATE TABLE user ( name text PRIMARY KEY, addresses map<text, frozen<address>> )注意:
7-1.创建UDT
create_type_statement ::= CREATE TYPE [ IF NOT EXISTS ]udt_name
'('field_definition
( ','field_definition
)* ')' field_definition ::=identifier
cql_type
7-2.UDT字面量
udt_literal ::= '{'换句话说,一个UDT字面量就像一个map字面量,但它的键是类型的字段的名称。例如,可以使用以下代码插入到上一节中的表定义中:identifier
':'term
( ','identifier
':'term
)* '}'
INSERT INTO user (name, addresses) VALUES ('z3 Pr3z1den7', { 'home' : { street: '1600 Pennsylvania Ave NW', city: 'Washington', zip: '20500', phones: { 'cell' : { country_code: 1, number: '202 456-1111' }, 'landline' : { country_code: 1, number: '...' } } }, 'work' : { street: '1600 Pennsylvania Ave NW', city: 'Washington', zip: '20500', phones: { 'fax' : { country_code: 1, number: '...' } } } })为了有效,UDT字面量应该只包括由类型定义的字段,它是一个字面量,但它可以省略一些字段(在这种情况下,这些字段将为null)。
7-3.更改UDT
alter_type_statement ::= ALTER TYPE您可以:udt_name
alter_type_modification
alter_type_modification ::= ALTERidentifier
TYPEcql_type
| ADDfield_definition
| RENAMEidentifier
TOidentifier
(identifier
TOidentifier
)*
address ADD country text
)。对于在添加之前创建的类型的任何值,该新字段将为null。ALTER TYPE address RENAME zip TOzipcode
)。
7-4.删除UDT
drop_type_statement ::= DROP TYPE [ IF EXISTS ] udt_name
删除类型会立即产生结果,不可逆地删除该类型。 但是,尝试删除仍在由另一个类型,表或函数使用的类型将导致错误。
8.元组
tuple_type ::= TUPLE '<'因此可以使用:cql_type
( ','cql_type
)* '>' tuple_literal ::= '('term
( ','term
)* ')'
CREATE TABLE durations ( event text, duration tuple<int, text>, ) INSERT INTO durations (event, duration) VALUES ('ev1', (3, 'hours'));与其他“组合”类型(集合和UDT)不同,元组总是被冻结(不需要freeze关键字),并且不可能只更新元组的一些元素(不更新整个元组)。另外,元组字面量应该总是具有与在类型中声明的值相同的值,其中的一些值可以是null,但是它们需要被明确声明为这样。
9.自定义类型
自定义类型定义为:
custom_type ::= string
自定义类型是一个字符串,它包含继承自服务器端抽象类类的Java类的名称,并且可以由Cassandra加载(因此应该在运行Cassandra的每个节点的CLASSPATH中)。该类将定义什么值对类型有效,以及当用于聚类列时如何排序。处于一些其它目的,自定义类型的值与blob的值相同,并且可以使用blob字面量语法输入。