转载自: https://help.aliyun.com/document_detail/127146.html
(PS: 便于查看)

和其他语言一样,CQL也支持一系列灵活的数据类型,包括基本的数据类型,集合类型以及用户自定义数据类(User-Defined Types, UDTs)。本文将介绍CQL支持的数据类型。

数字数据类型(Numeric Data Types)

CQL支持的数字数据类型包括整型和浮点型,这些数据类型和Java的标准数据类型类似。包括以下几种:

  • int:32位有符号整型,和Java中的int类似;
  • bigint:64位长整型,和Java中的long类似;
  • smallint:16位有符号整型,和Java中的short类似,Apache Cassandra 2.2开始引入;
  • tinyint:8位有符号整型,和Java中的tinyint类似,Apache Cassandra 2.2开始引入;
  • varint:可变精度有符号整数,和Java中的java.math.BigInteger类似;
  • float:32位IEEE-754浮点型,和Java中的float类似;
  • double:64位IEEE-754浮点型,和Java中的double类似;
  • decimal:可变精度的decimal,和Java中的java.math.BigDecimal类似。

    文本数据类型(Textual Data Types)

    CQL中提供了两种数据类型用于存放文本类型:

  • text, varchar:UTF-8编码的字符串,这个在CQL中使用的比较普遍;

  • ascii:ASCII字符串。

    时间和标识符数据类型(Time and Identity Data Types)

  • timestamp:时间可以使用64位有符号的整数表示,但是一般为了可读性,我们会选择支持ISO 8601标准的时间戳表示。建议在使用时间戳的时候都指定时区,而不是依赖系统的时区。

  • date, time:在Apache Cassandra 2.1版本之前只支持timestamp类型,里面包含了日期和时间;从Cassandra 2.2版本开始引入了date和time时间类型,分别表示日期和时间。和timestamp一样,这个也是支持ISO 8601标准的。
  • uuid:通用唯一识别码(universally unique identifier,UUID)是128位数据类型,其实现包含了很多种类型,其中最有名的为Type 1和Type 4。CQL中的uuid实现是Type 4 UUID,其实现完全是基于随机数的。UUID的数据类似于ab7c46ac-c194-4c71-bb03-0f64986f3daa,uuid类型通常用作代理键,可以单独使用,也可以与其他值组合使用。由于UUID的长度有限,因此并不能绝对保证它们是唯一的。我们可以在CQL中使用uuid() 获取Type 4 UUID。
  • timeuuid:这个是Type 1 UUID,它的实现基于计算机的MAC地址,系统时间和用于防止重复的序列号。CQL中提供了now(), dateOf()以及unixTimestampOf()等函数来操作timeuuid数据类型。由于这些简便的函数,timeuuid的使用频率比uuid数据类型多。

    集合数据类型

这种数据类型可以存储集合数据类型,set里面的元素存储是无序的,但是cql返回的数据是有序的。set里面可以存储前面介绍的数据类型,也可以是用户自定义数据类型,甚至是其他集合类型。
下述案例以存储email信息为例,来说明set的使用:

  1. cqlsh:test_keyspace> CREATE TABLE test_user (first_name text , last_name text,emails set<text>, PRIMARY KEY (first_name)) ;
  2. cqlsh:test_keyspace> INSERT INTO test_user (first_name, last_name,emails) VALUES ('Wu', 'Shi',{'iteblog@iteblog.com'});
  3. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  4. first_name | emails | last_name
  5. ------------+-------------------------+-----------
  6. Wu | {'iteblog@iteblog.com'} | Shi
  7. (1 rows)

上述命令表示为first_name为Wu的数据添加了email信息。如果您还需要往里面加一些email信息,可以使用下述语法:

  1. cqlsh:test_keyspace> UPDATE test_user SET emails = emails + {'cassandra@iteblog.com' } WHERE first_name = 'Wu';
  2. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  3. first_name | emails | last_name
  4. ------------+--------------------------------------------------+-----------
  5. Wu | {'cassandra@iteblog.com', 'iteblog@iteblog.com'} | Shi
  6. (1 rows)

first_name为Wu的记录已经添加了两条email信息了。如果您需要删除email,可以使用下述语法:

  1. cqlsh:test_keyspace> UPDATE test_user SET emails = emails - {'cassandra@iteblog.com'} WHERE first_name = 'Wu';
  2. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  3. first_name | emails | last_name
  4. ------------+-------------------------+-----------
  5. Wu | {'iteblog@iteblog.com'} | Shi
  6. (1 rows)
  7. cqlsh:test_keyspace> UPDATE test_user SET emails ={} WHERE first_name = 'Wu';
  8. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  9. first_name | emails | last_name
  10. ------------+--------+-----------
  11. Wu | null | Shi
  12. (1 rows)

上述命令表示使用**SET emails = emails - {'cassandra@iteblog.com'}**从用户email列表里面删除email,使用**SET emails ={}**清空用户的email。

list

list包含了有序的列表数据,默认情况下,数据是按照插入顺序保存的。以test_user表为例,如果需要往该表中添加电话等信息,示例如下:

  1. cqlsh:test_keyspace> ALTER TABLE test_user ADD phone list<text>;
  2. cqlsh:test_keyspace> UPDATE test_user SET phone = ['1311234****' ] WHERE first_name = 'Wu';
  3. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  4. first_name | emails | last_name | phone
  5. ------------+--------+-----------+-----------------
  6. Wu | null | Shi | ['1311234****']
  7. (1 rows)

上述命令表示给first_name为Wu的记录添加了电话信息。如果需要再添加电话信息,其操作和set添加信息类似,例如:

  1. cqlsh:test_keyspace> UPDATE test_user SET phone = phone + ['1551111****' ] WHERE first_name = 'Wu';
  2. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  3. first_name | emails | last_name | phone
  4. ------------+--------+-----------+--------------------------------
  5. Wu | null | Shi | ['1311234****', '1551111****']
  6. (1 rows)

可以看出,新加入的电话号码被放在list的后面了。如果使用下述语句,则可以往电话号码的前面添加信息:

  1. cqlsh:test_keyspace> UPDATE test_user SET phone = ['1334444****' ] + phone WHERE first_name = 'Wu';
  2. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  3. first_name | emails | last_name | phone
  4. ------------+--------+-----------+-----------------------------------------------
  5. Wu | null | Shi | ['1334444****', '1311234****', '1551111****']
  6. (1 rows)

您可以使用下标从list数据类型中修改数据:

  1. cqlsh:test_keyspace> UPDATE test_user SET phone[1] = '1888888****' WHERE first_name = 'Wu';
  2. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  3. first_name | emails | last_name | phone
  4. ------------+--------+-----------+-----------------------------------------------
  5. Wu | null | Shi | ['1334444****', '1888888****', '1551111****']
  6. (1 rows)

下标为1的元素被修改了。也可以使用下标删除数据:

  1. cqlsh:test_keyspace> DELETE phone[2] from test_user WHERE first_name = 'Wu';
  2. cqlsh:test_keyspace> SELECT * FROM test_user WHERE first_name = 'Wu';
  3. first_name | emails | last_name | phone
  4. ------------+--------+-----------+--------------------------------
  5. Wu | null | Shi | ['1334444****', '1888888****']
  6. (1 rows)

当然,删除元素也可以使用**SET phone_numbers = phone_numbers - [ '1334444****' ]**

map

map数据类型包含了key/value键值对。key和value可以是任何类型,除了counter类型。使用如下:

  1. cqlsh:test_keyspace> ALTER TABLE test_user ADD login_sessions map<timeuuid, int>;
  2. cqlsh:test_keyspace> UPDATE test_user SET login_sessions = {now(): 13, now(): 18} WHERE first_name = 'Wu';
  3. cqlsh:test_keyspace> SELECT first_name, login_sessions FROM test_user WHERE first_name = 'Wu';
  4. first_name | login_sessions
  5. ------------+--------------------------------------------------------------------------------------
  6. Wu | {1cc61ff0-5f8b-11e9-ac3a-5336cd8118f6: 13, 1cc61ff1-5f8b-11e9-ac3a-5336cd8118f6: 18}
  7. (1 rows)

其他简单数据类型

  • boolean:取值只能为true/false,在cql中输入的这两个值无论大小如何写法,其输出都是True/False;
  • blob:二进制大对象(binary large object)是任意字节数组的术语简称。这个类型在存储媒体或者其他二进制数据类型时很有用,Cassandra并不会检查其中存储的二进制数据是否有效。Cassandra中二进制大对象是以十六进制存储的,如果想将任意的文本数据类型使用blob存储,可以使用textAsBlob()函数实现。
  • inet:这个数据类型可以表示IPv4或IPv6网络地址。cqlsh接受用于定义IPv4地址的任何合法格式,包括包含十进制,八进制或十六进制值的点或非点式表示。CQL统一输出为192.168.XX.XX这种格式的IP地址。
  • counter:计数器数据类型是64位有符号整数,其值不能直接设置,而只能递增或递减。计数器类型的使用有一些特殊限制,它不能用作主键的一部分;如果使用计数器,则除primary key列之外的所有列都必须是计数器。

    用户自定义数据类型(User-Defined Types)

    如果Cassandra中内置的数据类型无法满足您的需求,您还可以使用自定义数据类型。例如,需要使用一个字段存储用户的地址信息,需要获取地址的邮编、街道等信息。如果使用text来存储是不能满足我们的需求的,此时您可以自定义数据类型,示例如下: ```shell cqlsh:test_keyspace> CREATE TYPE address (
    1. ... street text,
    2. ... city text,
    3. ... state text,
    4. ... zip_code int);
  1. 上述语句定义了address数据类型。需要注意的是,Cassandra中数据类型的定义是keyspace范围的,表明 address数据类型只能在test_keyspace里面使用。如果您使用`**DESCRIBE KEYSPACE test_keyspace**`,可以看到address数据类型属于test_keyspace的一部分。现在定义好了address数据类型,使用示例如下:
  2. ```shell
  3. cqlsh:test_keyspace> ALTER TABLE test_user ADD addresses map<text, frozen<address>>;
  4. cqlsh:test_keyspace> UPDATE test_user SET addresses = addresses + {'home': { street: 'shangdi 9', city: 'Beijing', state: 'Beijing', zip_code: 100080} } WHERE first_name = 'Wu';
  5. cqlsh:test_keyspace> SELECT first_name, addresses FROM test_user WHERE first_name = 'Wu';
  6. first_name | addresses
  7. ------------+--------------------------------------------------------------------------------------
  8. Wu | {'home': {street: 'shangdi 9', city: 'Beijing', state: 'Beijing', zip_code: 100080}}
  9. (1 rows)