1. create table student (
  2. s_id Int8,
  3. s_name String,
  4. s_birth DateTime,
  5. s_sex Int8
  6. )
  7. engine = MergeTree()
  8. 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. # 1.values格式的常规导入,支持写入多条数据
  2. insert into student values(xxx,xxx,xxx,xxx)[,(),()];
  3. # 2.文件形式导入,需要指定数据库,不然是默认defalut数据库
  4. cat data.csv | clickhouse-client -q 'insert into test1.student format CSV';
  5. # 效果同上但是--format可以指定分隔符
  6. clickhouse-client --format_csv_delimiter="," --query="INSERT INTO test1.student FORMAT CSV" < data.csv;
  7. # 3.SELECT子句形式导入
  8. insert into student select * from table_name;

修改和删除

  1. # 删除
  2. alter table student delete where s_id ='1';
  3. # 修改
  4. 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

  1. select a.* from hits_v1 a where a.CounterID in (select CounterID from visits_v1);
  2. select a.* from hits_v1 a left join visits_v1 b on a.CounterID=b.CounterID;

分布式表使用 GLOBAL

两张分布式表上的 IN 和 JOIN 之前必须加上 GLOBAL 关键字, 右表只会在接收查询请求的那个节点查询一次,并将其分发到其他节点上。如果不加 GLOBAL 关键字的话,每个节点都会单独发起一次对右表的查询,而右表又是分布式表,就导致右表一共会被查询 N²次(N是该分布式表的分片数量),这就是查询放大,会带来很大开销。

  1. select a.* from hits_v1 a GLOBAL left join visits_v1 b on a.CounterID=b.CounterID;