Clickhouse基础语法、数据类型、数据表引擎学习
1、Clickhouse創(chuàng)建數(shù)據(jù)庫(kù)的語法,如下所示:
1 CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(...)]使用案例,如下所示:
1 master :) CREATE DATABASE IF NOT EXISTS gab_db;2 3 CREATE DATABASE IF NOT EXISTS gab_db4 5 Ok.6 7 0 rows in set. Elapsed: 0.013 sec. 8 9 master :) show databases; 10 11 SHOW DATABASES 12 13 ┌─name───────────────────────────┐ 14 │ _temporary_and_external_tables │ 15 │ default │ 16 │ gab_db │ 17 │ system │ 18 └────────────────────────────────┘ 19 20 4 rows in set. Elapsed: 0.012 sec. 21 22 master :)?
2、默認(rèn)情況下,ClickHouse使用的是原生的數(shù)據(jù)庫(kù)引擎Ordinary(在此數(shù)據(jù)庫(kù)下可以使用任意類型的表引擎,在絕大多數(shù)情況下都只需使用默認(rèn)的數(shù)據(jù)庫(kù)引擎)。當(dāng)然也可以使用Lazy引擎和MySQL引擎,比如使用MySQL引擎,可以直接在ClickHouse中操作MySQL對(duì)應(yīng)數(shù)據(jù)庫(kù)中的表。假設(shè)MySQL中存在一個(gè)名為Clickhouse的數(shù)據(jù)庫(kù),可以使用下面的方式連接MySQL數(shù)據(jù)庫(kù)。
1 -- --------------------------語法-----------------------------------2 CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster]3 ENGINE = MySQL('host:port', ['database' | database], 'user', 'password')4 5 -- --------------------------示例------------------------------------6 CREATE DATABASE mysql_db ENGINE = MySQL('192.168.0.109:3306', 'clickhouse', 'root', '123456');7 8 9 -- ---------------------------操作----------------------------------- 10 master :) CREATE DATABASE mysql_db ENGINE = MySQL('192.168.0.109:3306', 'clickhouse', 'root', '123456'); 11 12 CREATE DATABASE mysql_db 13 ENGINE = MySQL('192.168.0.109:3306', 'clickhouse', 'root', '123456') 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.011 sec. 18 19 master :) show databases; 20 21 SHOW DATABASES 22 23 ┌─name───────────────────────────┐ 24 │ _temporary_and_external_tables │ 25 │ default │ 26 │ gab_db │ 27 │ mysql_db │ 28 │ system │ 29 └────────────────────────────────┘ 30 31 5 rows in set. Elapsed: 0.006 sec. 32 33 master :) use mysql_db; 34 35 USE mysql_db 36 37 Ok. 38 39 0 rows in set. Elapsed: 0.002 sec. 40 41 master :) show tables; 42 43 SHOW TABLES 44 45 Ok. 46 47 0 rows in set. Elapsed: 0.012 sec. 48 49 master :) show tables; 50 51 SHOW TABLES 52 53 ┌─name────┐ 54 │ user_db │ 55 └─────────┘ 56 57 1 rows in set. Elapsed: 0.011 sec. 58 59 master :) select * from user_db; 60 61 SELECT * 62 FROM user_db 63 64 ┌─id─┬─name─────┬─age─┬─address──────┐ 65 │ 1 │ zhangsan │ 22 │ 河南省新鄉(xiāng)市 │ 66 └────┴──────────┴─────┴──────────────┘ 67 68 1 rows in set. Elapsed: 0.020 sec. 69 70 master :)如果創(chuàng)建的時(shí)候報(bào)下面的錯(cuò)誤,是因?yàn)闄?quán)限的問題,執(zhí)行下面的命令,解決問題即可。
1 master :) CREATE DATABASE mysql_db ENGINE = MySQL('192.168.0.109:3306', 'clickhouse', 'root', '123456');2 3 CREATE DATABASE mysql_db4 ENGINE = MySQL('192.168.0.109:3306', 'clickhouse', 'root', '123456')5 6 7 Received exception from server (version 20.8.3):8 Code: 501. DB::Exception: Received from localhost:9000. DB::Exception: Cannot create MySQL database, because Poco::Exception. Code: 1000, e.code() = 1045, e.displayText() = mysqlxx::ConnectionFailed: Access denied for user 'root'@'192.168.0.109' (using password: YES) ((nullptr):3306), 9 10 0 rows in set. Elapsed: 0.042 sec.執(zhí)行下面兩行命令,解決問題即可。
1 grant all privileges on *.* to root@'%' identified by '123456'; 2 3 FLUSH PRIVILEGES;?
3、Clickhouse創(chuàng)建數(shù)據(jù)表的,語法如下所示:
1 CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] 2 ( 3 name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1], 4 name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [compression_codec] [TTL expr2], 5 ... 6 ) ENGINE = engine使用案例,如下所示:
1 master :) 2 master :) show tables;3 4 SHOW TABLES5 6 Ok.7 8 0 rows in set. Elapsed: 0.008 sec. 9 10 master :) create table user_db( 11 :-] id Int32, 12 :-] name String 13 :-] )engine=Memory; 14 15 CREATE TABLE user_db 16 ( 17 `id` Int32, 18 `name` String 19 ) 20 ENGINE = Memory 21 22 Ok. 23 24 0 rows in set. Elapsed: 0.003 sec. 25 26 master :) show tables; 27 28 SHOW TABLES 29 30 ┌─name────┐ 31 │ user_db │ 32 └─────────┘ 33 34 1 rows in set. Elapsed: 0.007 sec. 35 36 master :)上面命令是創(chuàng)建了一張內(nèi)存表,即使用的是Memory引擎。表引擎決定了數(shù)據(jù)表的特性,也決定了數(shù)據(jù)將會(huì)被如何存儲(chǔ)及加載。Memory引擎是ClickHouse最簡(jiǎn)單的表引擎,數(shù)據(jù)只會(huì)被保存在內(nèi)存中,在服務(wù)重啟時(shí)數(shù)據(jù)會(huì)丟失。
?
4、Clickhouse的數(shù)據(jù)類型,在創(chuàng)建數(shù)據(jù)表的時(shí)候指定字段的數(shù)據(jù)類型,數(shù)據(jù)類型在使用的時(shí)候是區(qū)分大小寫的,所以在定義字段的時(shí)候一定注意數(shù)據(jù)類型的書寫。
4.1、整數(shù)數(shù)據(jù)類型Int Ranges ,Clickhouse直接使用Int8、Int16、Int32、Int64指代4種大小的Int類型,其末尾的數(shù)據(jù)正好表明了占用字節(jié)的大小(1個(gè)節(jié)點(diǎn) = 8位)。
| 名稱 | 大小(字節(jié)) | 范圍 | 普遍觀念 |
| Int8 | 1個(gè)字節(jié) | -128到127 | Tinyint |
| Int16 | 2個(gè)字節(jié) | -32768到32767 | Smallint |
| Int32 | 4個(gè)字節(jié) | -2147483648到2147483647 | int |
| Int64 | 8個(gè)字節(jié) | -9223372036854775808到9223372036854775807 | Bigint |
?具體對(duì)應(yīng)關(guān)系,如下所示:
Int8 - [-128 : 127] Int16 - [-32768 : 32767] Int32 - [-2147483648 : 2147483647] Int64 - [-9223372036854775808 : 9223372036854775807]整數(shù)數(shù)據(jù)類型Uint Ranges,Clickhouse支持無符號(hào)的整數(shù),使用前綴U表示,都表示的是正數(shù),即無負(fù)數(shù)表示。
UInt8 - [0 : 255] UInt16 - [0 : 65535] UInt32 - [0 : 4294967295] UInt64 - [0 : 18446744073709551615]使用案例,如下所示:
1 master :) create table tb_name(2 :-] id UInt8 , -- 指定數(shù)據(jù)類型3 :-] age UInt8 , -- 指定數(shù)據(jù)類型4 :-] flow Int64 -- 指定數(shù)據(jù)類型5 :-] ) engine=Log ; -- 指定表引擎6 7 CREATE TABLE tb_name8 (9 `id` UInt8, 10 `age` UInt8, 11 `flow` Int64 12 ) 13 ENGINE = Log 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.004 sec. 18 19 master :)4.2、小數(shù)數(shù)據(jù)類型。
Float32 - float,注意:和我們之前的認(rèn)知是一樣的,這種數(shù)據(jù)類型在數(shù)據(jù)特別精準(zhǔn)的情況下可能出現(xiàn)數(shù)據(jù)精度問題。 Float64 - double Decimal(P,S) Decimal32(s) Decimal64(s) ) Decimal128(s)。| 名稱 | 大小(字節(jié)) | 有效精度(位數(shù)) | 普遍概念 |
| Float32 | 4個(gè)字節(jié) | 7位 | Float |
| Float64 | 8個(gè)字節(jié) | 16位 | Double |
Select 8.0/0 INF表示的是正無窮,Select -8.0/0 INF表示負(fù)無窮,Select 0/0 NAN表示非數(shù)字。
使用案例,如下所示:
1 master :) create table tb_user(2 :-] uid Int8 ,3 :-] sal Decimal32(2)-- 指定2位小數(shù)點(diǎn) 4 :-] ) engine=TinyLog ;5 6 CREATE TABLE tb_user7 (8 `uid` Int8,9 `sal` Decimal32(2) 10 ) 11 ENGINE = TinyLog 12 13 Ok. 14 15 0 rows in set. Elapsed: 0.018 sec. 16 17 master :) insert into tb_user values(1,10000),(2,30000),(3,2000) ; 18 19 INSERT INTO tb_user VALUES 20 21 Ok. 22 23 3 rows in set. Elapsed: 0.053 sec. 24 25 master :) select * from tb_user; 26 27 SELECT * 28 FROM tb_user 29 30 ┌─uid─┬──────sal─┐ 31 │ 1 │ 10000.00 │ 32 │ 2 │ 30000.00 │ 33 │ 3 │ 2000.00 │ 34 └─────┴──────────┘ 35 36 3 rows in set. Elapsed: 0.009 sec. 37 38 master :)Decimal如果要求高精度的數(shù)值運(yùn)算,則需要使用定點(diǎn)數(shù)。Clickhouse提供了Decimal32、Decimal64和Decimal128三種精度的定點(diǎn)數(shù)。可以通過兩種行式表明定點(diǎn),簡(jiǎn)寫方式有Decimal32(S)、Decimal64(S)、Decimal128(S)三種,原生方式為Decimal(P,S),其中,P代表了精度,決定總位數(shù)(整數(shù)部分+ 小數(shù)部分),取值范圍是1~38,S代表規(guī)模,決定小數(shù)位,取值范圍是0~P。
| 名稱 | 等效聲明 | 范圍 |
| Decimal32(S) | Decimal(1 ~ 9,S) | -1 * 10^(9-S) 到 1 * 10^(9-S) |
| Decimal64(S) | Decimal(10 ~ 18,S) | -1 * 10^(18-S) 到 1 * 10^(18-S) |
| Decimal128(S) | Decimal(19 ~ 38,S) | -1 * 10^(38-S) 到 1 * 10^(38-S) |
在使用兩個(gè)不同精度的定點(diǎn)數(shù)進(jìn)行四則運(yùn)算的時(shí)候,它們的小數(shù)點(diǎn),位數(shù)S會(huì)發(fā)生變化。
在進(jìn)行加法運(yùn)算的時(shí)候,S取最大值,例如下面的查詢toDecimal64(2,4)與toDecimal32(2,2)相加后S=4;
在進(jìn)行減法運(yùn)算的時(shí)候,S取最大值,例如下面的查詢toDecimal(2,4)與toDecimal32(2,2)相減后S=4;
在進(jìn)行乘法運(yùn)算的時(shí)候,S取最大值,例如下面的查詢toDecimal(2,4)與toDecimal32(2,2)相乘后S=4+2;
在進(jìn)行除法運(yùn)算的時(shí)候,S取最大值,例如下面的查詢toDecimal(2,4)與toDecimal32(2,2)相除后S=4;
但是要保證被除數(shù)的S大于除數(shù)的S,否則會(huì)報(bào)錯(cuò)。
4.3、boolean類型,Clickhouse中沒有對(duì)布爾類型進(jìn)行支持,可以使用0 和1 來代表布爾數(shù)據(jù)類型。
4.4、字符串?dāng)?shù)據(jù)類型,字符串類型可以細(xì)分為String、FixedString、UUID三類,從命名來看彷佛是由一款數(shù)據(jù)庫(kù)提供的類型,反而更像一門編程語言的設(shè)計(jì),Clickhouse語法具備編程語言的特征(數(shù)據(jù)+運(yùn)算)。
a)、String,字符串由String定義,長(zhǎng)度不限,因此在使用String的時(shí)候無須聲明大小。它完全代替了傳統(tǒng)意義上數(shù)據(jù)庫(kù)的Varchar、Text、Clob和Blob等字符類型。String類型不限定字符集,因?yàn)樗揪蜎]有這個(gè)概念,所以可以將任意編碼的字符串存入其中。但是為了程序的規(guī)范性和可維護(hù)性,在同一套程序中應(yīng)該遵守使用統(tǒng)一的編碼,例如,統(tǒng)一使用UTF-8編碼就是一種很好的約定。所以在對(duì)數(shù)據(jù)操作的時(shí)候我們不再需要去關(guān)注編碼和亂碼問題。
b)、FixedString,類型和傳統(tǒng)意義上的Char類型有些類似,對(duì)于一些字符有明確長(zhǎng)度的場(chǎng)合,可以使用固定長(zhǎng)度的字符串。定長(zhǎng)字符串通過FixedString(N)聲明,其中N表示字符串長(zhǎng)度,但是與Char不同的是,FixedString使用Null字節(jié)填充末尾字符,而Char通常使用空格填充。
String -- 字符串?dāng)?shù)據(jù)類型 一般情況下使用String;類型就可以 FixedString(n) -- 固定長(zhǎng)度的數(shù)據(jù)類型使用案例,如下所示:
1 master :) drop table if exists tb_stu ;2 3 DROP TABLE IF EXISTS tb_stu4 5 Ok.6 7 0 rows in set. Elapsed: 0.013 sec. 8 9 master :) create table if not exists tb_stu( 10 :-] sid FixedString(8) , 11 :-] name String , 12 :-] address String 13 :-] ) engine = TinyLog ; 14 15 CREATE TABLE IF NOT EXISTS tb_stu 16 ( 17 `sid` FixedString(8), 18 `name` String, 19 `address` String 20 ) 21 ENGINE = TinyLog 22 23 Ok. 24 25 0 rows in set. Elapsed: 0.013 sec. 26 27 master :) 28 master :) insert into tb_stu values('aaaaaaaa' , 'HANGGE' ,'ZhongNanHai') ; 29 30 INSERT INTO tb_stu VALUES 31 32 Ok. 33 34 1 rows in set. Elapsed: 0.011 sec. 35 36 master :) select * from tb_stu; 37 38 SELECT * 39 FROM tb_stu 40 41 ┌─sid──────┬─name───┬─address─────┐ 42 │ aaaaaaaa │ HANGGE │ ZhongNanHai │ 43 └──────────┴────────┴─────────────┘ 44 45 1 rows in set. Elapsed: 0.008 sec. 46 47 master :)4.5、UUID隨機(jī)的一串字符串。
1 master :) drop table if exists tb_uuid ;2 3 DROP TABLE IF EXISTS tb_uuid4 5 Ok.6 7 0 rows in set. Elapsed: 0.002 sec. 8 9 master :) create table tb_uuid( 10 :-] id UUID , 11 :-] name String 12 :-] ) engine = TinyLog ; 13 14 CREATE TABLE tb_uuid 15 ( 16 `id` UUID, 17 `name` String 18 ) 19 ENGINE = TinyLog 20 21 Ok. 22 23 0 rows in set. Elapsed: 0.003 sec. 24 25 master :) 26 master :) insert into tb_uuid (name) values ('zss') , ('lss') ,('daa') ; 27 28 INSERT INTO tb_uuid (name) VALUES 29 30 Ok. 31 32 3 rows in set. Elapsed: 0.004 sec. 33 34 master :) insert into tb_uuid select generateUUIDv4() , 'HANGGE' ; 35 36 INSERT INTO tb_uuid SELECT 37 generateUUIDv4(), 38 'HANGGE' 39 40 Ok. 41 42 0 rows in set. Elapsed: 0.010 sec. 43 44 master :) select * from tb_uuid; 45 46 SELECT * 47 FROM tb_uuid 48 49 ┌───────────────────────────────────id─┬─name───┐ 50 │ 00000000-0000-0000-0000-000000000000 │ zss │ 51 │ 00000000-0000-0000-0000-000000000000 │ lss │ 52 │ 00000000-0000-0000-0000-000000000000 │ daa │ 53 │ c712b9e8-1c6c-4614-a836-f85da3de62aa │ HANGGE │ 54 └──────────────────────────────────────┴────────┘ 55 56 4 rows in set. Elapsed: 0.008 sec. 57 58 master :)4.6、枚舉類型,包括 Enum8 和 Enum16 類型。Enum 保存 'string'= integer 的對(duì)應(yīng)關(guān)系。Enum8 用 'String'= Int8 對(duì)描述。Enum16 用 'String'= Int16 對(duì)描述。
用法演示,創(chuàng)建一個(gè)帶有一個(gè)枚舉 Enum8('hello' = 1, 'world' = 2) 類型的列:
1 master :) CREATE TABLE t_enum2 :-] (3 :-] x Enum8('hello' = 1, 'world' = 2)4 :-] )5 :-] ENGINE = TinyLog;6 7 CREATE TABLE t_enum8 (9 `x` Enum8('hello' = 1, 'world' = 2) 10 ) 11 ENGINE = TinyLog 12 13 Ok. 14 15 0 rows in set. Elapsed: 0.008 sec. 16 17 master :) 18 19 -- 這個(gè) x 列只能存儲(chǔ)類型定義中列出的值:'hello'或'world'。如果嘗試保存任何其他值,ClickHouse 拋出異常。 20 master :) INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello') 21 :-] ; 22 23 INSERT INTO t_enum VALUES 24 25 Ok. 26 27 3 rows in set. Elapsed: 0.006 sec. 28 29 master :) INSERT INTO t_enum VALUES; 30 31 INSERT INTO t_enum VALUES 32 33 Ok. 34 35 0 rows in set. Elapsed: 0.004 sec. 36 37 master :) insert into t_enum values('a') 38 :-] ; 39 40 INSERT INTO t_enum VALUES 41 42 43 Exception on client: 44 Code: 36. DB::Exception: Unknown element 'a' for type Enum8('hello' = 1, 'world' = 2) 45 46 Connecting to localhost:9000 as user default. 47 Connected to ClickHouse server version 20.8.3 revision 54438. 48 49 master :) 50 51 52 -- 從表中查詢數(shù)據(jù)時(shí),ClickHouse 從 Enum 中輸出字符串值。 53 master :) select * from t_enum; 54 55 SELECT * 56 FROM t_enum 57 58 ┌─x─────┐ 59 │ hello │ 60 │ world │ 61 │ hello │ 62 └───────┘ 63 64 3 rows in set. Elapsed: 0.009 sec. 65 66 master :) 67 68 69 -- 如果需要看到對(duì)應(yīng)行的數(shù)值,則必須將 Enum 值轉(zhuǎn)換為整數(shù)類型。cast 強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換... 將枚舉類型字段轉(zhuǎn)換成Int8數(shù)據(jù)類型 70 master :) SELECT CAST(x, 'Int8') FROM t_enum 71 :-] ; 72 73 SELECT CAST(x, 'Int8') 74 FROM t_enum 75 76 ┌─CAST(x, 'Int8')─┐ 77 │ 1 │ 78 │ 2 │ 79 │ 1 │ 80 └─────────────────┘ 81 82 3 rows in set. Elapsed: 0.006 sec. 83 84 master :)4.7、數(shù)組數(shù)據(jù)類型。Array(T):由 T 類型元素組成的數(shù)組。其中,T 可以是任意類型,包含數(shù)組類型。 但不推薦使用多維數(shù)組,ClickHouse 對(duì)多維數(shù)組的支持有限。
例如,不能在 MergeTree 表中存儲(chǔ)多維數(shù)組。
Clickhouse支持?jǐn)?shù)組這種復(fù)合數(shù)據(jù)類型,并且數(shù)據(jù)操作在數(shù)據(jù)分析中起到非常便利的效果,數(shù)組的定義方式有兩種: 第一種是array(T),泛型的方式。 第二種是直接插入數(shù)據(jù)的行式[e1,e2,e3.....],我們?cè)谶@里要求數(shù)組中的數(shù)據(jù)類型是一致的,數(shù)組是強(qiáng)數(shù)據(jù)類型。使用案例,如下所示:
1 master :) SELECT array(1, 2) AS x, toTypeName(x);2 3 SELECT 4 [1, 2] AS x,5 toTypeName(x)6 7 ┌─x─────┬─toTypeName(array(1, 2))─┐8 │ [1,2] │ Array(UInt8) │9 └───────┴─────────────────────────┘ 10 11 1 rows in set. Elapsed: 0.022 sec. 12 13 master :) SELECT [1, 2] AS x, toTypeName(x); 14 15 SELECT 16 [1, 2] AS x, 17 toTypeName(x) 18 19 ┌─x─────┬─toTypeName([1, 2])─┐ 20 │ [1,2] │ Array(UInt8) │ 21 └───────┴────────────────────┘ 22 23 1 rows in set. Elapsed: 0.009 sec. 24 25 26 -- 數(shù)組的取值,從1開始取值,中括號(hào)里面從1開始,就可以取出數(shù)組的第一個(gè)值。 27 28 master :) SELECT ['a', 'b', 'c'][1] 29 :-] ; 30 31 SELECT ['a', 'b', 'c'][1] 32 33 ┌─arrayElement(['a', 'b', 'c'], 1)─┐ 34 │ a │ 35 └──────────────────────────────────┘ 36 37 1 rows in set. Elapsed: 0.006 sec. 38 39 master :) select array('a','b','c')[2]; 40 41 SELECT ['a', 'b', 'c'][2] 42 43 ┌─arrayElement(array('a', 'b', 'c'), 2)─┐ 44 │ b │ 45 └───────────────────────────────────────┘ 46 47 1 rows in set. Elapsed: 0.007 sec. 48 49 master :)如果要?jiǎng)?chuàng)建Array數(shù)組類型的字段,需要使用()來指定泛型,比如Array(String),如下所示:
1 master :) 2 master :) CREATE TABLE tb_array3 :-] (4 :-] `id` UInt8,5 :-] `name` String,6 :-] `hobby` Array(String)7 :-] )ENGINE = Log;8 9 CREATE TABLE tb_array 10 ( 11 `id` UInt8, 12 `name` String, 13 `hobby` Array(String) 14 ) 15 ENGINE = Log 16 17 Ok. 18 19 0 rows in set. Elapsed: 0.029 sec. 20 21 master :) desc tb_array; 22 23 DESCRIBE TABLE tb_array 24 25 ┌─name──┬─type──────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 26 │ id │ UInt8 │ │ │ │ │ │ 27 │ name │ String │ │ │ │ │ │ 28 │ hobby │ Array(String) │ │ │ │ │ │ 29 └───────┴───────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 30 31 3 rows in set. Elapsed: 0.014 sec. 32 33 master :) insert into tb_array values(1,'張三',['抽煙','喝酒','燙頭']),(2,'岳岳',['說相聲','唱歌']); 34 35 INSERT INTO tb_array VALUES 36 37 Ok. 38 39 2 rows in set. Elapsed: 0.045 sec. 40 41 master :) 42 master :) select * from tb_array; 43 44 SELECT * 45 FROM tb_array 46 47 ┌─id─┬─name─┬─hobby──────────────────┐ 48 │ 1 │ 張三 │ ['抽煙','喝酒','燙頭'] │ 49 │ 2 │ 岳岳 │ ['說相聲','唱歌'] │ 50 └────┴──────┴────────────────────────┘ 51 52 2 rows in set. Elapsed: 0.071 sec. 53 54 master :)注意:根據(jù)數(shù)組創(chuàng)建的數(shù)據(jù)塊數(shù),會(huì)根據(jù)服務(wù)器的核數(shù)來決定創(chuàng)建幾個(gè)塊,服務(wù)器的核數(shù)決定了創(chuàng)建的塊數(shù)。
1 總核數(shù) = 物理CPU個(gè)數(shù) * 每顆物理CPU的核數(shù)。2 總邏輯CPU數(shù) = 物理CPU個(gè)數(shù) * 每顆物理CPU的核數(shù) * 超線程數(shù)。3 4 查看物理CPU個(gè)數(shù)。5 cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l6 7 查看每個(gè)物理CPU中的core的個(gè)數(shù)即核數(shù)。8 cat /proc/cpuinfo | grep "cpu cores" |uniq9 10 查看邏輯CPU的個(gè)數(shù) 11 cat /proc/cpuinfo | grep "processor" | wc -l數(shù)組居然還支持高階函數(shù),類似Java的lambda表達(dá)式,也是很強(qiáng)大的東西了,如下所示:
注意:Clickhouse的字符串不能使用雙引號(hào)引起來,只能使用單引號(hào)引起來。
1 master :) 2 master :) select arrayMap(e -> concat(e,'lambda'),hobby) from tb_array;3 4 SELECT arrayMap(e -> concat(e, 'lambda'), hobby)5 FROM tb_array6 7 ┌─arrayMap(lambda(tuple(e), concat(e, 'lambda')), hobby)─┐8 │ ['抽煙lambda','喝酒lambda','燙頭lambda'] │9 │ ['說相聲lambda','唱歌lambda'] │ 10 └────────────────────────────────────────────────────────┘ 11 12 2 rows in set. Elapsed: 0.048 sec. 13 14 master :)4.8、Nested數(shù)據(jù)類型,Nested(name1 Type1, Name2 Type2, …)。
Nested是一種嵌套表結(jié)構(gòu),一張數(shù)據(jù)表,可以定義任意多個(gè)嵌套類型字段,但是每個(gè)字段的嵌套層級(jí)只支持一級(jí),即嵌套表內(nèi)不能繼續(xù)使用嵌套類型,對(duì)于簡(jiǎn)單場(chǎng)景的層級(jí)關(guān)系或者關(guān)聯(lián)關(guān)系,使用嵌套類型也是一個(gè)不錯(cuò)的選擇。
Nested嵌套類型本質(zhì)是一種多維數(shù)組的結(jié)構(gòu),嵌套表中的每個(gè)字段的都是一個(gè)數(shù)組,并且行與行之間數(shù)組的長(zhǎng)度無須對(duì)齊,但是需要注意的是,在同一行數(shù)據(jù)內(nèi)每個(gè)數(shù)組字段的長(zhǎng)度必須相等。
1 master :) 2 master :) CREATE TABLE tb_nested3 :-] (4 :-] `id` String,5 :-] `user` Nested( uid Int, name String, age UInt8)6 :-] )ENGINE = TinyLog;7 8 CREATE TABLE tb_nested9 ( 10 `id` String, 11 `user` Nested( uid Int, name String, age UInt8) 12 ) 13 ENGINE = TinyLog 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.010 sec. 18 19 master :) desc tb_nested ; 20 21 DESCRIBE TABLE tb_nested 22 23 ┌─name──────┬─type──────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐ 24 │ id │ String │ │ │ │ │ │ 25 │ user.uid │ Array(Int32) │ │ │ │ │ │ 26 │ user.name │ Array(String) │ │ │ │ │ │ 27 │ user.age │ Array(UInt8) │ │ │ │ │ │ 28 └───────────┴───────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘ 29 30 4 rows in set. Elapsed: 0.012 sec. 31 32 master :)插入數(shù)據(jù),進(jìn)行簡(jiǎn)單的測(cè)試,如下所示:
1 master :) insert into tb_nested values(1 , [1,2,3],['zss','lss','ymm'],[21,33,18]) ;2 3 INSERT INTO tb_nested VALUES4 5 Ok.6 7 1 rows in set. Elapsed: 0.007 sec. 8 9 master :) SELECT 10 :-] user.uid, 11 :-] user.name 12 :-] FROM tb_nested; 13 14 SELECT 15 user.uid, 16 user.name 17 FROM tb_nested 18 19 ┌─user.uid─┬─user.name───────────┐ 20 │ [1,2,3] │ ['zss','lss','ymm'] │ 21 └──────────┴─────────────────────┘ 22 23 1 rows in set. Elapsed: 0.008 sec. 24 25 master :)4.9、元組,Tuple(T1, T2, ...):元組,其中每個(gè)元素都有單獨(dú)的類型。
Tuple元組數(shù)據(jù)類型,是一個(gè)特殊的數(shù)據(jù)類型,可以理解為集合,可以存儲(chǔ)任意的數(shù)據(jù)類型,這一點(diǎn)區(qū)別于數(shù)組。在定義的時(shí)候需要聲明數(shù)據(jù)類型和數(shù)據(jù)元素的個(gè)數(shù)。
數(shù)據(jù)類型由1~n個(gè)元素組成,每個(gè)元素之間允許設(shè)置不同的數(shù)據(jù)類型,且彼此之間不要求兼容。元素同樣支持類型推斷,其推斷依據(jù)仍然以最小存儲(chǔ)代價(jià)為原則。與數(shù)據(jù)類型,元組也可以使用兩種方式定義,常規(guī)方式是tuple(T),元組中可以存儲(chǔ)多種數(shù)據(jù)類型,但是要注意數(shù)據(jù)類型的順序。
使用案例,如下所示:
1 master :) 2 master :) SELECT tuple(1,'a') AS x, toTypeName(x); # SELECT tuple(1,'a',12.23)可以簡(jiǎn)寫為SELECT (1,'a',12.23)3 4 SELECT 5 (1, 'a') AS x,6 toTypeName(x)7 8 ┌─x───────┬─toTypeName(tuple(1, 'a'))─┐9 │ (1,'a') │ Tuple(UInt8, String) │ 10 └─────────┴───────────────────────────┘ 11 12 1 rows in set. Elapsed: 0.008 sec. 13 14 master :)注意:創(chuàng)建數(shù)據(jù)表的時(shí)候使用元組的時(shí)候,需要指定元素的數(shù)據(jù)類型。
1 master :) 2 master :) CREATE TABLE tb_tuple3 :-] (4 :-] `id` UInt8,5 :-] `t1` Tuple(String,Int8,Date) 6 :-] )ENGINE = Log;7 8 CREATE TABLE tb_tuple9 ( 10 `id` UInt8, 11 `t1` Tuple(String, Int8, Date) 12 ) 13 ENGINE = Log 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.066 sec. 18 19 master :) insert into tb_tuple values(1, ('red',25,'1994-05-18')); 20 21 INSERT INTO tb_tuple VALUES 22 23 Ok. 24 25 1 rows in set. Elapsed: 0.145 sec. 26 27 master :) select * from tb_tuple; 28 29 SELECT * 30 FROM tb_tuple 31 32 ┌─id─┬─t1──────────────────────┐ 33 │ 1 │ ('red',25,'1994-05-18') │ 34 └────┴─────────────────────────┘ 35 36 1 rows in set. Elapsed: 0.033 sec. 37 38 master :)4.10、Date日期類型、DateTime日期時(shí)間類型,支持符合格式的字符串類型的插入。
DateTime64可以記錄亞秒,它在DateTime之上增加了精度的設(shè)置,在指定數(shù)據(jù)類型的時(shí)候可以使用DateTime64(2)指定兩位精度。
1 master :) 2 master :) CREATE TABLE tb_name3 :-] (4 :-] `id` UInt8,5 :-] `age` UInt8,6 :-] `birthday` Date,7 :-] `updateTime` DateTime8 :-] )ENGINE = Log;9 10 CREATE TABLE tb_name 11 ( 12 `id` UInt8, 13 `age` UInt8, 14 `birthday` Date, 15 `updateTime` DateTime 16 ) 17 ENGINE = Log 18 19 Ok. 20 21 0 rows in set. Elapsed: 0.055 sec. 22 23 master :) 24 master :) insert into tb_name values(1,22,'1994-05-16','2021-02-20 14:21:30'),(2,24,'1994-05-17','2021-02-20 14:21:30'); 25 26 INSERT INTO tb_name VALUES 27 28 Ok. 29 30 2 rows in set. Elapsed: 0.065 sec. 31 32 master :) select * from tb_name; 33 34 SELECT * 35 FROM tb_name 36 37 ┌─id─┬─age─┬───birthday─┬──────────updateTime─┐ 38 │ 1 │ 22 │ 1994-05-16 │ 2021-02-20 14:21:30 │ 39 │ 2 │ 24 │ 1994-05-17 │ 2021-02-20 14:21:30 │ 40 └────┴─────┴────────────┴─────────────────────┘ 41 42 2 rows in set. Elapsed: 0.010 sec. 43 44 master :)4.11、Enum枚舉類型,Clickhouse支持枚舉類型,這是一種在定義常量的時(shí)候經(jīng)常會(huì)使用的數(shù)據(jù)類型,Clickhouse提供了Enum8和Enum16兩種枚舉類型,他們除了取值范圍不同之外,別無二致。枚舉固定使用(String:Int),這種Key/Value鍵值對(duì)的行式定義數(shù)據(jù),所以Enum8和Enum16分別會(huì)對(duì)應(yīng)(String:Int8)和(String:Int16)。
1 master :) 2 master :) CREATE TABLE tb_enum3 :-] (4 :-] `id` UInt8,5 :-] `color` Enum('red' = 1,'green' = 2, 'blue' = 3)6 :-] )ENGINE = Log;7 8 CREATE TABLE tb_enum9 ( 10 `id` UInt8, 11 `color` Enum('red' = 1, 'green' = 2, 'blue' = 3) 12 ) 13 ENGINE = Log 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.034 sec. 18 19 master :) insert into tb_enum values(1,'red'),(2,'green'),(3,'blue'); 20 21 INSERT INTO tb_enum VALUES 22 23 Ok. 24 25 3 rows in set. Elapsed: 0.055 sec. 26 27 master :) insert into tb_enum values(4,1),(5,2),(6,3); 28 29 INSERT INTO tb_enum VALUES 30 31 Ok. 32 33 3 rows in set. Elapsed: 0.035 sec. 34 35 master :)4.12、Domain(pojo、beans實(shí)體類)里面的IPv4數(shù)據(jù)類型,域名分為IPv4和IPv6兩類,本質(zhì)上它們是對(duì)整數(shù)和字符串的進(jìn)一步封裝,其中IPv4類型是基于UInt32封裝的。
1)、出于便捷性的考量,例如IPv4類型支持格式檢查,格式錯(cuò)誤的IP數(shù)據(jù)是無法被寫入的。
2)、出于性能的考量,同樣以IPv4為例,IPv4使用UInt32存儲(chǔ),相對(duì)String更加緊湊,占用空間更小,查詢性能更快。IPv6類型是基于FixedString(16)封裝的,它的使用彷佛與IPv4別無二致,在使用Domain類型的時(shí)候還有一點(diǎn)需要注意,雖然它從表象上看起來與String一樣,但是Domain類型并不是字符串,所以它不支持隱式的自動(dòng)類型轉(zhuǎn)換。如果需要返回IP的字符串行式,需要顯示調(diào)用IPv4NumToString或者IPv6NumToString函數(shù)進(jìn)行轉(zhuǎn)換。
1 master :) 2 master :) CREATE TABLE tb_domin3 :-] (4 :-] `id` UInt8,5 :-] `ip` IPv46 :-] )ENGINE = Log;7 8 CREATE TABLE tb_domin9 ( 10 `id` UInt8, 11 `ip` IPv4 12 ) 13 ENGINE = Log 14 15 Ok. 16 17 0 rows in set. Elapsed: 0.024 sec. 18 19 master :) insert into tb_domin values(1, '192.168.110.133'); 20 21 INSERT INTO tb_domin VALUES 22 23 Ok. 24 25 1 rows in set. Elapsed: 0.058 sec. 26 27 master :) insert into tb_domin values(1, '192.168.110.133'); 28 29 INSERT INTO tb_domin VALUES 30 31 Ok. 32 33 1 rows in set. Elapsed: 0.006 sec. 34 35 master :) select * from tb_domin; 36 37 SELECT * 38 FROM tb_domin 39 40 ┌─id─┬──────────────ip─┐ 41 │ 1 │ 192.168.110.133 │ 42 └────┴─────────────────┘ 43 ┌─id─┬──────────────ip─┐ 44 │ 1 │ 192.168.110.133 │ 45 └────┴─────────────────┘ 46 47 2 rows in set. Elapsed: 0.025 sec. 48 49 master :)?
5、Clickhouse為什么可以這么快?主要特點(diǎn),如下所示:
1)、開發(fā)語言是C++,可以更好的利用硬件優(yōu)勢(shì)來提升數(shù)據(jù)處理的效率。
2)、摒棄了hadoop生態(tài)體系。
3)、數(shù)據(jù)底層以列式數(shù)據(jù)存儲(chǔ)。
4)、可以利用單節(jié)點(diǎn)的多核并行處理。
5)、為數(shù)據(jù)建立索引,分為一級(jí)索引、二級(jí)索引、稀疏索引。
6)、使用大量高效率算法處理數(shù)據(jù)。
7)、支持向量化處理數(shù)據(jù)。
8)、支持預(yù)先運(yùn)算模型,預(yù)先計(jì)算,等等優(yōu)勢(shì)。
?
6、Clickhouse的引擎分為數(shù)據(jù)庫(kù)引擎和數(shù)據(jù)表引擎,數(shù)據(jù)表的引擎,不同的引擎決定數(shù)據(jù)庫(kù)的類型,Clickhouse的數(shù)據(jù)庫(kù)引擎的作用。
1)、引擎決定了數(shù)據(jù)存儲(chǔ)位置。
2)、數(shù)據(jù)組織結(jié)構(gòu)。
3)、是否分塊、是否索引、是否持久化操作。
4)、是否可以并發(fā)讀寫。
5)、是否支持副本操作、是否支持索引。
6)、是否支持分布式。
?
7、Clickhouse的數(shù)據(jù)表引擎(即表的類型)決定了的特征,如下所示:
1)、數(shù)據(jù)的存儲(chǔ)方式和位置,寫到哪里以及從那里讀取數(shù)據(jù)。
2)、支持那些查詢以及如何支持。
3)、并發(fā)數(shù)據(jù)訪問。
4)、索引的使用(如果存在)。
5)、是否可以執(zhí)行多線程請(qǐng)求。
6)、數(shù)據(jù)復(fù)制參數(shù)。在讀取時(shí)候,引擎只需要輸出所請(qǐng)求的列,但在某些情況下,引擎可以在響應(yīng)請(qǐng)求時(shí)部分處理數(shù)據(jù)。對(duì)于大多數(shù)正式的任務(wù),應(yīng)該使用MergeTree族中的引擎。
?
8、數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)起到了命名空間的作用,可以有效規(guī)避命名沖突的問題,也是為后續(xù)的數(shù)據(jù)隔離提供了支撐。任何一張數(shù)據(jù)表,都必須歸屬在某個(gè)數(shù)據(jù)庫(kù)之下。在Clickhouse中數(shù)據(jù)庫(kù)也有自己的引擎,數(shù)據(jù)庫(kù)目前支持的數(shù)據(jù)庫(kù)引擎有6種,如下所示:
1)、Ordinary,默認(rèn)引擎,在絕大多數(shù)情況下我們都會(huì)使用默認(rèn)引擎,使用的時(shí)候無須刻意聲明。在此數(shù)據(jù)庫(kù)下可以使用任意類型的表引擎。
2)、Dictionary,字段引擎,此類數(shù)據(jù)庫(kù)會(huì)自動(dòng)為所有數(shù)據(jù)字典創(chuàng)建它們的數(shù)據(jù)表。
3)、Memory,內(nèi)存引擎,了解即可,用于存放臨時(shí)數(shù)據(jù),此類數(shù)據(jù)庫(kù)下的數(shù)據(jù)表只會(huì)停留在內(nèi)存中,不會(huì)設(shè)計(jì)任何磁盤操作,當(dāng)服務(wù)重啟后數(shù)據(jù)會(huì)被清除。
4)、Lazy,日志引擎,此類數(shù)據(jù)庫(kù)下只能使用Log系列的表引擎。
5)、Mysql,Mysql數(shù)據(jù)庫(kù)的引擎,此類數(shù)據(jù)庫(kù)下會(huì)自動(dòng)拉取遠(yuǎn)端Mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù),并為他們創(chuàng)建Mysql表引擎的數(shù)據(jù)表。
6)、MaterializeMySQL,主要做Mysql的數(shù)據(jù)同步,Clickhouse 20.8將新增 MaterializeMySQL引擎 ,可通過binlog日志實(shí)時(shí)物化mysql數(shù)據(jù),極大提升了數(shù)倉(cāng)的查詢性能和數(shù)據(jù)同步的時(shí)效性;原有mysql中承擔(dān)的數(shù)據(jù)分析工作 可交由clickhouse去做,這么做可顯著降低線上mysql的負(fù)載,從此OLTP與OLAP業(yè)務(wù)實(shí)現(xiàn)完美融合。
?
9、Clickhouse的數(shù)據(jù)表引擎,具體分類,如下所示:
9.1)、Log日志引擎,具有最小功能的輕量級(jí)引擎。當(dāng)您需要快速寫入許多小表(最多約100萬行)并在以后整體讀取它們時(shí),該類型的引擎是最有效的。具體表現(xiàn)為,比較簡(jiǎn)單,數(shù)據(jù)少,測(cè)試使用,Log家族都屬于本地表(在/var/lib/clickhouse/data下面),本地存儲(chǔ)表數(shù)據(jù)。
1)、TinyLog引擎(數(shù)據(jù)不分快)。最簡(jiǎn)單的數(shù)據(jù)表引擎,用于將數(shù)據(jù)存儲(chǔ)在磁盤上。每列都存儲(chǔ)在單獨(dú)的壓縮文件中,寫入的時(shí)候,數(shù)據(jù)將附加到文件末尾。該引擎沒有并發(fā)控制,只支持并發(fā)讀。如果同時(shí)從表中讀取和寫入數(shù)據(jù),則讀取操作將拋出異常。如果同時(shí)寫入多個(gè)查詢中的表,則數(shù)據(jù)將被破壞。
注意:TinyLog引擎(數(shù)據(jù)不分快)引擎,*.bin每個(gè)字段的壓縮數(shù)據(jù),數(shù)據(jù)插入時(shí)會(huì)進(jìn)行追加數(shù)據(jù)。sizes.json文件,顯示每個(gè)字段文件的大小。該引擎的特點(diǎn),沒有數(shù)據(jù)塊,不能并行操作,不能同時(shí)讀寫操作,沒有索引,寫是追加寫,數(shù)據(jù)以列字段文件存儲(chǔ)。
1 master :) 2 master :) 3 master :) CREATE TABLE tb_tinyLog4 :-] (5 :-] `id` UInt8,6 :-] `log_name` String7 :-] )ENGINE = TinyLog;8 9 CREATE TABLE tb_tinyLog 10 ( 11 `id` UInt8, 12 `log_name` String 13 ) 14 ENGINE = TinyLog 15 16 Ok. 17 18 0 rows in set. Elapsed: 0.016 sec. 19 20 master :) insert into tb_tinyLog values(1, '張三三'); 21 22 INSERT INTO tb_tinyLog VALUES 23 24 Ok. 25 26 1 rows in set. Elapsed: 0.027 sec. 27 28 master :) select * from tb_tinyLog; 29 30 SELECT * 31 FROM tb_tinyLog 32 33 ┌─id─┬─log_name─┐ 34 │ 1 │ 張三三 │ 35 └────┴──────────┘ 36 37 1 rows in set. Elapsed: 0.010 sec. 38 39 master :)2)、StripeLog引擎,數(shù)據(jù)分塊列在一起,在你需要寫入許多小數(shù)據(jù)量(小于一百萬行)的表的場(chǎng)景下使用這個(gè)引擎。
3)、Log引擎。
9.2)、MergeTree引擎,主要包含下面幾種。
1)、MergeTree()。
2)、ReplacingMergeTree。
3)、SummingMergeTree引擎,將相同主鍵的數(shù)據(jù)分區(qū)內(nèi)合并指定字段進(jìn)行累加。
4)、CollapsingMergeTree,ClickHouse實(shí)現(xiàn)了CollapsingMergeTree來消除ReplacingMergeTree的限制(只刪除小版本字段的問題)。該引擎要求在建表語句中指定一個(gè)標(biāo)記列Sign,后臺(tái)Compaction時(shí)會(huì)將主鍵相同、Sign相反的行進(jìn)行折疊,也即刪除。
CollapsingMergeTree雖然解決了主鍵相同的數(shù)據(jù)即時(shí)刪除的問題,但是狀態(tài)持續(xù)變化且多線程并行寫入情況下,狀態(tài)行與取消行位置可能亂序,導(dǎo)致無法正常折疊。只有保證老的狀態(tài)行在在取消行的上面, 新的狀態(tài)行在取消行的下面,但是多線程無法保證寫的順序。
5)、VersionedCollapsingMergeTree,取消字段和數(shù)據(jù)版本同事使用,避免取消行數(shù)據(jù)無法刪除的問題,為了解決CollapsingMergeTree亂序?qū)懭肭闆r下無法正常折疊問題,VersionedCollapsingMergeTree表引擎在建表語句中新增了一列Version,用于在亂序情況下記錄狀態(tài)行與取消行的對(duì)應(yīng)關(guān)系。主鍵相同,且Version相同、Sign相反的行,在Compaction時(shí)會(huì)被刪除。與CollapsingMergeTree類似, 為了獲得正確結(jié)果,業(yè)務(wù)層需要改寫SQL,將count()、sum(col)分別改寫為sum(Sign)、sum(col * Sign)。
總結(jié)
以上是生活随笔為你收集整理的Clickhouse基础语法、数据类型、数据表引擎学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 清理入侵痕迹
- 下一篇: 看了它就能看懂心电图室大部分心电图