ClickHouse屬于分析型資料庫,ClickHouse提供了許多資料型別,它們可以劃分為基礎型別、復合型別和特殊型別,其中基礎型別使ClickHouse具備了描述資料的基本能力,而另外兩種型別則使ClickHouse的資料表達能力更加豐富立體,
基礎型別
基礎型別只有數值、字串和時間三種型別,沒有Boolean型別,但可以使用整型的0或1替代,
數值型別
數值型別分為整數、浮點數和定點數三類,接下來分別進行說明,
Int
在普遍觀念中,常用Tinyint、Smallint、Int和Bigint指代整數的不同取值范圍,而ClickHouse則直接使用Int8、Int16、Int32和Int64指代4種大小的Int型別,其末尾的數字正好表明了占用位元組的大小(8位=1位元組),


Float
與整數類似,ClickHouse直接使用Float32和Float64代表單精度浮點數以及雙精度浮點數,在使用浮點數的時候,要意識到它是有限精度的,對Float32和Float64寫入超過有效精度的數值,結果就會出現資料誤差,會被截斷,

另外,ClickHousae對于正無窮、負無窮、以及非數值型別的表示,
- 正無窮:inf
- 負無窮:-inf
- 非數值型別:
Decimal
要更高精度的數值運算,需要使用定點數,ClickHouse提供了Decimal32、Decimal64和Decimal128三種精度的定點數,可以通過兩種形式宣告定點:簡寫方式有Decimal32(S)、Decimal64(S)、Decimal128(S)三種,原生方式為Decimal(P,S),其中:
- P代表精度,決定總位數(整數部分+小數部分),取值范圍是1~38;
- S代表規模,決定小數位數,取值范圍是0~P,

字串型別
字串型別可以細分為String、FixedString和UUID三類,
String
字串由String定義,長度不限,因此在使用String的時候無須宣告大小,它完全代替了傳統意義上資料庫的Varchar、Text、Clob和Blob等字符型別,String型別不限定字符集,因為它根本就沒有這個概念,所以可以將任意編碼的字串存入其中,
FixedString
FixedString型別和傳統意義上的Char型別有些類似,對于一些字符有明確長度的場合,可以使用固定長度的字串,定長字串通過FixedString(N)宣告,其中N表示字串長度,但與Char不同的是,FixedString使用null位元組填充末尾字符,而Char通常使用空格填充,比如在下面的例子中,字串‘abc’雖然只有3位,但長度卻是5,因為末尾有2位空字符填充,
UUID
UUID是一種資料庫常見的主鍵型別,在ClickHouse中直接把它作為一種資料型別,UUID共有32位,它的格式為8-4-4-4-12,如果一個UUID型別的欄位在寫入資料時沒有被賦值,則會依照格式使用0填充,
時間型別
時間型別分為DateTime、DateTime64和Date三類,ClickHouse目前沒有時間戳型別,時間型別最高的精度是秒,也就是說,如果需要處理毫秒、微秒等大于秒解析度的時間,則只能借助UInt型別實作,
DateTime
DateTime型別包含時、分、秒資訊,精確到秒,
DateTime64
DateTime64可以記錄亞秒,它在DateTime之上增加了精度的設定,
Date
Date型別不包含具體的時間資訊,只精確到天,
復合型別
ClickHouse還提供了陣列、元組、列舉和嵌套四類復合型別,
陣列Array
陣列有兩種定義形式,常規方式array(T),或者簡寫方式[T],在同一個陣列內可以包含多種資料型別,例如陣列[1,2.0]是可行的,但各型別之間必須兼容,例如陣列[1,'2']則會報錯,
在查詢時并不需要主動宣告陣列的元素型別,因為ClickHouse的陣列擁有型別推斷的能力,推斷依據:以最小存盤代價為原則,即使用最小可表達的資料型別,
--常規定義方式
SELECT array(1, 2) as a , toTypeName(a)
┌─a───┬─toTypeName(array(1, 2))─┐
│ [1,2] │ Array(UInt8) │
└─────┴────────────────┘
--簡寫定義方式
SELECT [1, 2]
--建表時資料型別定義
CREATE TABLE Array_TEST (
c1 Array(String)
) engine = Memory
元組Tuple
元組型別由1~n個元素組成,每個元素之間允許設定不同的資料型別,且彼此之間不要求兼容,元組同樣支持型別推斷,其推斷依據仍然以最小存盤代價為原則,與陣列類似,元組也可以使用兩種方式定義,常規方式tuple(T),或者簡寫方式(T),
--常規定義方式
SELECT tuple(1,'a',now()) AS x, toTypeName(x)
┌─x─────────────────┬─toTypeName(tuple(1, 'a', now()))─┐
│ (1,'a','2019-08-28 21:36:32') │ Tuple(UInt8, String, DateTime) │
└───────────────────┴─────────────────────┘
--簡寫定義方式
SELECT (1,'a',now()) AS x, toTypeName(x)
┌─x─────────────────┬─toTypeName(tuple(1, 'a', now()))─┐
│ (1,'a','2019-08-28 21:36:32') │ Tuple(UInt8, String, DateTime) │
└───────────────────┴─────────────────────┘
--建表時元組型別定義
CREATE TABLE Array_TEST (
c1 Array(String)
) engine = Memory
列舉Enum
ClickHouse支持列舉型別,這是一種在定義常量時經常會使用的資料型別,ClickHouse提供了Enum8和Enum16兩種列舉型別,它們除了取值范圍不同之外,別無二致,列舉固定使用(String:Int)Key/Value鍵值對的形式定義資料,所以Enum8和Enum16分別會對應(String:Int8)和(String:Int16),
在定義列舉集合的時候,有幾點需要注意,首先,Key和Value是不允許重復的,要保證唯一性,其次,Key和Value的值都不能為Null,但Key允許是空字串,在寫入列舉資料的時候,只會用到Key字串部分,
資料在寫入的程序中,會對照列舉集合項的內容逐一檢查,如果Key字串不在集合范圍內則會拋出例外,
為什么還需要專門的列舉型別呢?這是出于性能的考慮,因為列舉定義中的Key屬于String型別,但在后續對列舉的所有操作中(包括排序、分組、去重、過濾等),會使用Int型別的Value值,
--列舉型別定義
CREATE TABLE Enum_TEST (
c1 Enum8('ready' = 1, 'start' = 2, 'success' = 3, 'error' = 4)
) ENGINE = Memory;
--列舉型別插入
INSERT INTO Enum_TEST VALUES('ready');
INSERT INTO Enum_TEST VALUES('start');
嵌套Nested
嵌套型別,顧名思義是一種嵌套表結構,一張資料表,可以定義任意多個嵌套型別欄位,但每個欄位的嵌套層級只支持一級,即嵌套表內不能繼續使用嵌套型別,對于簡單場景的層級關系或關聯關系,使用嵌套型別也是一種不錯的選擇,
--創建Nested陳述句
CREATE TABLE nested_test (
name String,
age UInt8 ,
dept Nested(
id UInt8,
name String
)
) ENGINE = Memory;
ClickHouse的嵌套型別和傳統的嵌套型別不相同,導致在初次接觸它的時候會讓人十分困惑,以上面這張表為例,如果按照它的字面意思來理解,會很容易理解成nested_test與dept是一對一的包含關系,其實這是錯誤的,
嵌套型別本質是一種多維陣列的結構,嵌套表中的每個欄位都是一個陣列,并且行與行之間陣列的長度無須對齊,在同一行資料內每個陣列欄位的長度必須相等,
插入資料時候每一個nestd欄位要需要一個陣列,
--插入資料
INSERT INTO nested_test VALUES ('bruce' , 30 , [10000,10001,10002], ['研發部','技術支持中心','測驗部']);
--行與行之間,陣列長度無須對齊
INSERT INTO nested_test VALUES ('bruce' , 30 , [10000,10001], ['研發部','技術支持中心']);
--查詢資料
SELECT name, dept.id, dept.name FROM nested_test
┌─name─┬─dept.id──┬─dept.name─────────────┐
│ bruce │ [16,17,18] │ ['研發部','技術支持中心','測驗部'] │
└────┴───────┴────────────────────┘
特殊資料型別
Nullable
Nullable并不能算是一種獨立的資料型別,它更像是一種輔助的修飾符,需要與基礎資料型別一起搭配使用,Nullable型別與Java8的Optional物件有些相似,它表示某個基礎資料型別可以是Null值,
CREATE TABLE Null_TEST (
c1 String,
c2 Nullable(UInt8)
) ENGINE = TinyLog;
--通過Nullable修飾后c2欄位可以被寫入Null值:
INSERT INTO Null_TEST VALUES ('nauu',null)
INSERT INTO Null_TEST VALUES ('bruce',20)
SELECT c1 , c2 ,toTypeName(c2) FROM Null_TEST
┌─c1───┬───c2─┬─toTypeName(c2)─┐
│ nauu │ NULL │ Nullable(UInt8) │
│ bruce │ 20 │ Nullable(UInt8) │
└─────┴──────┴───────────┘
Domain
域名型別分為IPv4和IPv6兩類,本質上它們是對整型和字串的進一步封裝,IPv4型別是基于UInt32封裝的,
ClickHouse相關資料分享
ClickHouse經典中文檔案分享
參考文章
ClickHouse(05)ClickHouse資料型別詳解
本文來自博客園,作者:張飛的豬,轉載請注明原文鏈接:https://www.cnblogs.com/the-pig-of-zf/p/16653568.html
作者公眾號:張飛的豬大資料分享,不定期分享大資料學習的總結和相關資料,歡迎關注,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/503566.html
標籤:大數據
上一篇:SQL中的排座位問題
下一篇:簡析XDP的重定向機制
