CREATE
CREATE 用于创建新的数据库或者表。
CREATE DATABASE
Syntax
创建新数据库:
CREATE DATABASE [IF NOT EXISTS] db_name [WITH <options>]
如果 db_name 数据库已经存在,CREATE 语句的行为如下:
- 不会创建新的数据库。
- 当 IF NOT EXISTS子句被指定时,不会返回错误。
- 否则,返回错误。
数据库也可以通过使用 WITH 关键字配置与 CREATE TABLE 语句类似的选项。表选项 中提供的所有选项也可以在此处使用。在创建表时,如果未提供相应的表选项,将使用在数据库级别配置的选项或者默认值。
示例
创建名为 test 的数据库:
CREATE DATABASE test;
Query OK, 1 row affected (0.05 sec)
使用 IF NOT EXISTS 再次创建:
CREATE DATABASE IF NOT EXISTS test;
创建一个具有 7 天 TTL(数据存活时间)的数据库,也就是该数据库中的所有表如果没有单独设置 TTL 选项,都将继承此选项值。
CREATE DATABASE test WITH (ttl='7d');
CREATE TABLE
Syntax
在 db 或当前数据库中创建新表:
CREATE TABLE [IF NOT EXISTS] [db.]table_name
(
    column1 type1 [NULL | NOT NULL] [DEFAULT expr1] [TIME INDEX] [PRIMARY KEY] [FULLTEXT | FULLTEXT WITH options] [COMMENT comment1],
    column2 type2 [NULL | NOT NULL] [DEFAULT expr2] [TIME INDEX] [PRIMARY KEY] [FULLTEXT | FULLTEXT WITH options] [COMMENT comment2],
    ...
    [TIME INDEX (column)],
    [PRIMARY KEY(column1, column2, ...)]
) ENGINE = engine WITH([TTL | storage | ...] = expr, ...)
[
  PARTITION ON COLUMNS(column1, column2, ...) (
    <PARTITION EXPR>,
    ...
  )
]
表 schema 由 ENGINE 之前的括号指定,表 schema 是列的定义和表的约束。
列定义包括列名称和数据类型,以及可选的 NULL、NOT NULL、DEFAULT 等。
表约束
表约束包括以下内容:
- TIME INDEX指定时间索引列,每个表只能有一个时间索引列。它表示 GreptimeDB 的 数据模型 中的- Timestamp类型。
- PRIMARY KEY指定表的主键列,它表示 GreptimeDB 的 数据模型 中的- Tag类型。它不能包含时间索引列,但是它总是隐式地将时间索引列添加到键的末尾。
- 其他列是 GreptimeDB 的 数据模型 中的 Field类型。
CREATE 语句中指定的 PRIMARY KEY 不是 传统关系数据库中的主键。
实际上,传统关系数据库中的 PRIMARY KEY 相当于 GreptimeDB 中的 PRIMARY KEY 和 TIME INDEX 的组合。
换句话说,PRIMARY KEY 和 TIME INDEX 一起构成了 GreptimeDB 中行的唯一标识符。
如果表已经存在且创建表时指定了 IF NOT EXISTS,CREATE 语句不会返回错误;否则返回错误。
表选项
用户可以使用 WITH 添加表选项。有效的选项包括以下内容:
| 选项 | 描述 | 值 | 
|---|---|---|
| ttl | 表数据的存储时间 | 字符串值,例如 '60m','1h'代表 1 小时,'14d'代表 14 天等。支持的时间单位有:s/m/h/d | 
| storage | 自定义表的存储引擎,存储引擎提供商的名字 | 字符串,类似 S3、Gcs等。 必须在[[storage.providers]]列表里配置, 参考 configuration。 | 
| compaction.type | Compaction 策略 | 字符串值. 只支持 twcs。你可以阅读这篇文章来了解twcscompaction 策略 | 
| compaction.twcs.max_active_window_files | 当前活跃时间窗口内的最大文件数 | 字符串值,如 '8'。只在 compaction.type为twcs时可用 | 
| compaction.twcs.max_inactive_window_files | 非活跃时间窗口内的最大文件数 | 字符串值,如 '1'。只在 compaction.type为twcs时可用 | 
| compaction.twcs.time_window | Compaction 时间窗口 | 字符串值,如 '1d' 表示 1 天。该表会根据时间戳将数据分区到不同的时间窗口中。只在 compaction.type为twcs时可用 | 
| memtable.type | memtable 的类型 | 字符串值,支持 time_series,partition_tree | 
| append_mode | 该表是否时 append-only 的 | 字符串值。默认值为 'false',根据 'merge_mode' 按主键和时间戳删除重复行。设置为 'true' 可以开启 append 模式和创建 append-only 表,保留所有重复的行 | 
| merge_mode | 合并重复行的策略 | 字符串值。只有当 append_mode为 'false' 时可用。默认值为last_row,保留相同主键和时间戳的最后一行。设置为last_non_null则保留相同主键和时间戳的最后一个非空字段。 | 
| comment | 表级注释 | 字符串值. | 
创建指定 TTL 的表
例如,创建一个存储数据 TTL(Time-To-Live) 为七天的表:
CREATE TABLE IF NOT EXISTS temperatures(
  ts TIMESTAMP TIME INDEX,
  temperature DOUBLE DEFAULT 10,
) with(ttl='7d');
创建自定义存储的表
或者创建一个表单独将数据存储在 Google Cloud Storage 服务上:
CREATE TABLE IF NOT EXISTS temperatures(
  ts TIMESTAMP TIME INDEX,
  temperature DOUBLE DEFAULT 10,
) with(ttl='7d', storage="Gcs");
创建自定义 compaction 参数的表
创建带自定义 twcs compaction 参数的表。这个表会尝试根据数据的时间戳将数据按 1 天的时间窗口分区。
- 它会在最新时间窗口内的文件超过 8 个时合并该窗口的文件
- 它会将非最新窗口内的文件合并为一个文件
CREATE TABLE IF NOT EXISTS temperatures(
  ts TIMESTAMP TIME INDEX,
  temperature DOUBLE DEFAULT 10,
)
with(
  'compaction.type'='twcs',
  'compaction.twcs.time_window'='1d',
  'compaction.twcs.max_active_window_files'='8',
  'compaction.twcs.max_inactive_window_files'='1',
);
创建 Append-Only 表
创建一个 append-only 表来关闭去重
CREATE TABLE IF NOT EXISTS temperatures(
  ts TIMESTAMP TIME INDEX,
  temperature DOUBLE DEFAULT 10,
) with('append_mode'='true');
创建带有 merge 模式的表
创建一个带有 last_row merge 模式的表,这是默认的 merge 模式。
create table if not exists metrics(
  host string,
  ts timestamp,
  cpu double,
  memory double,
  TIME INDEX (ts),
  PRIMARY KEY(host)
)
with('merge_mode'='last_row');
在 last_row 模式下,表会通过保留最新的行来合并具有相同主键和时间戳的行。
INSERT INTO metrics VALUES ('host1', 0, 0, NULL), ('host2', 1, NULL, 1);
INSERT INTO metrics VALUES ('host1', 0, NULL, 10), ('host2', 1, 11, NULL);
SELECT * from metrics ORDER BY host, ts;
+-------+-------------------------+------+--------+
| host  | ts                      | cpu  | memory |
+-------+-------------------------+------+--------+
| host1 | 1970-01-01T00:00:00     |      | 10.0   |
| host2 | 1970-01-01T00:00:00.001 | 11.0 |        |
+-------+-------------------------+------+--------+
创建带有 last_non_null merge 模式的表。
create table if not exists metrics(
  host string,
  ts timestamp,
  cpu double,
  memory double,
  TIME INDEX (ts),
  PRIMARY KEY(host)
)
with('merge_mode'='last_non_null');
在 last_non_null 模式下,表会通过保留每个字段的最新值来合并具有相同主键和时间戳的行。
INSERT INTO metrics VALUES ('host1', 0, 0, NULL), ('host2', 1, NULL, 1);
INSERT INTO metrics VALUES ('host1', 0, NULL, 10), ('host2', 1, 11, NULL);
SELECT * from metrics ORDER BY host, ts;
+-------+-------------------------+------+--------+
| host  | ts                      | cpu  | memory |
+-------+-------------------------+------+--------+
| host1 | 1970-01-01T00:00:00     | 0.0  | 10.0   |
| host2 | 1970-01-01T00:00:00.001 | 11.0 | 1.0    |
+-------+-------------------------+------+--------+
列选项
GreptimeDB 支持以下列选项:
| 选项 | 描述 | 
|---|---|
| NULL | 列值可以为 null | 
| NOT NULL | 列值不能为 null | 
| DEFAULT expr | 该列的默认值是 expr,其类型必须是该列的类型 | 
| COMMENT comment | 列注释,必须为字符串类型 | 
| FULLTEXT | 创建全文索引,可以加速全文搜索操作。仅适用于字符串类型列 | 
表约束 TIME INDEX 和 PRIMARY KEY 也可以通过列选项设置,但是它们只能在列定义中指定一次,在多个列选项中指定 PRIMARY KEY 会报错:
CREATE TABLE system_metrics (
    host STRING PRIMARY KEY,
    idc STRING PRIMARY KEY,
    cpu_util DOUBLE,
    memory_util DOUBLE,
    disk_util DOUBLE,
    ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
    TIME INDEX(ts)
);
会得到报错:
 Illegal primary keys definition: not allowed to inline multiple primary keys in columns options
正确的做法是使用 PRIMARY KEY() 来指定多个列作为主键:
CREATE TABLE system_metrics (
    host STRING,
    idc STRING,
    cpu_util DOUBLE,
    memory_util DOUBLE,
    disk_util DOUBLE,
    ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP() TIME INDEX,
    PRIMARY KEY(host, idc),
);
Query OK, 0 rows affected (0.01 sec)
FULLTEXT 列选项
FULLTEXT 用于创建全文索引,加速全文搜索操作。该选项只能应用于字符串类型的列。
使用 FULLTEXT WITH 可以指定以下选项:
- analyzer:设置全文索引的分析器语言,支持- English和- Chinese。
- case_sensitive:设置全文索引是否区分大小写,支持- true和- false。
如果不带 WITH 选项,FULLTEXT 将使用默认值:
- analyzer:默认- English
- case_sensitive:默认- false
例如,要创建一个带有全文索引的表,配置 log 列为全文索引,并指定分析器为 Chinese 且不区分大小写:
CREATE TABLE IF NOT EXISTS logs(
  host STRING PRIMARY KEY,
  log STRING FULLTEXT WITH(analyzer = 'Chinese', case_sensitive = 'false'),
  ts TIMESTAMP TIME INDEX
);
更多关于全文索引和全文搜索的使用,请参阅 日志查询文档。
Region 分区规则
请参考 分区 章节.
CREATE EXTERNAL TABLE
Syntax
在 db 或当前数据库中创建新的文件外部表:
CREATE EXTERNAL TABLE [IF NOT EXISTS] [db.]table_name
[
 (
    column1 type1 [NULL | NOT NULL] [DEFAULT expr1] [TIME INDEX] [PRIMARY KEY] [COMMENT comment1],
    column2 type2 [NULL | NOT NULL] [DEFAULT expr2] [TIME INDEX] [PRIMARY KEY] [COMMENT comment2],
    ...
    [TIME INDEX (column)],
    [PRIMARY KEY(column1, column2, ...)]
 )
] WITH (
  LOCATION = url,
  FORMAT =  { 'CSV' | 'JSON' | 'PARQUET' | 'ORC' }
  [,PATTERN = regex_pattern ]
  [,REGION = region ]
  [,ENDPOINT = uri ]
  [,ACCESS_KEY_ID = key_id ]
  [,SECRET_ACCESS_KEY = access_key ]
  [,ENABLE_VIRTUAL_HOST_STYLE = { TRUE | FALSE }]
  [,SESSION_TOKEN = token ]
  ...
)
表选项
| 选项 | 描述 | 是否必需 | 
|---|---|---|
| LOCATION | 外部表的位置,例如 s3://<bucket>[<path>],/<path>/[<filename>] | 是 | 
| FORMAT | 目标文件的格式,例如 JSON,CSV,Parquet, ORC | 是 | 
| PATTERN | 使用正则来匹配文件,例如 *_today.parquet | 可选 | 
S3
| 选项 | 描述 | 是否必需 | 
|---|---|---|
| REGION | AWS region 名称,例如 us-east-1 | 是 | 
| ENDPOINT | The bucket endpoint | 可选 | 
| ACCESS_KEY_ID | 用于连接 AWS S3 兼容对象存储的访问密钥 ID | 可选 | 
| SECRET_ACCESS_KEY | 用于连接 AWS S3 兼容对象存储的秘密访问密钥 | 可选 | 
| ENABLE_VIRTUAL_HOST_STYLE | 如果你想要使用 virtual hosting 来定位 bucket,将其设置为 true | 可选 | 
| SESSION_TOKEN | 用于连接 AWS S3 服务的临时凭证 | 可选 | 
时间索引列
在利用 CREATE EXTERNAL TABLE 语句创建外部表时,要求使用 TIME INDEX 约束来指定一个时间索引列。
示例
你可以在创建外部表时不带有列定义,列定义将会被自动推断:
CREATE EXTERNAL TABLE IF NOT EXISTS city WITH (location='/var/data/city.csv',format='csv');
在这个例子中,我们没有明确定义表的列,为满足外边表必须指定时间索引列的要求,CREATE EXTERNAL TABLE 语句会依据下述规则推断出时间索引列:
- 如果可以从文件元数据中推断出时间索引列,那么就用该列作为时间索引列。
- 如果存在名为 greptime_timestamp的列(该列的类型必须为TIMESTAMP,否则将抛出错误),那么就用该列作为时间索引列。
- 否则,将自动创建名为 greptime_timestamp的列作为时间索引列,并添加DEFAULT '1970-01-01 00:00:00+0000'约束。
或者带有列定义:
CREATE EXTERNAL TABLE city (
            host string,
            ts timestamp,
            cpu float64 default 0,
            memory float64,
            TIME INDEX (ts),
            PRIMARY KEY(host)
) WITH (location='/var/data/city.csv', format='csv');
在这个例子中,我们明确定义了 ts 列作为时间索引列。如果在文件中没有适合的时间索引列,你也可以创建一个占位符列,并添加 DEFAULT expr 约束。
创建 Flow
CREATE [OR REPLACE] FLOW [ IF NOT EXISTS ] <flow-name>
SINK TO <sink-table-name>
[ EXPIRE AFTER <expr> ]
[ COMMENT '<string>' ]
AS
<SQL>;
用于创建或更新 Flow 任务,请阅读Flow 管理文档。
创建 View
CREATE [OR REPLACE] VIEW [ IF NOT EXISTS ] <view-name>
AS select_statement
用于创建或更新视图,请阅读视图用户指南。