数据类型
基础类型
基础类型只有三种 数值、字符串、时间
数值
1.1 数值类型 int (用int8 int16 int32 int64 代表tinyint smallint int bigint) 分别占用 1 2 4 8字节,无符号整数加前缀U表示。
1.2 浮点数 float (float32 float64 分别占用4 8字节 有效精度分别为7 16位)
1.3 定点数 decimal (decimal32(S) decimal64(S) decimal128(S) 表示 decimal(1~9, S) decimal(10~18, S) decimal(19~38, S) )字符串
2.1 String
2.2 FixedString
2.3 UUID (8-4-4-4-12)时间
3.1 DateTime 精确到秒
3.2 DateTime64 精确到微秒
3.3 Date 精确到天
复合类型
复合类型有四种,分别是数组、元组、枚举、嵌套。
- 数组Array 书写方式array(T) 或者
[T]
- 元组Tuple 书写方式tuple(T) 或者 (T)
- 枚举Enum Key/Value形式 Enum8和Enum16分别表示(String:int)和(String:int16),枚举类型K V不能重复且不能为null,K可以为空字符串
- 嵌套Nested 每个字段的嵌套层级只支持一层 嵌套类型本质是一种多维数组的结构 嵌套表中的每个字段都是一个数组,且行与行之间长度无需对齐 但同一行数据内的每个数组字段的长度必须相等
特殊类型
- Nullable 尽量避免,会使查询和写入性能变慢
[column].bin -> [column].null.bin
- Domian 域名类型分为IPv4和IPv6两类
定义数据表
数据库
CREATE DATABASE IF NOT EXISTS db_name [ENGINE = engine]
数据库目前支持5种引擎
Ordinary 默认引擎
Dictionary 字典引擎,此类数据库会自动为所有数据字典创建他们的数据表
Memory 内存引擎,用于存放临时数据,此类数据库下的数据表只会停留在内存中,不会涉及任何磁盘操作,当服务重启后数据会被清掉
Lazy 日志引擎,此类数据库下只能使用Log系列的表引擎
MySQL MySQL引擎,此类数据库下会自动拉取远端MySQL中的数据,并为他们创建MySQL表引擎的数据表
SHOW DATABASES #查看当前的数据库列表
USE db_name #切换数据库
SHOW TABLES #查询可以查看当前数据库的数据表列表
DROP DATABASES [IF EXISTS] db_name #删除数据库
数据表
- 常规定义方式
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name (
name1 [type] [DEFAULT|MATERIALIZED|ALTAS expr],
name2 [type] [DEFAULT|MATERIALIZED|ALTAS expr], ...
) ENGINE = engine
- 复制其他表结构
CREATE TABLE [IF NOT EXISTS] [db_name1.]table_name AS [db_name2.]table_name2 [ENGINE = engine]
- 通过select子句的形式创建相应的表结构,同时还会将select子句查询的数据顺带写入
CREATE TABLE IF NOT EXISTS table_name_new ENGINE = engine AS SELECT * FROM table_name_origin
默认值表达式
支持三种默认值表达式 DEFAULT|MATERIALIZED|ALTAS,无论使用哪一种形式,表字段一旦被定义了默认值便不再强制要求定义数据类型。
临时表
CREATE TEMPORARY TABLE [IF NOT EXISTS] table_name (
name1 [type] [DEFAULT|MATERIALIZED|ALTAS expr],
name2 [type] [DEFAULT|MATERIALIZED|ALTAS expr], ...
)
相比普通表,临时表生命周期是会话绑定的,只支持Memory表引擎,会话结束表就会被销毁。
临时表不属于任何数据库。
临时表与普通表重名时,临时表的优先级是高于普通表的。
分区表
CREATE TABLE table_name (...) ENGINE=MergeTree() PARTITION BY ... ORDER BY ... #建表
SELECT table,partition,path from system.parts WHERE table='table_name' #查询数据表的分区状态
视图
- 普通视图
CREATE VIEW [IF NOT EXISTS] [db_name.]view_name AS SELECT ...
视图不会存储任何数据,它只是一层单纯的SELECT查询映射,对查询性能不会有任何增强。
- 物化视图
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE=engin] [POPULATE] AS SELECT ...
物化视图创建好后,如果源表被写入新数据,那么物化视图也会同步更新。POPULATE修饰符决定了物化视图的初始化策略,如果使用POPULATE修饰符,那么在创建视图的过程中,会连带将源表中已存在的数据一并导入,反正则没有数据。物化视图不支持同步删除,源表删除后物化视图数据仍会保留。使用SHOW TABLE
查看数据表列表时 .inner. 特殊前缀的表为物化视图,可使用DROP TABLE
删除。
数据表的基本操作
追加新字段
ALTER TABLE tb_name ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [AFTER name_after]
修改数据类型
ALTER TABLE tb_name MODIFY COLUMN [IF EXISTS] name [type] [default_expr]
修改备注
ALTER TABLE tb_name COMMENT COLUMN [IF EXISTS] name 'some comment'
删除已有字段
ALTER TABLE tb_name DROP COLUMN [IF EXISTS] name
移动数据表
RENAME TABLE [db1.]table1 TO [db2.]table2 ...
清空数据表
TRUNCAT TABLE [IF EXISTS] [db.]table
数据分区的基本操作
查询分区信息
SELECT partition_id,name,table,database FROM system.parts WHERE table='table_name'
删除指定分区
ALTER TABLE tb_name DROP PARTITION partition_expr
复制分区数据
ALTER TABLE tb_b REPLACE PARTITION partition_expr FROM table_a
前提:两张表需要拥有相同的分区键,表结构完全相同。
重置分区数据
ALTER TABLE tb_name CLEAR COLUMN column_name IN PARTITION partition_expr
卸载与装载分区
分区被卸载后物理数据并没有删除,是被转移到了当前表目录的detached子目录下。
ALTER TABLE tb_name DETACH PARTITION partition_expr #卸载
ALTER TABLE tb_name ATTACH PARTITION partition_expr #装载
备份与还原分区
FREEZE FETCH
分布式DDL
CREATE ALTER DROP RENAME TRUNCAT 都支持分布式执行。
CREATE TABLE tb ON CLUSTER cluster_name (...) ...
数据写入
INSERT INTO [db.]table_name [(c1,c2, ...)] VALUES (v1,v2, ...) #values格式插入
INSERT INTO [db.]table_name [(c1,c2, ...)] FORMAT format_name data_set #使用指定格式
INSERT INTO [db.]table_name [(c1,c2, ...)] SELECT ... #使用SELECT插入
数据删除与修改
DELETE UPDATE 是 Mutation语句的变种,它是一种很[重]的操作,适用于批量数据的修改和删除,一旦提交就会立刻对现有数据产生影响且不可回滚,它是一个异步的后台过程,语句提交后就会立刻返回,所以这并不代表具体逻辑已经执行完毕,具体进度要通过system.mutations
系统表来查询。
ALTER TABLE [db.]tb DELETE WHERE filter_expr #删除
ALTER TABLE [db.]tb UPDATE column1=expr1 [, ...] WHERE filter_expr #更新