ClickHouse中的数据类型
- 数据类型说明
- 数值类型
- Int
- Float
- Decimal
- 字符串类型
- String
- FixedString
- UUID
- 时间类型
- Date
- DateTime
- DateTIme64
- 复杂类型
- Array
- Enum
- Tuple
- Nested
- 特殊类型
- IPV4
- GEO
- Boolean 和 Nullable
[参考文章]:
- ClickHouse | 数据类型介绍
数据类型说明
作为一款分析型数据库,ClickHouse提供了许多数据类型,它们可以划分为基础类型、复合类型和特殊类型
其中基础类型使ClickHouse具备了描述数据的基本能力,而另外两种类型则使ClickHouse的数据表达能力更加丰富立体
基本数据类型
Mysql | Hive | ClickHouse(区分大小写) |
---|---|---|
byte | TINYINT | Int8 |
short | SMALLINT | Int16 |
int | INT | Int32 |
long | BIGINT | Int64 |
varchar | STRING | String |
timestamp | TIMESTAMP | DateTime |
float | FLOAT | Float32 |
double | DOUBLE | Float64 |
boolean | BOOLEAN | 无 |
数值类型
Int
固定长度的整型,包括有符号整型或无符号整型。
创建表时,可以为整数设置类型参数 (例如. TINYINT(8), SMALLINT(16), INT(32), BIGINT(64)), 但 ClickHouse 会忽略它们,ClickHouse使用固定长度的整型
① 整型范围
名称 | 大小 | 数值范围 | 别名 |
---|---|---|---|
Int8 | 1 | [-128 : 127] | TINYINT, BOOL, BOOLEAN, INT1 |
Int16 | 2 | [-32768 : 32767] | SMALLINT, INT2 |
Int32 | 4 | [-2147483648 : 2147483647] | INT, INT4, INTEGER |
Int64 | 8 | [-9223372036854775808 : 9223372036854775807] | BIGINT |
Int128 | - | [-170141183460469231731687303715884105728 : 170141183460469231731687303715884105727] | - |
Int256 | - | [-57896044618658097711785492504343953926634992332820282019728792003956564819968 : 57896044618658097711785492504343953926634992332820282019728792003956564819967] | - |
② 无符号整型范围(即都是正数)
名称 | 大小 | 数值范围 | 别名 |
---|---|---|---|
UInt8 | 1 | [0 : 255] | - |
UInt16 | 2 | [0 : 65535] | - |
UInt32 | 4 | [0 : 4294967295] | - |
UInt64 | 8 | [0 : 18446744073709551615] | - |
Int128 | - | [0 : 340282366920938463463374607431768211455] | - |
Int256 | - | [0 : 115792089237316195423570985008687907853269984665640564039457584007913129639935] | - |
Float
名称 | 大小 | 有效精度(位数) | 别名 |
---|---|---|---|
Float32 | 4 | 7 | Float |
Float64 | 8 | 16 | Double |
注意:以下情况会出现精度问题
-- inf(正无穷)
select 7.0/0
-- inf(负无穷)
select -7.0/0
-- nan(非数字)
select 0/0
Decimal
如果需要高精度,ClickHouse提供了 Decimal32
、Decimal64
和 Decimal128
三种精度的定点数
-- 格式
-- P代表精度,决定总位数(整数部分+小数部分),取值范围是1~38
-- S代表规模,决定小数位数,取值范围是0~P
Decimal(P,S)
-- 简写格式
Decimal32(S)
Decimal64(S)
Decimal128(S)
名称 | 等效声明 | 数值范围 |
---|---|---|
Decimal32(S) | Decimal(1~9,S) | [-1*10^(9-S) : 10^(9-S)] |
Decimal64 | Decimal(10~18,S) | [-1*10^(18-S) : 10^(9-S)] |
Decimal128 | Decimal(19~38,S) | [-1*10^(38-S) : 10^(38-S)] |
注意:在使用两个不同精度的定点数进行四则运算的时候,它们的小数点位数S会发生变化
-- 在进行加法运算时,S取最大值,S=4
toDecimal64(2,4)与toDecimal32(2,2)相加后S=4
-- 在进行减法运算时,S取最大值,S=4
toDecimal64(2,4)与toDecimal32(2,2)相减后S=4
-- 在进行乘法运算时,S取最和,S=4+2
toDecimal64(2,4)与toDecimal32(2,2)相乘后S=4+2
-- 在进行除法运算时,S取最大值,S=4(但是要保证被除数的S大于除数的S,否则会报错)
toDecimal64(2,4)与toDecimal32(2,2)相除后S=4
名称 | 规则 |
---|---|
加法 | S = max(S1,S2) |
减法 | S = max(S1,S2) |
乘法 | S = S1 + S2(S1范围 >= S2范围) |
除法 | S = S1 (S1为被除数, S1/S2) |
字符串类型
字符串类型可以细分为String、FixedString和UUID三类
从命名来看仿佛不像是由一款数据库提供的类型,反而更像是一门编程语言的设计,没错CK语法具备编程语言的特征(数据+运算)
String
字符串由String定义,长度不限,在使用String的时候无须声明大小,它完全代替了传统意义上数据库的Varchar、Text、Clob和Blob等字符类型
String类型不限定字符集,可以将任意编码的字符串存入其中
为了程序的规范性和可维护性,在同一套程序中应该遵循使用统一的编码,例如“统一保持UTF-8编码”就是一种很好的约定
FixedString
FixedString 类型和传统意义上的 Char 类型有些类似,对于一些字符有明确长度的场合,可以使用固定长度的字符串
-- FixedString 的定义格式,N表示字符串长度
FixedString(N)
注意:与 Char
不同的是,FixedString
使用 null
字节填充末尾字符,而 Char
通常使用空格填充
create table fixedstring_demo(create_date Date, mobile FixedString(11), desc String) ENGINE=TinyLog;
insert into table fixedstring_demo values(now(), '1871016', '张三');
insert into table fixedstring_demo values(now(), '18710167716111', 'lisi');
UUID
UUID 是一种数据库常见的主键类型,在ClickHouse中直接把它作为一种数据类型
注意:UUID共有32位,它的格式为 8-4-4-4-12
,如果一个UUID类型的字段在写入数据时没有被赋值,则会依照格式使用0填充
CREATE TABLE UUID_TEST (c1 UUID,c2 String) ENGINE = Memory;
--第一行UUID有值
INSERT INTO UUID_TEST SELECT generateUUIDv4(),'t1'
--第二行UUID没有值
INSERT INTO UUID_TEST(c2) VALUES('t2')
时间类型
Date
Date 类型不包含具体的时间信息,只精确到天,支持字符串形式写入:
CREATE TABLE testDate(`ct` Date)ENGINE = Memory;
-- 插入数据
insert into testDate values('2020-12-26'),(now());
DateTime
DateTime类型包含时、分、秒信息,精确到秒,支持字符串形式写入
create table testDataTime(ctime DateTime) engine=Memory ;
insert into testDataTime values('2020-12-27 01:11:12'),(now());
DateTIme64
DateTime64可以记录亚秒,它在DateTime之上增加了精度的设置
CREATE TABLE Datetime64_TEST(c1 Datetime64(2)) ENGINE = Memory;
--以字符串形式写入
INSERT INTO Datetime64_TEST VALUES('2020-06-22 00:00:00');
复杂类型
Array
ClickHouse 支持数组这种复合数据类型,数组中的数据类型需要一致
SELECT ['a','b','c'];
SELECT [1, 2, 3];
Enum
ClickHouse 支持枚举类型,这是一种在定义常量时经常会使用的数据类型
ClickHouse提供了Enum8 和Enum16两种枚举类型,它们除了取值范围不同之外,别无二致
注意:枚举固定使用 (String:Int)Key/Value
键值对的形式定义数据,所以 Enum8
和 Enum16
分别会对应(String:Int8)
和 (String:Int16)
create table test_enum(id Int8 , color Enum('red'=1 , 'green'=2 , 'blue'=3)) engine=Memory ;
insert into test_enum values(1,'red'),(1,'red'),(2,'green');
Tuple
元组类型由 1~n
个元素组成,每个元素之间允许设置不同的数据类型,且彼此之间不要求兼容
元组同样支持类型推断,其推断依据仍然以最小存储代价为原则
注意:与数组类似,元组也可以使用两种方式定义,常规方式 tuple(T)
,元组中可以存储多种数据类型,但是要注意数据类型的顺序
-- 常规定义方式
select tuple(1,'asb',12.23) as x , toTypeName(x);
-- 简写形式
SELECT (1, 'zss', 12, 1);
注意:建表的时候需要定义元组中的数据类型
CREATE TABLE Tuple_TEST (c1 Tuple(String,Int8)) ENGINE = Memory;
Nested
Nested是一种嵌套表结构
一张数据表,可以定义任意多个嵌套类型字段,但每个字段的嵌套层级只支持一级,即嵌套表内不能继续使用嵌套类型,对于简单场景的层级关系或关联关系,使用嵌套类型也是一种不错的选择
create table test_nested(id Int8, name String,props Nested(pid Int8,pnames String,pvalues String))engine=Memory;
特殊类型
IPV4
域名类型分为 IPv4
和 IPv6
两类,本质上它们是对整型和字符串的进一步封装,IPv4
类型是基于 UInt32
封装的
注意:出于便捷性的考量,例如 IPv4
类型支持格式检查,格式错误的 IP
数据是无法被写入的。IPv4
相比 String
更加紧凑,占用的空间更小,查询性能更快。IPv6
类型是基于 FixedString(16)
封装的,它的使用方法与 IPv4
别无二致, 在使用 Domain
类型的时候还有一点需要注意,虽然它从表象上看起来与String一样,但Domain类型并不是字符串,所以它不支持隐式的自动类型转换。如果需要返回IP的字符串形式,则需要显式调用 IPv4NumToString或IPv6NumToString函数进行转换
create table test_domain(id Int8 ,ip IPv4)engine=Memory ;
insert into test_domain values(1,'192.168.133.2') ;
GEO
ClickHouse 支持用于表示地理对象的数据类型
① Point 类型
SET allow_experimental_geo_types = 1;
CREATE TABLE geo_point (p Point) ENGINE = Memory();
INSERT INTO geo_point VALUES((10, 10));
SELECT p, toTypeName(p) FROM geo_point;
② Ring
CREATE TABLE geo_ring (r Ring) ENGINE = Memory();
INSERT INTO geo_ring VALUES([(0, 0), (10, 0), (10, 10), (0, 10)]);
SELECT r, toTypeName(r) FROM geo_ring;
③ Polygon
CREATE TABLE geo_polygon (pg Polygon) ENGINE = Memory();
INSERT INTO geo_polygon VALUES([[(20, 20), (50, 20), (50, 50), (20, 50)], [(30, 30), (50, 50), (50, 30)]]);
SELECT pg, toTypeName(pg) FROM geo_polygon;
Boolean 和 Nullable
ClickHouse 中没有 Boolean 类型 ,使用 1
和 0
来代表 true
和 false
Nullable 某种数据类型允许为null , 或者是没有给值的情况下模式是NULL
create table test_null(id Int8,age Int8)engine = Memory ;
create table test_null2(id Int8,age Nullable(Int8))engine = Memory ;