create table student (
s_id Int8,
s_name String,
s_birth DateTime,
s_sex Int8
)
engine = MergeTree()
order by s_id;
插入数据
ClickHouse 内部所有的数据操作都是面向 Block 数据块的,所以 INSERT 查询最终会将数据转换为Block 数据块。也正因如此, INSERT 语句在单个数据块的写入过程中是具有原子性的。在默认的情况下,每个数据块最多可以写入 1048576 行数据(由 max_insert_block_size 参数控制)。也就是说,如果一条 INSERT 语句写入的数据少于 max_insert_block_size 行, 那么这批数据的写入是具有原子性的,即要么全部成功,要么全部失败。 需要注意的是,只有在 ClickHouse 服务端处理数据的时候才具有这种原子写入的特性,例如使用 JDBC 或者 HTTP 接口时。因为 max_insert_block_size 参数在使用 CLI 命令行或者 INSERT SELECT 子句写入时是不生效的
# 1.values格式的常规导入,支持写入多条数据
insert into student values(xxx,xxx,xxx,xxx)[,(),()];
# 2.文件形式导入,需要指定数据库,不然是默认defalut数据库
cat data.csv | clickhouse-client -q 'insert into test1.student format CSV';
# 效果同上但是--format可以指定分隔符
clickhouse-client --format_csv_delimiter="," --query="INSERT INTO test1.student FORMAT CSV" < data.csv;
# 3.SELECT子句形式导入
insert into student select * from table_name;
修改和删除
# 删除
alter table student delete where s_id ='1';
# 修改
alter table student update s_name=asd where s_id=1;
查询
ClickHouse 基本上与标准 SQL 差别不大
- 支持子查询
- 支持 CTE(Common Table Expression 公用表表达式 with 子句)
- join时时注意右边小,左边大,因为ck会把右表完全缓存到内存中。容易出现oom,(可以用in代替join,只关联一张表情况下)
支持各种 JOIN, 但是 JOIN 操作无法使用缓存,所以即使是两次相同的 JOIN 语句,ClickHouse 也会视为两条新 SQL - 窗口函数(测试中…)
- 不支持自定义函数
- GROUP BY 操作增加了 with rollup\with cube\with total 用来计算小计和总计。
可以用in代替join
select a.* from hits_v1 a where a.CounterID in (select CounterID from visits_v1);
select a.* from hits_v1 a left join visits_v1 b on a.CounterID=b.CounterID;
分布式表使用 GLOBAL
两张分布式表上的 IN 和 JOIN 之前必须加上 GLOBAL 关键字, 右表只会在接收查询请求的那个节点查询一次,并将其分发到其他节点上。如果不加 GLOBAL 关键字的话,每个节点都会单独发起一次对右表的查询,而右表又是分布式表,就导致右表一共会被查询 N²次(N是该分布式表的分片数量),这就是查询放大,会带来很大开销。
select a.* from hits_v1 a GLOBAL left join visits_v1 b on a.CounterID=b.CounterID;