ClickHouse数据类型
整型 支持有符号和无符号的整数
-
有符号整数
Int<位数>
:称 精确范围 最大数级 对应MySQL类型 Int8 -128 ~ 127 百 Tinyint Int16 -32768 ~32767 万 Smallint Int32 -2147483648 ~ 2147483647 十亿 Int Int64 -9223372036854775808 ~ 9223372036854775807 千亿亿 Bigint -
无符号整数
UInt<位数>
:称 精确范围 最大数级 对应MySQL类型 UInt8 0 ~ 255 百 Tinyint Unsigned UInt16 0 ~ 65535 万 Smallint Unsigned UInt32 0 ~ 4294967295 十亿 Int Unsigned UInt64 0 ~ 18446744073709551615 千亿亿 Bigint Unsigned
浮点型 支持单精度和双精度的浮点数,也会有精度丢失问题
名称 | 大小(字节) | 有效精度(位数) | 对应编程语言的数据类型 |
---|---|---|---|
Float32 | 4 | 7 | Float |
Float64 | 8 | 16 | Double |
-
字符串转浮点、查看字段类型
select toFloat32('0.12345678901234567890') as f1, toFloat64('0.12345678901234567890') as f2, toTypeName(f1) as type1, toTypeName(f2) as type2 -- 结果 "f1" "f2" "type1" "type2" "0.12345679" "0.12345678901234568" "Float32" "Float64"
-
高精度的数值运算
用Decimal(P,S)来定义:
P代表精度(Precise),表示总位数(整数部分 + 小数部分),取值范围1 ~ 38。
S代表规模(Scale),表示小数位数,取值范围1 ~ P。
也可以使用Decimal32(S)、Decimal64(S)和Decimal128(S)的方式来表示。
因为现在还没有128位操作系统,所以Decimal128(S)是用软件模拟的,可能会用性能问题
字符串类型
- String
- 可变长度的字符串;
- 长度没有限制;
- 统一了关系型数据库中的Varchar、Text、Clob和Blob类型;
- String没有编码的概念(同时支持存储文本和二进制),但是建议在存储文本时用UTF-8
- FixedString
-
定长的字符串;
-
使用
FixedString(N)
,N为字符串长度 -
字符串内容不够,自动用null填充到末尾
select toFixedString('abc', 4) as s, length(s) -- 结果 "s" "length(toFixedString('abc', 4))" "abc" "4"
- UUID 什么是UUID?
- 随机生成UUID的函数
generateUUIDv4()
,默认UUID:00000000-0000-0000-0000-000000000000
select generateUUIDv4() as uuid -- 结果 "uuid" "49293f5d-fcdb-40dd-a546-1fb08275825b"
- UUID长度是36,被四个
-
分成五段,各段长度为8-4-4-4-12
时间类型
- Date 精确到天,不支持指定时区
-- 将字符串转成Date,只支持yyyy-MM-dd格式 select toDate('2020-11-02') as day1, toTypeName(day1) -- 将Datetime转成Date select toDate(now()) as day2, toTypeName(day2)
- DateTime 精确到秒,支持指定时区
-- 将字符串转成DateTime,只支持yyyy-MM-dd HH:MI:SS select toDateTime('2020-11-02 09:27:33') as day3 , toTypeName(day3) -- 支持指定时区 select toDateTime(now(), 'Asia/Yekaterinburg') as day4 , toTypeName(day4)
- DateTime64
-- 将字符串转成DateTime64,只支持yyyy-MM-dd HH:MI:SS 或 yyyy-MM-dd HH:MI:SS.SSS,示例精度为4 select toDateTime64('2020-11-02 09:27:33.1234567', 4) as day5 , toTypeName(day5) -- 支持指定时区 select toDateTime64(now(), 4, 'Asia/Yekaterinburg') as day6 , toTypeName(day6)
其他日期函数详见官网:
ClickHouse日期函数
数组、元组 存的元素是其他类型的话,那就是复合类型了
- 初始化
可明确指定Array数据类型,比如Array(UInt16)
-- 数组 select array(1, 2, 3) as arr1, toTypeName(arr1) select [1, 2, 3] as arr2, toTypeName(arr2) -- 结果 "arr1" "toTypeName(array(1, 2, 3))" "ru.yandex.clickhouse.ClickHouseArray@35721bbf" "Array(UInt8)" -- 元组 select tuple(3.14, 'pai', now()) as tup1, toTypeName(tup1) select (3.14, 'pai', now()) as tup2, toTypeName(tup2) -- 结果 "tup1" "toTypeName(tuple(3.14, 'pai', now()))" "(3.14,'pai','2021-11-03 11:14:15')" "Tuple(Float64, String, DateTime)"
- 兼容
- 数组内元素需要兼容,需要有个
Supertype
。eg:[1, 2.1 ,'zjk']
,字符串zjk就无法找到兼容导致报Supertype错 - 元组内的元素没有兼容问题,任何类型
Enum枚举 Key和Value不可重复、不为Null,但Key可为空字符串 (空和空字符串是两个概念)
Enum类型使用(String:Int
)的Key/Value
键值对的形式来定义数据。
- Enum8: 包含256个枚举值,(String :Int8),Value取值范围:-128 ~ 127
- Enum16:包含65536个枚举值,(String:Int16),Value取值范围:-32768 ~ 32767
Map
key可为String
or Integer
;
value可为String
、 Integer
or Array
。
- 创建表(设a字段类型为map类型),插入数据并查找key2的value:
CREATE TABLE table_map (a Map(String, UInt64)) ENGINE=Memory; INSERT INTO table_map VALUES ({'key1':1, 'key2':10}), ({'key1':2,'key2':20}), ({'key1':3,'key2':30}); SELECT a['key2'] FROM table_map; -- 结果 "arrayElement(a, 'key2')" "10" "20" "30"
- 使用函数转成Map
- CAST函数 以Tuple转Map为例
SELECT CAST(([1, 2, 3], ['Ready', 'Steady', 'Go']), 'Map(UInt8, String)') AS map;
- MAP函数 以
numbers(3)
生成的列表[0,1,2]为例SELECT map('key1', number, 'key2', number * 2) FROM numbers(3); -- 结果 "map('key1', number, 'key2', multiply(number, 2))" "{'key1':0,'key2':0}" "{'key1':1,'key2':2}" "{'key1':2,'key2':4}"
极值
-
正无穷:
Infinity
select 2/0 -- 结果 "divide(2, 0)" "Infinity"
-
负无穷:
-Infinity
select -2/0 -- 结果 "divide(-2, 0)" "-Infinity"
-
非数字:
NaN
select 0/0 -- 结果 "divide(0, 0)" "NaN"
-
空字符串 使用
Nullable
关键字使字段可为空,可能会导致聚合性能下降
像如下建表语句create table employee ( \ name String, \ age Nullable(UInt8) ) engine = Memory;
嵌套
- 目前只支持一维嵌套
- 使用关键字
Nested
表示该字段为嵌套类型 - 嵌套字段内的字段,结构为Array格式,类型是自定义的(如下语句,id类型为
UInt8
,存储格式为[id1,id2,id3]
,name同理,不是单纯的一个String,是一个name和age对应一个teacher结构的 各字段数组,数组内数据类型为DDL时自定义的)
eg:一个学生是可以被多个老师教的,学生表的表结构可建成如下
create table student (
name String,
age UInt8,
teacher Nested (
id UInt8,
name String
)
) engine = Memory;
-- 数据select出来是类似这样的
name | age | teacher.id | teacher.name
狗剩 | 23 | ['2122','3233','2643','2128'] | ['华强','翠花','大壮','春梅']
小二 | 12 | ['3233','2643'] | ['翠花','大壮']
大头 | 24 | ['2128'] | ['春梅']
丫蛋 | 22 | [] | []
Domain
对于域类型的函数,支持将Domain类型转为字符串类型,或者字符串的IP转IpNum,更或者v4和v6互转
- 十进制表示的ipv4
IPv4NumToString(num)
、IPv4StringToNum(str)
- 十六进制的ipv6
IPv6NumToString(num)
、IPv6StringToNum(str)
IPv4ToIPv6(x)
- 其他IP函数
参考链接:
ClickHouse官方文档
阿里文档