Cassandra 数据定义

Cassandra 数据定义

CQL在表中存储数据,它的schema定义表中所述数据的布局,并且这些表在键空间中分组。 键空间定义了一些适用于其包含的所有表的选项,其中最显着的是键空间使用的复制策略。 通常建议一个应用程序一个keyspace,许多集群可以仅定义一个键空间。
本节介绍用于创建,修改和删除这些键空间和表的语句。
键空间和表名都应该只包含字母数字字符,不能为空,并且大小限制为48个字符(该限制主要用于避免文件名(可能包括键空间和表名)超过某个文件系统的限制)。 默认情况下,键空间和表名称不区分大小写(myTable等效于mytable),但可以通过使用双引号(“myTable”不同于mytable)强制区分大小写。
此外,表始终是键空间的一部分,并且表名可以由其所属的键空间完全限定。 如果不是完全限定的,则假定表在当前键空间中。

CREATE KEYSPACE

语法格式为:

CREATE KEYSPACE [ IF NOT EXISTS ] keyspace_name WITH options

举两个例子:

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;

参数replication是强制性的,用于定义复制策略和用于键空间的选项。有SimpleStrategyNetworkTopologyStrategy两个可供选择的值。
'SimpleStrategy':一个简单的策略,定义整个集群的复制因子。支持的唯一子选项是’replication_factor’以定义该复制因子并且是必需的。
'NetworkTopologyStrategy':允许为每个数据中心独立设置复制因素的复制策略。 其余的子选项是键值对,其中键是数据中心名称,其值是关联的复制因子
参数durable_writes是可选的,用于定义是否使用提交日志来更新此键空间
尝试创建已存在的键空间将返回错误,除非使用IF NOT EXISTS选项。

USE KEYSPACE

可以使用

use keyspaceName

来切换keypsace,相当于mysql中的use xxxDatabase一样。

ALTER KEYSPACE

修改keypsace的语法为:

ALTER KEYSPACE keyspace_name WITH options

比如:

ALTER KEYSPACE Excelsior
          WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 4};

DROP KEYSPACE

语法为:

DROP KEYSPACE [ IF EXISTS ] keyspace_name
DROP KEYSPACE Excelsior;

删除键空间导致立即不可逆地删除该键空间,包括其中的所有表,UTD和函数以及这些表中包含的所有数据。

CREATE TABLE

CQL表具有名称,并由一组行组成。创建表等于定义将组成行的列,哪些列构成主键,以及表的可选选项。尝试创建已存在的表将返回错误,除非使用IF NOT EXISTS指令

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 loads (
    machine inet,
    cpu int,
    mtime timeuuid,
    load float,
    PRIMARY KEY ((machine, cpu), mtime)
) WITH CLUSTERING ORDER BY (mtime DESC);

Column definitions

CQL表中的每一行都有一组在创建表时定义的预定义列(或稍后使用alter语句添加)。
column_definition主要由定义的列的名称及其类型组成,它限制了该列接受哪些值。此外,列定义可以具有以下修饰符:

  • STATIC i它声明该列为 static column.
  • PRIMARY KEY 它声明该列是表的主键的唯一组件

某些列可以在表定义中声明为STATIC。属于static column将由属于同一分区(具有相同的分区键)的所有行“共享”。例如:

CREATE TABLE t (
    pk int,
    t int,
    v text,
    s text static,
    PRIMARY KEY (pk, t)
);
INSERT INTO t (pk, t, v, s) VALUES (0, 0, 'val0', 'static0');
INSERT INTO t (pk, t, v, s) VALUES (0, 1, 'val1', 'static1');
SELECT * FROM t;
   pk | t | v      | s
  ----+---+--------+-----------
   0  | 0 | 'val0' | 'static1'
   0  | 1 | 'val1' | 'static1'

正如你说看到的,对于分区中的行(这个例子中的分区键是pk, 两行都在同一分区中)的s值是相同的(static1):第二插入覆盖了s的值 。
使用静态列的限制如下:
– 具有COMPACT STORAGE选项的表不能使用它们
– 没有聚簇列的表不能具有静态列(在没有聚簇列的表中,每个分区只有一行,因此每列都是固有的)。
– 只有非PRIMARY KEY列可以是静态的。

PRIMARY KEY

在一个表中,一行由其PRIMARY KEY唯一标识,因此所有表必须定义一个PRIMARY KEY(只有一个)。 PRIMARY KEY定义由表中定义的一个或多个列组成。 在语法上,主键定义了关键字PRIMARY KEY,后跟逗号分隔的在括号中组成它的列名称的列表,但是如果主键只有一列,则可以通过PRIMARY KEY关键字替代该列定义。 主键定义中的列的顺序很重要。
CQL主键由2部分组成:

  • 分区键(partition key )部分:它是主键定义的第一个组件。 它可以是单列,或使用额外的括号,可以是多列。 一个表总是至少有一个分区键,最小的可能表定义是:
    CREATE TABLE t (k text PRIMARY KEY);
  • 聚类列(clustering columns)。这些是主键定义的第一个组件之后的列,这些列的顺序定义了聚类顺序。

THE PRIMARY KEY

主键定义的一些示例是:
PRIMARY KEY (a): a 是分区键,并且没有聚类列
PRIMARY KEY (a, b, c) : 阿是分区键,b和c是聚类列
PRIMARY KEY ((a, b), c) : a和b组成了分区键,叫做composite partition key, c 是聚类列
在表中,CQL定义了分区的概念。 分区只是它们的分区键共享相同值的一组行。 注意,如果分区键由多个列组成,只有它们对所有这些分区键列具有相同的值则行属于同一分区。 例如,给定下面的表定义和内容:

CREATE TABLE t (
    a int,
    b int,
    c int,
    d int,
    PRIMARY KEY ((a, b), c, d)
);
SELECT * FROM t;
   a | b | c | d
  ---+---+---+---
   0 | 0 | 0 | 0    // row 1
   0 | 0 | 1 | 1    // row 2
   0 | 1 | 2 | 2    // row 3
   0 | 1 | 3 | 3    // row 4
   1 | 1 | 4 | 4    // row 5

row1和row2是在同一个分区中,row3和row4也在相同的另外一个分区中,row5单独在一个分区中
注意,表始终具有分区键,并且如果表没有聚集列,则该表的每个分区仅由单个行构成(因为主键唯一地标识行,并且主键等于分区键)。
分区的最重要的属性是属于同一分区的所有行保证被存储在同一副本节点集合上。换句话说,表的分区键定义哪些行将在集群中一起本地化,因此明智地选择分区键是非常重要的,以便需要一起提取的行在同一个分区中(因为一起查询这些行需要联系最少的节点)。
但请注意,这种保证有一个反面:因为所有共享一个分区键的行都保证存储在同一副本节点集合上,分组太多数据的分区键可以创建一个热点。
分区的另一个有用的属性是,当写入数据时,属于单个分区的所有更新是原子地并且单独地完成的,而跨分区不是这样。
正确选择表的分区键和聚簇列可能是Cassandra中数据建模的最重要的方面之一,它在很大程度上影响可以执行的查询以及它们的效率。

The clustering columns

表的聚簇列定义了该表的分区的聚类顺序。对于给定的分区,通过该聚类顺序,所有行在Cassandra内是物理排序的。例如,给定:

CREATE TABLE t (
    a int,
    b int,
    c int,
    PRIMARY KEY (a, c, d)
);
SELECT * FROM t;
   a | b | c
  ---+---+---
   0 | 0 | 4     // row 1
   0 | 1 | 9     // row 2
   0 | 2 | 2     // row 3
   0 | 3 | 3     // row 4

那么所有行(它们都属于同一分区)全部以它们的b列的值的顺序(它们在上面显示的顺序)在内部存储。 因此,表的分区键允许对同一副本集上的行进行分组时,聚簇列会控制这些行如何存储在副本上。 该排序允许检索分区内的行范围(例如,在上面的示例中,SELECT * FROM t WHERE a = 0 AND b> 1 and b <= 3)非常有效。

Table options

CQL表有许多可以在创建时设置的选项。这些选项在WITH关键字后指定。在这些选项中,两个重要的选项在创建后不能更改,并影响可以对表执行哪些查询:COMPACT STORAGE选项和CLUSTERING ORDER选项。

Compact tables

Since Cassandra 3.0, compact tables have the exact same layout internally than non compact ones (for the same schema obviously), and declaring a table compact only creates artificial limitations on the table definition and usage that are necessary to ensure backward compatibility with the deprecated Thrift API. And as COMPACT STORAGE cannot, as of Cassandra 4.0, be removed, it is strongly discouraged to create new table with the COMPACT STORAGE option.

紧凑表是使用COMPACT STORAGE选项定义的表, 并且

  • 紧凑表不能使用集合或静态列。
  • 如果紧凑表具有至少一个聚类列,则它必须在主键之外具有正好一个列。这意味着您不能在创建后特别添加或删除列。
  • 紧凑表在其可以创建的索引中受到限制,并且不能在其上创建实体化视图。(a compact table is limited in the indexes it can create, and no materialized view can be created on it.)

Reversing the clustering order

表的聚类顺序由该表的聚类列定义。默认情况下,该排序基于这些聚类顺序的自然顺序,但是CLUSTERING ORDER允许更改该聚类顺序以对某些(可能所有)列使用反向自然顺序。
CLUSTERING ORDER选项采用聚类列的逗号分隔列表,每个列都有一个ASC(用于上升,例如自然顺序)或DESC(对于后代,例如反向自然顺序)。特别要注意的是,默认(如果不使用CLUSTERING ORDER选项)严格等同于使用ASC修改器在所有聚簇列中使用该选项。

ALTER TABLE

修改表的语法为:

alter_table_statement   ::=  ALTER TABLE table_name alter_table_instruction
alter_table_instruction ::=  ALTER column_name TYPE cql_type
                             | ADD column_name cql_type ( ',' column_name cql_type )*
                             | DROP column_name ( column_name )*
                             | WITH options

例如

ALTER TABLE addamsFamily ALTER lastKnownLocation TYPE uuid;
ALTER TABLE addamsFamily ADD gravesite varchar;
ALTER TABLE addamsFamily
       WITH comment = 'A most excellent and useful table'
       AND read_repair_chance = 0.2;

注意:

  • 更改表中某一列的类型,列的类型不能任意改变。 需要保证兼容性
  • 向表中添加新列(通过ADD指令)。 注意,表的主键不能被改变,因此新添加的列将不再是主键的一部分。 还要注意,紧凑表(compact tables)对列添加有限制。
  • 从表中删除列。 这会删除列及其所有内容,但请注意,列会立即不可用,但是其内容只会在压缩期间被懒惰删除。
  • 更改一些表选项(通过WITH指令)。 支持的选项与创建表时(在COMPACT STORAGE和CLUSTERING ORDER`之外,在创建后无法更改)相同。 请注意,设置任何压缩子选项都会删除所有以前的压缩选项,因此如果要保留它们,则需要重新指定所有子选项。 相同的注释适用于压缩子选项集。
  • 一旦删除列,则允许重新添加与删除的列名称相同的列,除非删除列的类型是(非冻结)列(由于内部技术限制)。

DROP TABLE

删除表的语法为:

DROP TABLE [ IF EXISTS ] table_name

TRUNCATE

truncate的语法为:

TRUNCATE [ TABLE ] table_name

truncate会永久删除表中的所有现有数据,但不删除表本身。

参考资料

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

微信赞赏支付宝赞赏

发表评论

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