7 ClickHouse 的常用數據類型
7.1 UUID
通用唯一標識符(UUID)是用於標識記錄的16字節數。
UUID類型值的示例如下所示:
61f0c404-5cb3-11e7-907b-a6006ad3dba0
7.2 Decimal
Decimal(P,S),Decimal32(S),Decimal64(S),Decimal128(S)
有符號的定點數,可在加、減和乘法運算過程中保持精度。對於除法,最低有效數字會被丟棄(不舍入)。
參數:
- P - 精度。有效范圍:[1:38],決定可以有多少個十進制數字(包括分數)。
- S - 規模。有效范圍:[0:P],決定數字的小數部分中包含的小數位數。
對於不同的 P 參數值 Decimal(P, S) 和以下例子是同義的:
-P從[1:9],對於Decimal32(S)
-P從[10:18],對於Decimal64(小號)
-P從[19:38],對於Decimal128(S)
Decimal值的范圍:
- Decimal32(S) - ( -1 * 10^(9 - S),1*10^(9-S) )
- Decimal64(S) - ( -1 * 10^(18 - S),1*10^(18-S) )
- Decimal128(S) - ( -1 * 10^(38 - S),1*10^(38-S) )
例如,Decimal32(4) 可以表示 -99999.9999 至 99999.9999 的數值,步長為0.0001。
7.3 Float32, Float64
浮點數,類型與以下 C 語言中類型是相同的:
- Float32 - float
- Float64 - double
我們建議您盡可能以整數形式存儲數據。例如,將固定精度的數字轉換為整數值,例如貨幣數量或頁面加載時間用毫秒為單位表示
7.4 UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
固定長度的整型,包括有符號整型或無符號整型。
整型范圍:
- Int8-[-128:127]
- Int16-[-32768:32767]
- Int32-[-2147483648:2147483647]
- Int64-[-9223372036854775808:9223372036854775807]
無符號整型范圍:
- UInt8-[0:255]
- UInt16-[0:65535]
- UInt32-[0:4294967295]
- UInt64-[0:18446744073709551615]
7.5 Tuple(T1, T2, …)
元組,其中每個元素都有單獨的類型。
不能作為字段類型(除了內存表)。它們可以用於臨時列分組。在查詢中,IN 表達式和帶特定參數的 lambda 函數可以來對臨時列進行分組。更多信息,請參閱 IN 操作符和 高階函數。
元組可以是查詢的結果。在這種情況下,對於JSON以外的文本格式,括號中的值是逗號分隔的。在JSON格式中,元組作為數組輸出(在方括號中)。
可以使用函數來創建元組:
tuple(T1, T2, ...)
創建元組的示例:
node01 :) SELECT tuple(1,'a') AS x, toTypeName(x)
SELECT
(1, 'a') AS x,
toTypeName(x)
┌─x───────┬─toTypeName(tuple(1, 'a'))─┐
│ (1,'a') │ Tuple(UInt8, String) │
└─────────┴───────────────────────────┘
1 rows in set. Elapsed: 0.021 sec.
7.6 Enum
包含命名值的枚舉類型。
命名值必須聲明為 'string' = integer 對。ClickHouse僅存儲數字,但支持通過其名稱使用值進行運算。
ClickHouse支持:
8位Enum。它最多可以包含該 [-128, 127] 范圍內列舉的256個值。
16位Enum。它最多可以包含該 [-32768, 32767] 范圍內列舉的65536個值。
ClickHouse會自動選擇Enum插入數據的類型。您也可以使用Enum8或輸入Enum16以確保存儲大小。
用法示例:
創建一個帶有一個枚舉 Enum8('hello' = 1, 'world' = 2) 類型的列:
CREATE TABLE t_enum
(
x Enum8('hello' = 1, 'world' = 2)
)
ENGINE = TinyLog
這個 x 列只能存儲類型定義中列出的值:'hello'或'world'。如果您嘗試保存任何其他值,ClickHouse 拋出異常。
INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello');
Ok.
insert into t_enum values('a');
Exception on client:
Code: 49. DB::Exception: Unknown element 'a' for type Enum('hello' = 1, 'world' = 2)
7.7 Nullable(typename)
允許用特殊標記 (NULL) 表示”缺失值”,可以與 TypeName 的正常值存放一起。例如,Nullable(Int8) 類型的列可以存儲 Int8 類型值,而沒有值的行將存儲 NULL。
對於 TypeName,不能使用復合數據類型 陣列 和 元組。復合數據類型可以包含 Nullable 類型值,例如Array(Nullable(Int8))。
Nullable 類型字段不能包含在表索引中。
除非在 ClickHouse 服務器配置中另有說明,否則 NULL 是任何 Nullable 類型的默認值。
存儲特性:
要在表的列中存儲 Nullable 類型值,ClickHouse 除了使用帶有值的普通文件外,還使用帶有 NULL 掩碼的單獨文件。 掩碼文件中的條目允許 ClickHouse 區分每個表行的 NULL和相應數據類型的默認值。 由於附加了新文件,Nullable 列與類似的普通文件相比消耗額外的存儲空間。
注意點:
使用 Nullable 幾乎總是對性能產生負面影響,在設計數據庫時請記住這一點
掩碼文件中的條目允許ClickHouse區分每個表行的對應數據類型的«NULL»和默認值由於有額外的文件,«Nullable»列比普通列消耗更多的存儲空間
用法示例:
CREATE TABLE t_null(x Int8, y Nullable(Int8)) ENGINE TinyLog
7.8 Fixedstring(N)
固定長度 為N 的字符串(N 必須是嚴格的正整數)。
您可以使用下面的語法對列聲明為FixedString類型:
<column_name> FixedString(N)
其中N表示自然數。
當數據的長度恰好為N個字節時,FixedString類型是高效的。 在其他情況下,這可能會降低效率。
可以有效存儲在FixedString類型的列中的值的示例:
- 二進制表示的IP地址(IPv6使用FixedString(16))
- 語言代碼(ru_RU, en_US … )
- 貨幣代碼(USD, RUB … )
- 二進制表示的哈希值(MD5使用FixedString(16),SHA256使用FixedString(32))
請使用UUID數據類型來存儲UUID值。
當向ClickHouse中插入數據時,
- 如果字符串包含的字節數少於N,將對字符串末尾進行空字節填充。
- 如果字符串包含的字節數大於N,將拋出Too large value for FixedString(N)異常。
當做數據查詢時,ClickHouse不會刪除字符串末尾的空字節。 如果使用WHERE子句,則須要手動添加空字節以匹配FixedString的值。 以下示例闡明了如何將WHERE子句與FixedString一起使用。
7.9 String
字符串可以任意長度的。它可以包含任意的字節集,包含空字節。因此,字符串類型可以代替其他 DBMSs 中的 VARCHAR、BLOB、CLOB 等類型。
7.10 Boolean
沒有單獨的類型來存儲布爾值。可以使用 UInt8 類型,取值限制為 0 或 1。
7.11 Datetime64
允許存儲時間時刻,可以表示為日歷日期和一天中的時間,具有定義的亞秒精度。
精度: 10-precision 秒
語法:
DateTime64(precision, [timezone])
在內部,存儲數據作為一些 ‘ticks’ 自紀元開始(1970-01-01 00:00:00UTC)作為Int64. 刻度分辨率由precision參數確定。 此外,該 DateTime64 類型可以存儲時區是相同的整個列,影響如何的值 DateTime64 類型值以文本格式顯示,以及如何解析指定為字符串的值 (‘2020-01-01 05:00:01.000’). 時區不存儲在表的行中(或resultset中),而是存儲在列元數據中。
7.12 Date
日期類型,用兩個字節存儲,表示從 1970-01-01 (無符號) 到當前的日期值。允許存儲從 Unix 紀元開始到編譯階段定義的上限閾值常量(目前上限是2106年,但最終完全支持的年份為2105)。最小值輸出為1970-01-01。
示例:
CREATE TABLE dt
(
`timestamp` Date,
`event_id` UInt8
)
ENGINE = TinyLog;
INSERT INTO dt Values (1546300800, 1), ('2019-01-01', 2);
7.13 DateTime
時間戳類型。用四個字節(無符號的)存儲 Unix 時間戳)。允許存儲與日期類型相同的范圍內的值。最小值為 1970-01-01 00:00:00。時間戳類型值精確到秒(沒有閏秒)
示例:
CREATE TABLE dt
(
`timestamp` DateTime('Europe/Moscow'),
`event_id` UInt8
)
ENGINE = TinyLog;
INSERT INTO dt Values (1546300800, 1), ('2019-01-01 00:00:00', 2);
7.14 LowCardinality(Low Cardinality data type)
把其它數據類型轉變為字典編碼類型。
語法:
LowCardinality(data_type)
LowCardinality 是一種改變數據存儲和數據處理方法的概念。 ClickHouse會把 LowCardinality 所在的列進行字典編碼。對很多應用來說,處理字典編碼的數據可以顯著的增加SELECT查詢速度。
7.15 Domain
Domain類型是特定實現的類型,它總是與某個現存的基礎類型保持二進制兼容的同時添加一些額外的特性,以能夠在維持磁盤數據不變的情況下使用這些額外的特性。目前ClickHouse暫不支持自定義domain類型。
如果你可以在一個地方使用與Domain類型二進制兼容的基礎類型,那么在相同的地方您也可以使用Domain類型,例如:
使用Domain類型作為表中列的類型;
對Domain類型的列進行讀/寫數據;
如果與Domain二進制兼容的基礎類型可以作為索引,那么Domain類型也可以作為索引;
將Domain類型作為參數傳遞給函數使用;
局限性:
1. 無法通過將基本類型的索引列轉換為Domain類型ALTER TABLE。
2. 從另一列或表插入數據時,無法將字符串值隱式轉換為Domain值。
3. Domain對存儲的值不加任何限制。
下面是幾種Domain 的子類型。
IPv4
IPv4是與UInt32類型保持二進制兼容的Domain類型,其用於存儲IPv4地址的值。它提供了更為緊湊的二進制存儲的同時支持識別可讀性更加友好的輸入輸出格式。
基本用法:
CREATE TABLE hits (url String, from IPv4)
ENGINE = MergeTree() ORDER BY url;
IPv6
IPv6是與FixedString(16)類型保持二進制兼容的Domain類型,其用於存儲IPv6地址的值。它提供了更為緊湊的二進制存儲的同時支持識別可讀性更加友好的輸入輸出格式。
基本用法:
CREATE TABLE hits (url String, from IPv6)
ENGINE = MergeTree() ORDER BY url;
7.16 array(T)
由 T 類型元素組成的數組。
T 可以是任意類型,包含數組類型。 但不推薦使用多維數組,ClickHouse 對多維數組的支持有限。例如,不能存儲在 MergeTree 表中存儲多維數組。
您可以使用array函數來創建數組:
array(T)
也可以使用方括號:
[]
創建數組示例:
:) SELECT array(1, 2) AS x, toTypeName(x);
:) SELECT [1, 2] AS x, toTypeName(x);
7.17 Nested(name1 Type1, Name2 Type2, …)
嵌套的數據結構就像單元格內的表格。 嵌套數據結構的參數(列名和類型)的指定方式與CREATE TABLE查詢中的指定方式相同。 每個表行都可以對應於嵌套數據結構中的任意數量的行。
示例:
CREATE TABLE test.visits
(
CounterID UInt32,
StartDate Date,
Sign Int8,
IsNew UInt8,
VisitID UInt64,
UserID UInt64,
...
Goals Nested
(
ID UInt32,
Serial UInt32,
EventTime DateTime,
Price Int64,
OrderID String,
CurrencyID UInt32
),
...
) ENGINE = CollapsingMergeTree(StartDate, intHash32(UserID), (CounterID, StartDate, intHash32(UserID), VisitID), 8192, Sign);
此示例聲明了目標嵌套數據結構,其中包含有關轉化的數據(達到目標)。 “訪問”表中的每一行都可以對應零次或任意數量的轉化。