實時電商數倉(十八)之實時資料儲存與查詢(八) Clickhouse (三) 資料型別
資料型別
1 整型
固定長度的整型,包括有符號整型或無符號整型。
整型範圍(-2n-1~2n-1-1):
Int8 - [-128 : 127]
Int16 - [-32768 : 32767]
Int32 - [-2147483648 : 2147483647]
Int64 - [-9223372036854775808 : 9223372036854775807]
無符號整型範圍(0~2n-1):
UInt8 - [0 : 255]
UInt16 - [0 : 65535]
UInt32 - [0 : 4294967295]
UInt64 - [0 : 18446744073709551615]
使用場景: 個數、數量、也可以儲存型
2 浮點型
Float32 - float
Float64 – double
建議儘可能以整數形式儲存資料。例如,將固定精度的數字轉換為整數值,如時間用毫秒為單位表示,因為浮點型進行計算時可能引起四捨五入的誤差。
:) select 1-0.9 ┌───────minus(1, 0.9)─┐ │ 0.09999999999999998 │ └─────────────────────┘
使用場景:一般資料值比較小,不涉及大量的統計計算,精度要求不高的時候。比如儲存商品的重量。
3 布林型
沒有單獨的型別來儲存布林值。可以使用 UInt8 型別,取值限制為 0 或 1。
4 Decimal
有符號的浮點點數,可在加、減和乘法運算過程中保持精度。對於除法,最低有效數字會被丟棄(不捨入)。
有三種宣告:Decimal32(s),相當於Decimal(9-s,s)
Decimal64(s),相當於Decimal(18-s,s)
Decimal128(s),相當於Decimal(38-s,s)
s標識小數位
使用場景: 一般金額欄位、匯率、利率等欄位為了保證小數點精度,都使用Decimal進行儲存。
4 字串
1)String
字串可以任意長度的。它可以包含任意的位元組集,包含空位元組。
2)FixedString(N)
固定長度 N 的字串,N 必須是嚴格的正自然數。當服務端讀取長度小於
與String相比,極少會使用FixedString,因為使用起來不是很方便。
使用場景:名稱、文字描述、字元型編碼。 固定長度的可以儲存一些定長的內容,比如一些編碼,性別等但是考慮到一定的變化風險,帶來收益不夠明顯,所以定長字串使用意義有限。
5 列舉型別
包括 Enum8 和 Enum16 型別。Enum 儲存 'string'= integer 的對應關係。
Enum8 用 'String'= Int8 對描述。
Enum16 用 'String'= Int16 對描述。
用法演示:
建立一個帶有一個列舉 Enum8('hello' = 1, 'world' = 2) 型別的列:
CREATE TABLE t_enum ( x Enum8('hello' = 1, 'world' = 2) ) ENGINE = TinyLog
這個x列只能儲存型別定義中列出的值:'hello'或'world'。如果嘗試儲存任何其他值,ClickHouse 丟擲異常。
從表中查詢資料時,ClickHouse 從Enum中輸出字串值。
SELECT * FROM t_enum
┌─x─────┐
│ hello │
│ world │
│ hello │
└───────┘
如果需要看到對應行的數值,則必須將Enum值轉換為整數型別。
SELECT CAST(x, 'Int8') FROM t_enum ┌─CAST(x, 'Int8')─┐ │ 1 │ │ 2 │ │ 1 │ └─────────────────┘
使用場景:對一些狀態、型別的欄位算是一種空間優化,也算是一種資料約束。但是實際使用中往往因為一些資料內容的變化增加一定的維護成本,甚至是資料丟失問題。所以謹慎使用。
8 時間型別
目前clickhouse 有三種時間型別
Date 接受年-月-日 的字串比如‘2019-12-16’
Datetime 接受 年-月-日 時:分:秒的字串比如‘2019-12-16 20:50:10’
Datetime64 接受 年-月-日 時:分:秒.亞秒的字串比如‘2019-12-16 20:50:10.66’
日期型別,用兩個位元組儲存,表示從 1970-01-01 (無符號) 到當前的日期值。
還有很多資料結構,可以參考官方文件:https://clickhouse.yandex/docs/zh/data_types/
9 陣列
Array(T):由 T 型別元素組成的陣列。
T 可以是任意型別,包含陣列型別。 但不推薦使用多維陣列,ClickHouse 對多維陣列的支援有限。例如,不能在 MergeTree 表中儲存多維陣列。
可以使用array函式來建立陣列:
array(T)
也可以使用方括號:
[]
建立陣列案例:
:) SELECT array(1, 2) AS x, toTypeName(x) SELECT [1, 2] AS x, toTypeName(x) ┌─x─────┬─toTypeName(array(1, 2))─┐ │ [1,2] │ Array(UInt8) │ └───────┴─────────────────────────┘ 1 rows in set. Elapsed: 0.002 sec. :) SELECT [1, 2] AS x, toTypeName(x) SELECT [1, 2] AS x, toTypeName(x) ┌─x─────┬─toTypeName([1, 2])─┐ │ [1,2] │ Array(UInt8) │ └───────┴────────────────────┘ 1 rows in set. Elapsed: 0.002 sec.