ClickHouse屬於分析型資料庫,ClickHouse提供了許多數據類型,它們可以劃分為基礎類型、複合類型和特殊類型。其中基礎類型使ClickHouse具備了描述數據的基本能力,而另外兩種類型則使ClickHouse的數據表達能力更加豐富立體。 基礎類型 基礎類型只有數值、字元串和時間三種類型, ...
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(05)ClickHouse數據類型詳解
本文來自博客園,作者:張飛的豬,轉載請註明原文鏈接:https://www.cnblogs.com/the-pig-of-zf/p/16653568.html
作者公眾號:張飛的豬大數據分享,不定期分享大數據學習的總結和相關資料,歡迎關註。