參考官網:https://clickhouse.tech/docs/zh/sql-reference/statements/create/,更多詳細文檔可以參考官網,強烈推薦。
1、Clickhouse創建數據庫,CREATE DATABASE,該查詢用於根據指定名稱創建數據庫。
1 CREATE DATABASE [IF NOT EXISTS] db_name
數據庫其實只是用於存放表的一個目錄。如果查詢中存在IF NOT EXISTS,則當數據庫已經存在時,該查詢不會返回任何錯誤。
2、Clickhouse數據表的定義語法,是在標准SQL的基礎之上建立的。Clickhouse目前提供了三種最基本的建表方法,但是注意的是在Clickhouse中建表一定要指定表的引擎,在指定數據表字段之后,最后一定要指定數據表的引擎。CREATE TABLE的三種方式,對於CREATE TABLE,存在以下幾種方式。
2.1、第一種方式,直接指定字段名稱、字段類型,是否有默認值,中文備注名稱等信息。
1 CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] 2 ( 3 name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1], 4 name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2], 5 ... 6 ) ENGINE = engine
使用案例,如下所示:
1 master :) 2 master :) CREATE TABLE tb_table1 3 :-] ( 4 :-] `id` UInt8, 5 :-] `name` String 6 :-] )ENGINE = TinyLog; 7 8 CREATE TABLE tb_table1 9 ( 10 `id` UInt8, 11 `name` String 12 ) 13 ENGINE = TinyLog 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.038 sec. 18 19 master :) insert into tb_table1 values(1, '張三三'); 20 21 INSERT INTO tb_table1 VALUES 22 23 Ok. 24 25 1 rows in set. Elapsed: 0.036 sec. 26 27 master :) select * from tb_table1; 28 29 SELECT * 30 FROM tb_table1 31 32 ┌─id─┬─name───┐ 33 │ 1 │ 張三三 │ 34 └────┴────────┘ 35 36 1 rows in set. Elapsed: 0.014 sec. 37 38 master :)
注意,如果創建數據表沒有指定數據庫,將在default默認的數據庫下創建一張數據表。注意末尾的engine參數,它被用於指定數據表的引擎,表引擎決定了數據表的特性,也決定了數據將會被如何存儲和加載。
2.2、第二種方式,這種方式其實就是復制已經存在的一張表結構,可用於數據的備份,可用於多個數據庫之間復制表機構。
創建一個與db2.name2具有相同結構的表,同時你可以對其指定不同的表引擎聲明。如果沒有表引擎聲明,則創建的表將與db2.name2使用相同的表引擎。
1 CREATE TABLE [IF NOT EXISTS] [db.]table_name AS [db2.]name2 [ENGINE = engine]
使用案例,如下所示:
1 master :) create database gab_db2; 2 3 CREATE DATABASE gab_db2 4 5 Ok. 6 7 0 rows in set. Elapsed: 0.009 sec. 8 9 master :) use gab_db2; 10 11 USE gab_db2 12 13 Ok. 14 15 0 rows in set. Elapsed: 0.051 sec. 16 17 master :) show tables; 18 19 SHOW TABLES 20 21 Ok. 22 23 0 rows in set. Elapsed: 0.010 sec. 24 25 master :) show tables; 26 27 SHOW TABLES 28 29 Ok. 30 31 0 rows in set. Elapsed: 0.011 sec. 32 33 master :) create table if not exists gab_db2.tb_name as gab_db.tb_name; 34 35 CREATE TABLE IF NOT EXISTS gab_db2.tb_name AS gab_db.tb_name 36 37 Ok. 38 39 0 rows in set. Elapsed: 0.014 sec. 40 41 master :) show tables; 42 43 SHOW TABLES 44 45 ┌─name────┐ 46 │ tb_name │ 47 └─────────┘ 48 49 1 rows in set. Elapsed: 0.010 sec. 50 51 master :)
2.3、第三種方式,通過select查詢的方式來創建表,同時也會導入查詢的結果數據。
1 CREATE TABLE [IF NOT EXISTS] [db.]table_name ENGINE = engine AS SELECT ...
使用案例,如下所示:
1 master :) create table tb_name2 engine=TinyLog as select * from gab_db.tb_name; 2 3 CREATE TABLE tb_name2 4 ENGINE = TinyLog AS 5 SELECT * 6 FROM gab_db.tb_name 7 8 Ok. 9 10 0 rows in set. Elapsed: 0.021 sec. 11 master :) show tables; 12 13 SHOW TABLES 14 15 ┌─name─────┐ 16 │ tb_name │ 17 │ tb_name2 │ 18 └──────────┘ 19 20 2 rows in set. Elapsed: 0.010 sec. 21 22 master :) select * from tb_name2; 23 24 SELECT * 25 FROM tb_name2 26 27 ┌─id─┬─age─┬───birthday─┬──────────updateTime─┐ 28 │ 1 │ 22 │ 1994-05-16 │ 2021-02-20 14:21:30 │ 29 │ 2 │ 24 │ 1994-05-17 │ 2021-02-20 14:21:30 │ 30 └────┴─────┴────────────┴─────────────────────┘ 31 32 2 rows in set. Elapsed: 0.010 sec. 33 34 master :)
3、Clickhouse刪除表的語法結構。也可以通過此語法刪除普通視圖和物化視圖。
1 DROP TABLE [IF EXISTS] [db_name.]table_name;
使用案例,如下所示:
1 master :) 2 master :) show tables; 3 4 SHOW TABLES 5 6 ┌─name─────┐ 7 │ tb_name │ 8 │ tb_name2 │ 9 └──────────┘ 10 11 2 rows in set. Elapsed: 0.008 sec. 12 13 master :) drop table tb_name2; 14 15 DROP TABLE tb_name2 16 17 Ok. 18 19 0 rows in set. Elapsed: 0.005 sec. 20 21 master :) show tables; 22 23 SHOW TABLES 24 25 ┌─name────┐ 26 │ tb_name │ 27 └─────────┘ 28 29 1 rows in set. Elapsed: 0.006 sec. 30 31 master :)
4、臨時表,Clickhouse也有臨時表的概念,創建臨時表的方法是在普通表的基礎上添加temporary關鍵字,相比普通表而言,臨時表有如下兩點特殊之處。
1)、它的生命周期是會話綁定的,所以它只支持Memory表引擎,如果會話結束,數據表就會被銷毀。
2)、臨時表不屬於任何數據庫,所以在它的建表語句中,既沒有數據庫參數也沒有數據表引擎參數。
臨時表的優先級大於系統中的表,一般用於集群之間的數據傳播的載體。臨時表不屬於任何數據庫。會話斷開以后表會自動刪除,不會持久化。如果本地表和臨時表沖突,臨時表優先。可以用於數據庫之間的數據遷移。
5、ClickHouse支持臨時表,其具有以下特征:
1)、當回話結束時,臨時表將隨會話一起消失,這包含鏈接中斷。
2)、臨時表僅能夠使用Memory表引擎。
3)、無法為臨時表指定數據庫。它是在數據庫之外創建的。
4)、如果臨時表與另一個表名稱相同,那么當在查詢時沒有顯示的指定db的情況下,將優先使用臨時表。
5)、對於分布式處理,查詢中使用的臨時表將被傳遞到遠程服務器。
可以使用下面的語法創建一個臨時表:
1 CREATE TEMPORARY TABLE [IF NOT EXISTS] table_name [ON CLUSTER cluster] 2 ( 3 name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1], 4 name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2], 5 ... 6 )
大多數情況下,臨時表不是手動創建的,只有在分布式查詢處理中使用(GLOBAL) IN時為外部數據創建。
1 master :) 2 master :) CREATE temporary TABLE tb_table1 3 :-] ( 4 :-] `id` UInt8, 5 :-] `name` String 6 :-] ); 7 8 CREATE TEMPORARY TABLE tb_table1 9 ( 10 `id` UInt8, 11 `name` String 12 ) 13 14 Ok. 15 16 0 rows in set. Elapsed: 0.003 sec. 17 18 master :) insert into tb_table1 values(1, '張三三'); 19 20 INSERT INTO tb_table1 VALUES 21 22 Ok. 23 24 1 rows in set. Elapsed: 0.004 sec. 25 26 master :) select * from tb_table1; 27 28 SELECT * 29 FROM tb_table1 30 31 ┌─id─┬─name───┐ 32 │ 1 │ 張三三 │ 33 └────┴────────┘ 34 35 1 rows in set. Elapsed: 0.007 sec. 36 37 master :)
臨時表不需要指定數據表的引擎,我們可以理解成臨時表會將當前數據庫中已經存在的同名表覆蓋隱藏,當出現操作的時候,如果有臨時表,那么會操作臨時表。
6、Clickhouse擁有普通視圖和物化兩種視圖。其中物化視圖擁有獨立的存儲,而普通視圖只是一層簡單的查詢代理。
6.1、普通視圖不會存儲任何數據,它只是一層單純的select查詢映射,起着簡化查詢,明晰語義的作用,對查詢性能不會有任何增強。
1 CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
創建一個視圖。它存在兩種可選擇的類型:普通視圖與物化視圖。普通視圖不存儲任何數據,只是執行從另一個表中的讀取。換句話說,普通視圖只是保存了視圖的查詢,當從視圖中查詢時,此查詢被作為子查詢用於替換FROM子句。
使用案例,如下所示:
1 master :) show tables; 2 3 SHOW TABLES 4 5 ┌─name───────┐ 6 │ tb_array │ 7 │ tb_enum │ 8 │ tb_name │ 9 │ tb_tinyLog │ 10 │ tb_tuple │ 11 │ user_db │ 12 └────────────┘ 13 14 6 rows in set. Elapsed: 0.017 sec. 15 16 master :) select * from tb_name; 17 18 SELECT * 19 FROM tb_name 20 21 ┌─id─┬─age─┬───birthday─┬──────────updateTime─┐ 22 │ 1 │ 22 │ 1994-05-16 │ 2021-02-20 14:21:30 │ 23 │ 2 │ 24 │ 1994-05-17 │ 2021-02-20 14:21:30 │ 24 └────┴─────┴────────────┴─────────────────────┘ 25 26 2 rows in set. Elapsed: 0.006 sec. 27 28 master :) CREATE VIEW view_name AS SELECT * from tb_name; 29 30 CREATE VIEW view_name AS 31 SELECT * 32 FROM tb_name 33 34 Ok. 35 36 0 rows in set. Elapsed: 0.009 sec. 37 38 master :) select * from view_name; 39 40 SELECT * 41 FROM view_name 42 43 ┌─id─┬─age─┬───birthday─┬──────────updateTime─┐ 44 │ 1 │ 22 │ 1994-05-16 │ 2021-02-20 14:21:30 │ 45 │ 2 │ 24 │ 1994-05-17 │ 2021-02-20 14:21:30 │ 46 └────┴─────┴────────────┴─────────────────────┘ 47 48 2 rows in set. Elapsed: 0.011 sec. 49 50 master :)
6.2、物化視圖存儲的數據是由相應的SELECT查詢轉換得來的。物化視圖是特殊的表,有數據表結構,有數據表引擎,可以將數據持久化。
在創建物化視圖時,你還必須指定表的引擎,將會使用這個表引擎存儲數據。目前物化視圖的工作原理:當將數據寫入到物化視圖中SELECT子句所指定的表時,插入的數據會通過SELECT子句查詢進行轉換並將最終結果插入到視圖中。
1 master :) 2 master :) show tables; 3 4 SHOW TABLES 5 6 ┌─name───────┐ 7 │ tb_array │ 8 │ tb_enum │ 9 │ tb_name │ 10 │ tb_tinyLog │ 11 │ tb_tuple │ 12 │ user_db │ 13 │ view_name │ 14 └────────────┘ 15 16 7 rows in set. Elapsed: 0.007 sec. 17 18 master :) create materialized view m_name_view engine=Log populate as select * from tb_name; 19 20 CREATE MATERIALIZED VIEW m_name_view 21 ENGINE = Log POPULATE AS 22 SELECT * 23 FROM tb_name 24 25 Ok. 26 27 0 rows in set. Elapsed: 0.011 sec. 28 29 master :) select * from m_name_view; 30 31 SELECT * 32 FROM m_name_view 33 34 ┌─id─┬─age─┬───birthday─┬──────────updateTime─┐ 35 │ 1 │ 22 │ 1994-05-16 │ 2021-02-20 14:21:30 │ 36 │ 2 │ 24 │ 1994-05-17 │ 2021-02-20 14:21:30 │ 37 └────┴─────┴────────────┴─────────────────────┘ 38 39 2 rows in set. Elapsed: 0.007 sec. 40 41 master :)
如果創建物化視圖時指定了POPULATE子句,則在創建時將該表的數據插入到物化視圖中。就像使用CREATE TABLE ... AS SELECT ...一樣。否則,物化視圖只會包含在物化視圖創建后的新寫入的數據。我們不推薦使用POPULATE,因為在視圖創建期間寫入的數據將不會寫入其中。
7、Clickhouse的分區表,數據分區(partition)和數據分片(shard)是完全不同的兩個概念。數據分區是針對本地數據而言的,是數據的一種縱向切分,而數據分片是數據的一種橫向切分。
數據分區對於一款OLAP數據庫而言意義非凡,借助數據分區,在后續的查詢過程中能夠跳過不必要的數據目錄,從而提升查詢的性能。合理利用分區特性,還可以變相實現數據的更新操作,因為數據分區支持刪除、替換和重置操作。假設數據表按照月份分區,那么數據就可以按照月份的粒度被替換更新。分區雖好,但不是所有的表引擎都可以使用這項特性,目前只有合並樹MergeTree家族系統的表引擎才支持數據分區。
1 master :) 2 master :) CREATE TABLE tb_partition 3 :-] ( 4 :-] `pid` UInt8, 5 :-] `name` String, 6 :-] `ctime` DateTime, 7 :-] `money` Float64 8 :-] )engine=MergeTree() 9 :-] partition by toYYYYMM(ctime) 10 :-] ORDER BY pid; 11 12 CREATE TABLE tb_partition 13 ( 14 `pid` UInt8, 15 `name` String, 16 `ctime` DateTime, 17 `money` Float64 18 ) 19 ENGINE = MergeTree() 20 PARTITION BY toYYYYMM(ctime) 21 ORDER BY pid 22 23 Ok. 24 25 0 rows in set. Elapsed: 0.010 sec. 26 27 master :) insert into tb_partition values(1, '張三三', '2021-02-22 12:20:20', '120000'); 28 29 INSERT INTO tb_partition VALUES 30 31 Ok. 32 33 1 rows in set. Elapsed: 0.008 sec. 34 35 master :) select * from tb_partition; 36 37 SELECT * 38 FROM tb_partition 39 40 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 41 │ 1 │ 張三三 │ 2021-02-22 12:20:20 │ 120000 │ 42 └─────┴────────┴─────────────────────┴────────┘ 43 44 1 rows in set. Elapsed: 0.017 sec. 45 46 master :) desc tb_partition; 47 48 DESCRIBE TABLE tb_partition 49 50 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 51 │ pid │ UInt8 │ │ │ │ │ │ 52 │ name │ String │ │ │ │ │ │ 53 │ ctime │ DateTime │ │ │ │ │ │ 54 │ money │ Float64 │ │ │ │ │ │ 55 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 56 57 4 rows in set. Elapsed: 0.012 sec. 58 59 master :) insert into tb_partition values(1, '張三三', '2021-01-22 12:20:20', '120000'); 60 61 INSERT INTO tb_partition VALUES 62 63 Ok. 64 65 1 rows in set. Elapsed: 0.008 sec. 66 67 master :) select * from tb_partition; 68 69 SELECT * 70 FROM tb_partition 71 72 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 73 │ 1 │ 張三三 │ 2021-02-22 12:20:20 │ 120000 │ 74 └─────┴────────┴─────────────────────┴────────┘ 75 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 76 │ 1 │ 張三三 │ 2021-01-22 12:20:20 │ 120000 │ 77 └─────┴────────┴─────────────────────┴────────┘ 78 79 2 rows in set. Elapsed: 0.012 sec. 80 81 master :)
可以使用分區合並命令:optimize table 數據表名稱,將相同分區的數據進行分區合並,如下所示:
1 master :) select * from tb_partition; 2 3 SELECT * 4 FROM tb_partition 5 6 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 7 │ 1 │ 張三三 │ 2021-02-22 12:20:20 │ 120000 │ 8 └─────┴────────┴─────────────────────┴────────┘ 9 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 10 │ 1 │ 張三三 │ 2021-01-22 12:20:20 │ 120000 │ 11 └─────┴────────┴─────────────────────┴────────┘ 12 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 13 │ 1 │ 張三三 │ 2021-02-24 12:20:20 │ 120000 │ 14 └─────┴────────┴─────────────────────┴────────┘ 15 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 16 │ 1 │ 張三三 │ 2021-01-23 12:20:20 │ 120000 │ 17 └─────┴────────┴─────────────────────┴────────┘ 18 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 19 │ 1 │ 張三三 │ 2021-01-24 12:20:20 │ 120000 │ 20 └─────┴────────┴─────────────────────┴────────┘ 21 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 22 │ 1 │ 張三三 │ 2021-03-24 12:20:20 │ 120000 │ 23 └─────┴────────┴─────────────────────┴────────┘ 24 25 6 rows in set. Elapsed: 0.017 sec. 26 27 master :) 28 master :) 29 master :) optimize table tb_partition; 30 31 OPTIMIZE TABLE tb_partition 32 33 Ok. 34 35 0 rows in set. Elapsed: 0.006 sec. 36 37 master :) select * from tb_partition; 38 39 SELECT * 40 FROM tb_partition 41 42 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 43 │ 1 │ 張三三 │ 2021-02-24 12:20:20 │ 120000 │ 44 └─────┴────────┴─────────────────────┴────────┘ 45 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 46 │ 1 │ 張三三 │ 2021-03-24 12:20:20 │ 120000 │ 47 └─────┴────────┴─────────────────────┴────────┘ 48 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 49 │ 1 │ 張三三 │ 2021-01-22 12:20:20 │ 120000 │ 50 │ 1 │ 張三三 │ 2021-01-23 12:20:20 │ 120000 │ 51 │ 1 │ 張三三 │ 2021-01-24 12:20:20 │ 120000 │ 52 └─────┴────────┴─────────────────────┴────────┘ 53 ┌─pid─┬─name───┬───────────────ctime─┬──money─┐ 54 │ 1 │ 張三三 │ 2021-02-22 12:20:20 │ 120000 │ 55 └─────┴────────┴─────────────────────┴────────┘ 56 57 6 rows in set. Elapsed: 0.016 sec. 58 59 master :)
參考:https://clickhouse.tech/docs/zh/sql-reference/statements/alter/#alter_drop-column,更多參考官網。
8、數據表DDL,目前只有MergeTree、Merge和Distributed這三類表引擎支持Alter查詢,所以在進行alter操作的是注意表的引擎。
1)、DML(data manipulation language,數據操作語言):它們是SELECT、UPDATE、INSERT、DELETE,就象它的名字一樣,這4條命令是用來對數據庫里的數據進行操作的語言。凡是和數據的增刪改查有關的是DML。
2)、DDL(data definition language,數據定義語言):DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定義或改變表(TABLE)的結構,數據類型,表之間的鏈接和約束等初始化工作上,他們大多在建立表時使用。凡是和數據庫,數據表結構有關的都是DDL
3)、DCL(Data Control Language,數據控制語言):是數據庫控制功能。是用來設置或更改數據庫用戶或角色權限的語句,包括(grant、deny、revoke等)語句。在默認狀態下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人員才有權力執行DCL 。
列操作,改變表結構的標准語法:
1 ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ...
在語句中,配置一個或多個用逗號分隔的動作。每個動作是對某個列實施的操作行為。支持下列動作:
1)、ADD COLUMN — 添加列,默認添加到最后一列的后面,也可以指定列的位置。
1 master :) 2 master :) CREATE TABLE tb_alter 3 :-] ( 4 :-] `pid` UInt8, 5 :-] `name` String 6 :-] )engine=MergeTree() 7 :-] order by pid; 8 9 CREATE TABLE tb_alter 10 ( 11 `pid` UInt8, 12 `name` String 13 ) 14 ENGINE = MergeTree() 15 ORDER BY pid 16 17 Ok. 18 19 0 rows in set. Elapsed: 0.010 sec. 20 21 master :) alter table tb_alter add column age UInt8; 22 23 ALTER TABLE tb_alter 24 ADD COLUMN `age` UInt8 25 26 27 Ok. 28 29 0 rows in set. Elapsed: 0.024 sec. 30 31 master :) desc tb_alter; 32 33 DESCRIBE TABLE tb_alter 34 35 ┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 36 │ pid │ UInt8 │ │ │ │ │ │ 37 │ name │ String │ │ │ │ │ │ 38 │ age │ UInt8 │ │ │ │ │ │ 39 └──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 40 41 3 rows in set. Elapsed: 0.004 sec. 42 43 master :)
2)、DROP COLUMN — 刪除列,刪除列之后,列中的數據也會被刪除。
1 master :) alter table tb_alter drop column age; 2 3 ALTER TABLE tb_alter 4 DROP COLUMN age 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.034 sec. 10 11 master :) desc tb_alter; 12 13 DESCRIBE TABLE tb_alter 14 15 ┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 16 │ pid │ UInt8 │ │ │ │ │ │ 17 │ name │ String │ │ │ │ │ │ 18 └──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 19 20 2 rows in set. Elapsed: 0.004 sec. 21 22 master :)
3)、CLEAR COLUMN — 重置列的值。
1 master :) select * from tb_alter; 2 3 SELECT * 4 FROM tb_alter 5 6 ┌─pid─┬─name───┐ 7 │ 1 │ 張三三 │ 8 └─────┴────────┘ 9 10 1 rows in set. Elapsed: 0.007 sec. 11 12 master :) alter table tb_alter clear column name; 13 14 ALTER TABLE tb_alter 15 CLEAR COLUMN name 16 17 18 Ok. 19 20 0 rows in set. Elapsed: 0.029 sec. 21 22 master :) select * from tb_alter; 23 24 SELECT * 25 FROM tb_alter 26 27 ┌─pid─┬─name─┐ 28 │ 1 │ │ 29 └─────┴──────┘ 30 31 1 rows in set. Elapsed: 0.006 sec. 32 33 master :)
4)、COMMENT COLUMN — 給列增加注釋說明。
1 master :) 2 master :) alter table tb_alter comment column name '姓名'; 3 4 ALTER TABLE tb_alter 5 COMMENT COLUMN name '姓名' 6 7 8 Ok. 9 10 0 rows in set. Elapsed: 0.004 sec. 11 12 master :) desc tb_alter; 13 14 DESCRIBE TABLE tb_alter 15 16 ┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 17 │ pid │ UInt8 │ │ │ │ │ │ 18 │ name │ String │ │ │ 姓名 │ │ │ 19 └──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 20 21 2 rows in set. Elapsed: 0.003 sec. 22 23 master :)
5)、MODIFY COLUMN — 改變列的值類型,默認表達式以及TTL。不能修改主鍵和排序字段。
1 master :) alter table tb_alter modify column name UUID; 2 3 ALTER TABLE tb_alter 4 MODIFY COLUMN `name` UUID 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.008 sec. 10 11 master :) desc tb_alter; 12 13 DESCRIBE TABLE tb_alter 14 15 ┌─name─┬─type──┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 16 │ pid │ UInt8 │ │ │ │ │ │ 17 │ name │ UUID │ │ │ 姓名 │ │ │ 18 └──────┴───────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 19 20 2 rows in set. Elapsed: 0.006 sec. 21 22 master :)
參考:https://clickhouse.tech/docs/zh/sql-reference/statements/misc/#misc_operations-rename,更多參考官網。
9、Clickhouse移動表,在Linux系統中,mv命令的本意是將一個文件從原始位置A移動到目標位置B,但是如果位置A和位置B相同,則可以變相實現重命名的作用。Clickhouse的Rename查詢就與之有異曲同工之妙,Rename語句的完整語法,如下所示:
1 RENAME TABLE [db11.]name11 TO [db12.]name12, [db21.]name21 TO [db22.]name22, ... [ON CLUSTER cluster]
Rename可以修改表的名稱,如果將原始數據庫和目標數據庫設為不同的名稱,那么就可以實現數據表在兩個數據庫之間移動的效果。
1 master :) show tables; 2 3 SHOW TABLES 4 5 ┌─name───────────────┐ 6 │ .inner.m_name_view │ 7 │ m_name_view │ 8 │ tb_alter │ 9 │ tb_array │ 10 │ tb_enum │ 11 │ tb_name │ 12 │ tb_partition │ 13 │ tb_tinyLog │ 14 │ tb_tuple │ 15 │ user_db │ 16 │ view_name │ 17 └────────────────────┘ 18 19 11 rows in set. Elapsed: 0.006 sec. 20 21 master :) rename table tb_alter to tb_alter2; 22 23 RENAME TABLE tb_alter TO tb_alter2 24 25 Ok. 26 27 0 rows in set. Elapsed: 0.005 sec. 28 29 master :) show tables; 30 31 SHOW TABLES 32 33 ┌─name───────────────┐ 34 │ .inner.m_name_view │ 35 │ m_name_view │ 36 │ tb_alter2 │ 37 │ tb_array │ 38 │ tb_enum │ 39 │ tb_name │ 40 │ tb_partition │ 41 │ tb_tinyLog │ 42 │ tb_tuple │ 43 │ user_db │ 44 │ view_name │ 45 └────────────────────┘ 46 47 11 rows in set. Elapsed: 0.006 sec. 48 49 master :)
需要注意的是,數據表的移動只能在單個節點的范圍內,換言之,數據表移動的目標數據庫和原始數據庫必須在同一個服務節點內,而不能是集群的遠程節點。
1 master :) show tables; 2 3 SHOW TABLES 4 5 ┌─name───────────────┐ 6 │ .inner.m_name_view │ 7 │ m_name_view │ 8 │ tb_alter2 │ 9 │ tb_array │ 10 │ tb_enum │ 11 │ tb_name │ 12 │ tb_partition │ 13 │ tb_tinyLog │ 14 │ tb_tuple │ 15 │ user_db │ 16 │ view_name │ 17 └────────────────────┘ 18 19 11 rows in set. Elapsed: 0.007 sec. 20 21 master :) rename table tb_alter2 to gab_db2.tb_alter2; 22 23 RENAME TABLE tb_alter2 TO gab_db2.tb_alter2 24 25 Ok. 26 27 0 rows in set. Elapsed: 0.004 sec. 28 29 master :) show tables; 30 31 SHOW TABLES 32 33 ┌─name───────────────┐ 34 │ .inner.m_name_view │ 35 │ m_name_view │ 36 │ tb_array │ 37 │ tb_enum │ 38 │ tb_name │ 39 │ tb_partition │ 40 │ tb_tinyLog │ 41 │ tb_tuple │ 42 │ user_db │ 43 │ view_name │ 44 └────────────────────┘ 45 46 10 rows in set. Elapsed: 0.007 sec. 47 48 master :) show tables in gab_db2;; 49 50 SHOW TABLES FROM gab_db2 51 52 ┌─name──────┐ 53 │ tb_alter2 │ 54 │ tb_name │ 55 └───────────┘ 56 57 2 rows in set. Elapsed: 0.009 sec. 58 59 master :)
可以同時,在移動數據表的時候,修改數據表的名稱,如下所示:
1 master :) 2 master :) rename table gab_db2.tb_alter2 to gab_db.tb_alter; 3 4 RENAME TABLE gab_db2.tb_alter2 TO gab_db.tb_alter 5 6 Ok. 7 8 0 rows in set. Elapsed: 0.006 sec. 9 10 master :) show tables; 11 12 SHOW TABLES 13 14 ┌─name───────────────┐ 15 │ .inner.m_name_view │ 16 │ m_name_view │ 17 │ tb_alter │ 18 │ tb_array │ 19 │ tb_enum │ 20 │ tb_name │ 21 │ tb_partition │ 22 │ tb_tinyLog │ 23 │ tb_tuple │ 24 │ user_db │ 25 │ view_name │ 26 └────────────────────┘ 27 28 11 rows in set. Elapsed: 0.007 sec. 29 30 master :)
10、Clickhouse的TTL,定義值的存儲時間,只能為MergeTree系統表指定,確定值的生存期。當列中的值過期時候,Clickhouse會將其替換為列數據類型的默認值,如果數據部分中的所有列均已過期,Clickhouse則將從文件系統中的數據部分刪除此列。TTL可以為整個表和每個單獨的列設置該子句,表級TTL也可以指定在磁盤和卷之間自動移動數據的邏輯。
1)、列TTL,當列的時間超過設置的值,一整列數據會被刪除。表TTL,當表中的某個寫行的時間超過設置的值,整行會被刪除。
2)、TTL 表達式的計算結果必須是日期或日期時間類型的字段。例如TTL time_column、TTL time_column + interval。要定義interval, 需要使用時間間隔操作符,TTL date_time + INTERVAL 1 MONTH、TTL date_time + INTERVAL 15 HOUR。
3)、列TTL,當列中的值過期時, ClickHouse會將它們替換成該列數據類型的默認值。如果數據片段中列的所有值均已過期,則ClickHouse 會從文件系統中的數據片段中刪除此列。TTL子句不能被用於主鍵字段。
1 master :) 2 master :) CREATE TABLE tb_ttl 3 :-] ( 4 :-] id Int TTL ctime + INTERVAL 1 MONTH, 5 :-] age Int TTL ctime + INTERVAL 1 HOUR, 6 :-] name String, 7 :-] ctime DateTime 8 :-] )ENGINE = MergeTree 9 :-] PARTITION BY toYYYYMM(ctime) 10 :-] ORDER BY ctime; 11 12 CREATE TABLE tb_ttl 13 ( 14 `id` Int TTL ctime + toIntervalMonth(1), 15 `age` Int TTL ctime + toIntervalHour(1), 16 `name` String, 17 `ctime` DateTime 18 ) 19 ENGINE = MergeTree 20 PARTITION BY toYYYYMM(ctime) 21 ORDER BY ctime 22 23 Ok. 24 25 0 rows in set. Elapsed: 0.035 sec. 26 27 master :) desc tb_ttl; 28 29 DESCRIBE TABLE tb_ttl 30 31 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─────────────┐ 32 │ id │ Int32 │ │ │ │ │ ctime + toIntervalMonth(1) │ 33 │ age │ Int32 │ │ │ │ │ ctime + toIntervalHour(1) │ 34 │ name │ String │ │ │ │ │ │ 35 │ ctime │ DateTime │ │ │ │ │ │ 36 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────────────────┘ 37 38 4 rows in set. Elapsed: 0.007 sec. 39 40 master :) 41 master :) 42 master :) CREATE TABLE tb_ttl 43 :-] ( 44 :-] id Int TTL ctime + INTERVAL 1 MONTH, 45 :-] age Int TTL ctime + INTERVAL 1 HOUR, 46 :-] name String, 47 :-] ctime DateTime 48 :-] )ENGINE = MergeTree 49 :-] PARTITION BY toYYYYMM(ctime) 50 :-] ORDER BY ctime; 51 52 CREATE TABLE tb_ttl 53 ( 54 `id` Int TTL ctime + toIntervalMonth(1), 55 `age` Int TTL ctime + toIntervalHour(1), 56 `name` String, 57 `ctime` DateTime 58 ) 59 ENGINE = MergeTree 60 PARTITION BY toYYYYMM(ctime) 61 ORDER BY ctime 62 63 Ok. 64 65 0 rows in set. Elapsed: 0.035 sec. 66 67 master :) desc tb_ttl; 68 69 DESCRIBE TABLE tb_ttl 70 71 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─────────────┐ 72 │ id │ Int32 │ │ │ │ │ ctime + toIntervalMonth(1) │ 73 │ age │ Int32 │ │ │ │ │ ctime + toIntervalHour(1) │ 74 │ name │ String │ │ │ │ │ │ 75 │ ctime │ DateTime │ │ │ │ │ │ 76 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────────────────┘ 77 78 4 rows in set. Elapsed: 0.007 sec. 79 80 master :)
為數據表中已存在的列字段添加 TTL,如下所示:
1 master :) ALTER TABLE tb_ttl MODIFY COLUMN name String TTL ctime + INTERVAL 1 DAY; 2 3 ALTER TABLE tb_ttl 4 MODIFY COLUMN `name` String TTL ctime + toIntervalDay(1) 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.012 sec. 10 11 master :) desc tb_ttl; 12 13 DESCRIBE TABLE tb_ttl 14 15 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─────────────┐ 16 │ id │ Int32 │ │ │ │ │ ctime + toIntervalMonth(1) │ 17 │ age │ Int32 │ │ │ │ │ ctime + toIntervalHour(1) │ 18 │ name │ String │ │ │ │ │ ctime + toIntervalDay(1) │ 19 │ ctime │ DateTime │ │ │ │ │ │ 20 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────────────────┘ 21 22 4 rows in set. Elapsed: 0.005 sec. 23 24 master :)
修改數據表的列字段的 TTL,如下所示:
1 master :) ALTER TABLE tb_ttl MODIFY COLUMN name String TTL ctime + INTERVAL 1 HOUR; 2 3 ALTER TABLE tb_ttl 4 MODIFY COLUMN `name` String TTL ctime + toIntervalHour(1) 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.012 sec. 10 11 master :) desc tb_ttl; 12 13 DESCRIBE TABLE tb_ttl 14 15 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─────────────┐ 16 │ id │ Int32 │ │ │ │ │ ctime + toIntervalMonth(1) │ 17 │ age │ Int32 │ │ │ │ │ ctime + toIntervalHour(1) │ 18 │ name │ String │ │ │ │ │ ctime + toIntervalHour(1) │ 19 │ ctime │ DateTime │ │ │ │ │ │ 20 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────────────────┘ 21 22 4 rows in set. Elapsed: 0.004 sec. 23 24 master :)
4)、表 TTL,表可以設置一個用於移除過期行的表達式,以及多個用於在磁盤或卷上自動轉移數據片段的表達式。當表中的行過期時,ClickHouse 會刪除所有對應的行。對於數據片段的轉移特性,必須所有的行都滿足轉移條件。
1 TTL expr [DELETE|TO DISK 'aaa'|TO VOLUME 'bbb'], ...
TTL 規則的類型緊跟在每個 TTL 表達式后面,它會影響滿足表達式時(到達指定時間時)應當執行的操作:
a、DELETE - 刪除過期的行(默認操作)。
b、TO DISK 'aaa' - 將數據片段移動到磁盤 aaa。
c、TO VOLUME 'bbb' - 將數據片段移動到卷 bbb。
1 master :) 2 master :) CREATE TABLE tb_table_ttl 3 :-] ( 4 :-] ctime DateTime, 5 :-] id Int 6 :-] ) 7 :-] ENGINE = MergeTree 8 :-] PARTITION BY toYYYYMM(ctime) 9 :-] ORDER BY ctime 10 :-] TTL ctime + INTERVAL 1 MONTH DELETE; 11 12 CREATE TABLE tb_table_ttl 13 ( 14 `ctime` DateTime, 15 `id` Int 16 ) 17 ENGINE = MergeTree 18 PARTITION BY toYYYYMM(ctime) 19 ORDER BY ctime 20 TTL ctime + toIntervalMonth(1) 21 22 Ok. 23 24 0 rows in set. Elapsed: 0.012 sec. 25 26 master :) desc tb_table_ttl; 27 28 DESCRIBE TABLE tb_table_ttl 29 30 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 31 │ ctime │ DateTime │ │ │ │ │ │ 32 │ id │ Int32 │ │ │ │ │ │ 33 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 34 35 2 rows in set. Elapsed: 0.004 sec. 36 37 master :)
修改數據表的 TTL,如下所示:
1 master :) ALTER TABLE tb_table_ttl MODIFY TTL ctime + INTERVAL 1 DAY; 2 3 ALTER TABLE tb_table_ttl 4 MODIFY TTL ctime + toIntervalDay(1) 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.018 sec. 10 11 master :) desc tb_table_ttl; 12 13 DESCRIBE TABLE tb_table_ttl 14 15 ┌─name──┬─type─────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 16 │ ctime │ DateTime │ │ │ │ │ │ 17 │ id │ Int32 │ │ │ │ │ │ 18 └───────┴──────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 19 20 2 rows in set. Elapsed: 0.004 sec. 21 22 master :)
11、Clickhouse的數據分區的DDL操作。
Clickhouse內置了很多system系統表,用於查詢自身的狀態信息,其中parts系統表專門用於查詢數據表的分區信息,show tables from system;
1 master :) 2 master :) CREATE TABLE tb_partition 3 :-] ( 4 :-] `pid` UInt8, 5 :-] `name` String, 6 :-] `city` String 7 :-] )engine=MergeTree() 8 :-] partition by(city) 9 :-] order by pid; 10 11 CREATE TABLE tb_partition 12 ( 13 `pid` UInt8, 14 `name` String, 15 `city` String 16 ) 17 ENGINE = MergeTree() 18 PARTITION BY city 19 ORDER BY pid 20 21 Ok. 22 23 0 rows in set. Elapsed: 0.008 sec. 24 25 master :) insert into tb_partition values(1, '張三三', '北京市'), 26 :-] (1, '李思思', '天津市'), 27 :-] (1, '王五五', '重慶市'), 28 :-] (1, '小剛', '重慶市'), 29 :-] (1, '小紅', '重慶市'), 30 :-] (1, '小明', '北京市'); 31 32 INSERT INTO tb_partition VALUES 33 34 Ok. 35 36 6 rows in set. Elapsed: 0.006 sec. 37 38 master :) select * from tb_partition; 39 40 SELECT * 41 FROM tb_partition 42 43 ┌─pid─┬─name───┬─city───┐ 44 │ 1 │ 張三三 │ 北京市 │ 45 │ 1 │ 小明 │ 北京市 │ 46 └─────┴────────┴────────┘ 47 ┌─pid─┬─name───┬─city───┐ 48 │ 1 │ 李思思 │ 天津市 │ 49 └─────┴────────┴────────┘ 50 ┌─pid─┬─name───┬─city───┐ 51 │ 1 │ 王五五 │ 重慶市 │ 52 │ 1 │ 小剛 │ 重慶市 │ 53 │ 1 │ 小紅 │ 重慶市 │ 54 └─────┴────────┴────────┘ 55 56 6 rows in set. Elapsed: 0.021 sec. 57 58 master :)
可以使用Clickhouse的system數據庫下面的表parts查看自己創建的分區數據信息,如下所示:
1 master :) 2 master :) select path,table,name,partition from system.parts where table = 'tb_partition'; 3 4 SELECT 5 path, 6 table, 7 name, 8 partition 9 FROM system.parts 10 WHERE table = 'tb_partition' 11 12 ┌─path──────────────────────────────────────────────────────────────────────────────────┬─table────────┬─name───────────────────────────────────┬─partition─┐ 13 │ /var/lib/clickhouse/data/default/tb_partition/0166cf470a90ac651aab8618c56861aa_2_2_0/ │ tb_partition │ 0166cf470a90ac651aab8618c56861aa_2_2_0 │ 天津市 │ 14 │ /var/lib/clickhouse/data/default/tb_partition/44ceaf3baa845be4fde99b820ce370b7_1_1_0/ │ tb_partition │ 44ceaf3baa845be4fde99b820ce370b7_1_1_0 │ 北京市 │ 15 │ /var/lib/clickhouse/data/default/tb_partition/63ff9f9250ece854b1460461034fc2da_3_3_0/ │ tb_partition │ 63ff9f9250ece854b1460461034fc2da_3_3_0 │ 重慶市 │ 16 └───────────────────────────────────────────────────────────────────────────────────────┴──────────────┴────────────────────────────────────────┴───────────┘ 17 18 3 rows in set. Elapsed: 0.021 sec. 19 20 master :) 21 master :) 22 master :)
合理的設計分區鍵並利用分區的刪除功能,就能夠達到數據更新的目的,如下所示:
此命令會將指定分區刪除,並且分區中的數據也會被刪除,我們的可以刪除指定分區,然后再導入這個分區的數據,從而達到分區數據更新的目的。
1 master :) alter table tb_partition drop partition '天津市'; 2 3 ALTER TABLE tb_partition 4 DROP PARTITION '天津市' 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.008 sec. 10 11 master :) select path,table,name,partition from system.parts where table = 'tb_partition'; 12 13 SELECT 14 path, 15 table, 16 name, 17 partition 18 FROM system.parts 19 WHERE table = 'tb_partition' 20 21 ┌─path──────────────────────────────────────────────────────────────────────────────────┬─table────────┬─name───────────────────────────────────┬─partition─┐ 22 │ /var/lib/clickhouse/data/default/tb_partition/44ceaf3baa845be4fde99b820ce370b7_1_1_0/ │ tb_partition │ 44ceaf3baa845be4fde99b820ce370b7_1_1_0 │ 北京市 │ 23 │ /var/lib/clickhouse/data/default/tb_partition/63ff9f9250ece854b1460461034fc2da_3_3_0/ │ tb_partition │ 63ff9f9250ece854b1460461034fc2da_3_3_0 │ 重慶市 │ 24 └───────────────────────────────────────────────────────────────────────────────────────┴──────────────┴────────────────────────────────────────┴───────────┘ 25 26 2 rows in set. Elapsed: 0.022 sec. 27 28 master :)
Clickhouse支持將A表中的分區數據復制到B表,這項特性可以用於快速數據寫入,多表間數據同步和備份等場景,不過需要注意的是,並不是任意數據表質檢都能夠相互復制,它們還需要滿足兩個前提條件,如下所示:
1)、兩張表需要擁有相同的分區鍵。
2)、它們的表結構完全相同。
1 master :) CREATE TABLE tb_partition2 2 :-] ( 3 :-] `pid` UInt8, 4 :-] `name` String, 5 :-] `city` String 6 :-] ) 7 :-] ENGINE = MergeTree() 8 :-] PARTITION BY city 9 :-] ORDER BY pid; 10 11 CREATE TABLE tb_partition2 12 ( 13 `pid` UInt8, 14 `name` String, 15 `city` String 16 ) 17 ENGINE = MergeTree() 18 PARTITION BY city 19 ORDER BY pid 20 21 Ok. 22 23 0 rows in set. Elapsed: 0.017 sec. 24 25 master :) alter table tb_partition2 replace partition '北京市' from tb_partition; 26 27 ALTER TABLE tb_partition2 28 REPLACE PARTITION '北京市' FROM tb_partition 29 30 31 Ok. 32 33 0 rows in set. Elapsed: 0.004 sec. 34 35 master :) select * from tb_partition2; 36 37 SELECT * 38 FROM tb_partition2 39 40 ┌─pid─┬─name───┬─city───┐ 41 │ 1 │ 張三三 │ 北京市 │ 42 │ 1 │ 小明 │ 北京市 │ 43 └─────┴────────┴────────┘ 44 45 2 rows in set. Elapsed: 0.017 sec. 46 47 master :)
重置分區數據,如果數據表某一列的數據有誤,需要將其重置為初始值,如果設置了默認值那么就是默認值數據,如果沒有設置默認值,系統會給出默認的初始值,此時可以使用下面的語句實現:
1 master :) alter table tb_partition2 clear column name in partition '北京市'; 2 3 ALTER TABLE tb_partition2 4 CLEAR COLUMN name IN PARTITION '北京市' 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.014 sec. 10 11 master :) select * from tb_partition2; 12 13 SELECT * 14 FROM tb_partition2 15 16 ┌─pid─┬─name─┬─city───┐ 17 │ 1 │ │ 北京市 │ 18 │ 1 │ │ 北京市 │ 19 └─────┴──────┴────────┘ 20 21 2 rows in set. Elapsed: 0.023 sec. 22 23 master :)
卸載分區和裝載分區,表分區可以通過detach語句協助分區,卸載分區之后,它的物理數據並沒有刪除,而是被轉移到了當前數據表目錄的detached子目錄下面了。而裝載分區則是反向操作,它能夠將detached子目錄下的某個分區重新裝載回去。卸載與裝載這一對伴生的操作,常用於分區數據的遷移和備份場景。卸載某個分區的語法,如下所示:
1 master :) select * from tb_partition; 2 3 SELECT * 4 FROM tb_partition 5 6 ┌─pid─┬─name───┬─city───┐ 7 │ 1 │ 張三三 │ 北京市 │ 8 │ 1 │ 小明 │ 北京市 │ 9 └─────┴────────┴────────┘ 10 ┌─pid─┬─name───┬─city───┐ 11 │ 1 │ 王五五 │ 重慶市 │ 12 │ 1 │ 小剛 │ 重慶市 │ 13 │ 1 │ 小紅 │ 重慶市 │ 14 └─────┴────────┴────────┘ 15 16 5 rows in set. Elapsed: 0.027 sec. 17 18 master :) 19 master :) alter table tb_partition detach partition '北京市'; 20 21 ALTER TABLE tb_partition 22 DETACH PARTITION '北京市' 23 24 25 Ok. 26 27 0 rows in set. Elapsed: 0.002 sec. 28 29 master :) select * from tb_partition; 30 31 SELECT * 32 FROM tb_partition 33 34 ┌─pid─┬─name───┬─city───┐ 35 │ 1 │ 王五五 │ 重慶市 │ 36 │ 1 │ 小剛 │ 重慶市 │ 37 │ 1 │ 小紅 │ 重慶市 │ 38 └─────┴────────┴────────┘ 39 40 3 rows in set. Elapsed: 0.016 sec.
卸載完畢之后,可以裝載某個分區,如下所示:
1 master :) alter table tb_partition attach partition '北京市'; 2 3 ALTER TABLE tb_partition 4 ATTACH PARTITION '北京市' 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.007 sec. 10 11 master :) select * from tb_partition; 12 13 SELECT * 14 FROM tb_partition 15 16 ┌─pid─┬─name───┬─city───┐ 17 │ 1 │ 張三三 │ 北京市 │ 18 │ 1 │ 小明 │ 北京市 │ 19 └─────┴────────┴────────┘ 20 ┌─pid─┬─name───┬─city───┐ 21 │ 1 │ 王五五 │ 重慶市 │ 22 │ 1 │ 小剛 │ 重慶市 │ 23 │ 1 │ 小紅 │ 重慶市 │ 24 └─────┴────────┴────────┘ 25 26 5 rows in set. Elapsed: 0.020 sec. 27 28 master :)
12、Clickhouse的數據DML(數據操作語言),數據導入的幾種方式,如下所示:
1 ----------- 方式一,可以指定字段和對應的值 2 master :) insert into tb_partition(pid,name,city) values(2,'clickhouse','北京市'); 3 4 INSERT INTO tb_partition (pid, name, city) VALUES 5 6 Ok. 7 8 1 rows in set. Elapsed: 0.012 sec. 9 10 ----------- 方式二,可以直接給定全部字段的值 11 master :) insert into tb_partition values(3,'java','北京市'); 12 13 INSERT INTO tb_partition VALUES 14 15 Ok. 16 17 1 rows in set. Elapsed: 0.007 sec. 18 19 ----------- 方式三,可以查詢出一個表的字段,插入到另外一個表中 20 master :) insert into tb_partition select * from tb_partition2; 21 22 INSERT INTO tb_partition SELECT * 23 FROM tb_partition2 24 25 Ok. 26 27 0 rows in set. Elapsed: 0.016 sec. 28 29 master :) 30 31 32 ----------- 方式四,可以在創建的表的時候,將查詢的數據插入到該表中 33 master :) 34 master :) CREATE TABLE default.tb_partition3 ENGINE=Log as select * from tb_partition; 35 36 CREATE TABLE default.tb_partition3 37 ENGINE = Log AS 38 SELECT * 39 FROM tb_partition 40 41 Ok. 42 43 0 rows in set. Elapsed: 0.024 sec. 44 45 master :)
由文件導入到數據表中的時候,需要指定文件的分割符,--format_csv_delimiter=','參數后面跟的是字段之間的分割符。
1 ----------- 方式五,可以使用--query參數來指定sql語句,查看相關的數據信息。 2 [root@master ~]# 3 [root@master ~]# clickhouse-client --query='show databases'; 4 _temporary_and_external_tables 5 default 6 system 7 8 ----------- 可以通過-q參數來執行sql語句,查看相關的數據信息。 9 [root@master ~]# clickhouse-client -q 'show databases'; 10 _temporary_and_external_tables 11 default 12 system 13 [root@master ~]# 14 15 ----------- 可以通過-n參數來開啟多行sql語句同時執行。-m參數支持多行書寫。 16 [root@master ~]# clickhouse-client -n -q 'show databases;use default;select * from tb_partition'; 17 _temporary_and_external_tables 18 default 19 system 20 3 java 北京市 21 1 張三三 北京市 22 1 小明 北京市 23 1 北京市 24 1 北京市 25 2 clickhouse 北京市 26 1 王五五 重慶市 27 1 小剛 重慶市 28 1 小紅 重慶市 29 [root@master ~]# 30 31 ----------- 由文件導入到數據表中的時候,需要指定文件的分割符,--format_csv_delimiter=','參數后面跟的是字段之間的分割符。 32 [root@master clickhouse]# clickhouse-client --format_csv_delimiter=',' -q 'insert into default.tb_partition format CSV ' < ./data.txt 33 [root@master clickhouse]# 34 [root@master clickhouse]#
13、在Clickhouse中支持更新和刪除操作,這類操作稱為mutation操作,它可以看作是Alter語句的變種,雖然Mutation能最終實現修改和刪除,但是不能完全以通常意義上的update和delete來理解,我們必須清醒的人事到它的不同,不建議使用。
1)、首先,Mutation語句是一種很重的操作操作,更適用於批量數據的修改和刪除,建議批量操作。
2)、其次,Clickhouse對數據不支持事務,一旦語句被提交執行,就會立刻對現有數據產生影響,無法回滾。
3)、最后Mutation語句執行是一個異步的后台過程,語句被提交后就會立即返回,但是這並不代表已經執行完畢,它的具體執行進度需要通過system.mutations系統表查詢。注意,數據的修改和刪除操作是使用MergeTree家族引擎。
1 ----------- 刪除操作的語句,必須使用MergeTree引擎。 2 master :) alter table tb_partition delete where pid = 1; 3 4 ALTER TABLE tb_partition 5 DELETE WHERE pid = 1 6 7 8 Ok. 9 10 0 rows in set. Elapsed: 0.012 sec. 11 12 master :) select * from tb_partition; 13 14 SELECT * 15 FROM tb_partition 16 17 ┌─pid─┬─name───────┬─city───┐ 18 │ 14 │ java │ 北京市 │ 19 │ 15 │ 張三三 │ 北京市 │ 20 │ 16 │ 小明 │ 北京市 │ 21 │ 17 │ what │ 北京市 │ 22 │ 18 │ why │ 北京市 │ 23 │ 19 │ clickhouse │ 北京市 │ 24 └─────┴────────────┴────────┘ 25 ┌─pid─┬─name───────┬─city───┐ 26 │ 2 │ clickhouse │ 北京市 │ 27 │ 3 │ java │ 北京市 │ 28 └─────┴────────────┴────────┘ 29 ┌─pid─┬─name───┬─city───┐ 30 │ 10 │ 王五五 │ 重慶市 │ 31 │ 11 │ 小剛 │ 重慶市 │ 32 │ 12 │ 小紅 │ 重慶市 │ 33 └─────┴────────┴────────┘ 34 ┌─pid─┬─name───────┬─city───┐ 35 │ 4 │ java │ 北京市 │ 36 │ 5 │ 張三三 │ 北京市 │ 37 │ 6 │ 小明 │ 北京市 │ 38 │ 7 │ what │ 北京市 │ 39 │ 8 │ why │ 北京市 │ 40 │ 9 │ clickhouse │ 北京市 │ 41 └─────┴────────────┴────────┘ 42 ┌─pid─┬─name───┬─city───┐ 43 │ 20 │ 王五五 │ 重慶市 │ 44 │ 21 │ 小剛 │ 重慶市 │ 45 │ 22 │ 小紅 │ 重慶市 │ 46 └─────┴────────┴────────┘ 47 48 20 rows in set. Elapsed: 0.027 sec. 49 50 master :)
Clickhouse的修改語句,注意,不能修改排序和主鍵字段,必須使用MergeTree引擎,如下所示:
1 master :) alter table tb_partition update name='王五' where pid = 20; 2 3 ALTER TABLE tb_partition 4 UPDATE name = '王五' WHERE pid = 20 5 6 7 Ok. 8 9 0 rows in set. Elapsed: 0.012 sec. 10 11 master :) select * from tb_partition; 12 13 SELECT * 14 FROM tb_partition 15 16 ┌─pid─┬─name───────┬─city───┐ 17 │ 14 │ java │ 北京市 │ 18 │ 15 │ 張三三 │ 北京市 │ 19 │ 16 │ 小明 │ 北京市 │ 20 │ 17 │ what │ 北京市 │ 21 │ 18 │ why │ 北京市 │ 22 │ 19 │ clickhouse │ 北京市 │ 23 └─────┴────────────┴────────┘ 24 ┌─pid─┬─name───────┬─city───┐ 25 │ 2 │ clickhouse │ 北京市 │ 26 │ 3 │ java │ 北京市 │ 27 └─────┴────────────┴────────┘ 28 ┌─pid─┬─name───┬─city───┐ 29 │ 10 │ 王五五 │ 重慶市 │ 30 │ 11 │ 小剛 │ 重慶市 │ 31 │ 12 │ 小紅 │ 重慶市 │ 32 └─────┴────────┴────────┘ 33 ┌─pid─┬─name───────┬─city───┐ 34 │ 4 │ java │ 北京市 │ 35 │ 5 │ 張三三 │ 北京市 │ 36 │ 6 │ 小明 │ 北京市 │ 37 │ 7 │ what │ 北京市 │ 38 │ 8 │ why │ 北京市 │ 39 │ 9 │ clickhouse │ 北京市 │ 40 └─────┴────────────┴────────┘ 41 ┌─pid─┬─name─┬─city───┐ 42 │ 20 │ 王五 │ 重慶市 │ 43 │ 21 │ 小剛 │ 重慶市 │ 44 │ 22 │ 小紅 │ 重慶市 │ 45 └─────┴──────┴────────┘ 46 47 20 rows in set. Elapsed: 0.014 sec. 48 49 master :)