Cassandra 数据类型

Cassandra 数据类型

CQL支持丰富的数据类型,可以粗略的分为:原始类型、集合类型、用户定义的类型(user-defined types,)、元祖类型、Custom Types

原始类型

type constants supported description
ascii string ASCII character string
bigint integer 64-bit signed long
blob blob Arbitrary bytes (no validation)
boolean boolean Either true or false
counter integer Counter column (64-bit signed value). See Counters for details
date integer, string A date (with no corresponding time value). See Working with dates below for details
decimal integer, float Variable-precision decimal
double integer float 64-bit IEEE-754 floating point
float integer, float 32-bit IEEE-754 floating point
inet string An IP address, either IPv4 (4 bytes long) or IPv6 (16 bytes long). Note that there is no inet constant, IP address should be input as | strings
int integer 32-bit signed int
smallint integer 16-bit signed int
text string UTF8 encoded string
time integer, string A time (with no corresponding date value) with nanosecond precision. See Working with times below for details
timestamp integer, string A timestamp (date and time) with millisecond precision. See Working with timestamps below for details
timeuuid uuid Version 1 UUID, generally used as a “conflict-free” timestamp. Also see Timeuuid functions
tinyint integer 8-bit signed int
uuid uuid A UUID (of any version)
varchar string UTF8 encoded string
varint integer Arbitrary-precision integer

Counters

计数器类型用于定义计数器列。 计数器列是其值为64位有符号整数且支持2个操作的列:递增和递减。
Counters有下列重要的限制:
Note that the value of a counter cannot be set: a counter does not exist until first incremented/decremented, and that first increment/decrement is made as if the prior value was 0.

  • 不能作为PRIMARY KEY的一部分
  • 包含计数器的表只能包含计数器。 换句话说,PRIMARY KEY外部的表的所有列都是计数器类型,或者都不是计数器类型
  • 计数器列只支持过期操作
  • 支持删除计数器,但只能保证在您第一次删除计数器时工作。 换句话说,你不应该重新更新你已经删除的计数器
  • 计数器的更新不是幂等操作

timestamps

timestamp类型的值被编码为64位有符号整数,表示自称为时期的标准基准时间以来的毫秒数:1970年1月1日00:00: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'

上面的+0000是RFC 822 4位时区规范; +0000GMT。 如果需要,可以省略时区('2011-02-03 04:05:00'),
如果是这样,则日期将被解释为处于配置Cassandra节点的时区。
当然也可以省略时间('2011-02-03''2011-02-03 + 0000'),在这种情况下,时间将在指定或默认时区中默认为00:00:00
但是,如果只有日期部分相关,请考虑使用date类型。

date

date类型的值被编码为表示天数的32位无符号整数,其中“时期”在范围的中心(2 ^ 31)。 时代是1970年1月1日
对于时间戳,日期可以作为整数输入或使用日期字符串输入。 如果使用字符串输入,格式应为yyyy-mm-dd(例如“2011-02-03”)。

time

time类型的值被编码为表示自午夜以来纳秒数的64位有符号整数。
对于时间戳,时间可以作为整数输入或使用表示时间的字符串输入。 在后一种情况下,格式应为hh:mm:ss [.fffffffff]例如,以下是一段时间的有效输入:

'08:12:54'
'08:12:54.123'
'08:12:54.123456'
'08:12:54.123456789'

集合类型

CQL支持三中集合类型:Map, Set, List
集合用于存储/反规范化相对少量的数据。它们对于诸如“给定用户的电话号码”,“应用于电子邮件的标签”等的事物工作良好。
但是当期望项目增长无界(“由用户发送的所有消息”,“由传感器登记的事件“...),那么集合是不合适的.
需要注意的是:

  • 单个集合不在内部编制索引。 这意味着即使访问集合的单个元素,集合也必须被读取(并且读取一个元素不在内部被分页)。
  • 在对SetMap集合类型进行插入的时候,是不会进行read-before-write操作。但是对于列表操作会进行read-before-write操作,并且对于List操作,
    一些操作不是幂等的。

Map集合类型

Map是一组(排序)的键值对,其中键是唯一的,并且按其键对映射进行排序。 您可以定义和插入Map:

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

更新或者插入元素:

UPDATE users SET favs['author'] = 'Ed Poe' WHERE id = 'jsmith';
UPDATE users SET favs = favs + { 'movie' : 'Cassablanca', 'band' : 'ZZ Top' } WHERE id = 'jsmith';

删除一个或多个元素(如果元素不存在,则删除它不会有什么效果,但不会抛出错误):

ELETE favs['author'] FROM users WHERE id = 'jsmith';
UPDATE users SET favs = favs - { 'movie', 'band'} WHERE id = 'jsmith';

请注意,要删除Map中的多个元素,请从中删除一组键。
最后,对于INSERT和UPDATE都允许TTL,但是在这两种情况下,TTL集合仅适用于新插入/更新的元素。也就是说:

UPDATE users USING TTL 10 SET favs['color'] = 'green' WHERE id = 'jsmith';

TTL仅仅对{ 'color' : 'green' }记录有效果,其他记录不会受到影响

Set集合类型

Set是一系列有序的唯一元素的集合

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

Adding one or multiple elements (as this is a set, inserting an already existing element is a no-op):
插入一个或者多个元素(如果要插入的元素已经在这个集合中,则不会进行操作,这个操作是幂等的):

UPDATE images SET tags = tags + { 'gray', 'cuddly' } WHERE name = 'cat.jpg';

删除一个或者多个元素,如果被删除的元素不在集合中,那么不会进行操作,并且不会抛出异常

UPDATE images SET tags = tags - { 'cat' } WHERE name = 'cat.jpg';

最后和Map一模一样的,TTLs也仅仅仅适用于新插入/更新的元素。

Lists集合类型

列表具有限制和特定的性能注意事项,在使用它们之前应该考虑。 一般来说,如果你可以使用一个Set而不是List,那么你应该选择Set

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

往列表的后面和前面插入元素:

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

删除元素在列表中的位置。 这意味着列表具有用于该位置的预先存在的元素,或者将抛出该列表太小的错误。 此外,当操作从列表中移除元素时,列表大小将减少1.

DELETE scores[1] FROM plays WHERE id = '123-afde';

删除列表中所有出现的特定值(如果某个元素在列表中不会出现,它将被忽略并且不会抛出任何错误):

UPDATE plays SET scores = scores - [ 12, 21 ] WHERE id = '123-afde';

最后和Map一模一样的,TTLs也仅仅仅适用于新插入/更新的元素。

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

CQL支持用户自定义数据类型,一旦定义好以后,就可以使用类型的名称来使用它们了。

创建用户自定义类型

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

注意:

  • 尝试创建已存在的类型将导致错误,除非使用IF NOT EXISTS选项
  • 类型是绑定在创建他的keypsace中的,并在只能在这个keyspace中使用。

类型本质上绑定到创建它的键空间,并且只能在该键空间中使用。 在创建时,如果类型名称由键空间名称前缀,则在该键空间中创建。 否则,将在当前键空间中创建。

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: '...' } }
              }
          })

修改自定义类型

ALTER TYPE address ALTER zip TYPE bigint
ALTER TYPE address ADD country text
ALTER TYPE address RENAME zip TO zipcode

删除自定义类型

DROP TYPE [ IF EXISTS ] udt_name

元祖类型

CREATE TABLE durations (
    event text,
    duration tuple<int, text>,
)
INSERT INTO durations (event, duration) VALUES ('ev1', (3, 'hours'));

Custom Types

官方文档说Custom Types主要是用于先后兼容的,并不建议使用,所以就不提了。

Custom types exists mostly for backward compatiliby purposes and their usage is discouraged. Their usage is complex, not user friendly and the other provided types, particularly user-defined types, should almost always be enough.

参考资料

本文版权归作者所有,禁止一切形式的转载,复制等操作
赞赏

微信赞赏支付宝赞赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注