ClickHouse的数据类型

ClickHouse的数据类型非常丰富,在这只介绍一下常见的数据类型。更加详细的数据类型可参考官方网站https://clickhouse.tech/docs/zh/sql-reference/data-types/

整形

固定长度的类型,包括有符号整形或无符号整型。有符号整型范围(-2n-1~2n-1-1),比如Int8、Int16、Int32、Int64
无符号整型范围(0~2n-1),比如UInt8、UInt16、UInt32、UInt64。有符号和无符号最大的区别在于有符号整型是包含负数的,而无符号是不包含负数的。

浮点型

浮点型包括Float32、Float64。建议尽可能以整数形式存储数据,因为浮点型进行计算时可能引起四舍五入的误差。可以启动ClickHouse之后执行select 1-0.9;试一试,结果并不是0.1,而是0.0999999。与标准SQL相比,ClickHouse还支持以下类别的浮点数。Inf(正无穷),-Inf(负无穷),NaN(非数字)

Decimal

如果要求高精度,可以选择Decimal类型。格式:Decimal(P,S),P:代表精度,决定总位数(正数部分+小数部分),取值范围0~38;S:代表规模,决定小数位数,取值范围是0-P。ClickHouse对Decimal提供了三种类型分别为:Decimal32、Decimal64、Decimal128。

字符串

字符串(String)可以任意长度,它可以包含任意的字节集,包含空字节。FixedString(N)固定长度N的字符串,N必须是严格的正自然数。当服务端读取长度小于N的字符串时候,通过在字符串末尾添加空字节来达到N字节长度。当服务端读取长度大于N的字符串时候,将返回错误消息。
SELECT toFixedString('abc', 5),length(toFixedString('abc', 5)) as length;

UUID

ClickHouse将UUID这种在传统数据库中充当主键的类型直接做成了数据类型。例如建表语句

1
2
3
4
create table uuid_test(`c1` UUID,`c2` String)engine=Memory;
-- 插入语句
insert into uuid_test select generateUUIDv4(),'t1';
insert into uuid_test(c2) values('t2');

枚举类型

枚举类型包括Enum8和Enum16类型,Enum保存string=integer的对应关系。相关的用法如下
建表语句

1
create table t_enum(x Enum8('hello'=1,'world'=2))ENGINE=TinyLog;

这个x列只能存储类型定义中列出的值:hello或者world。如果尝试保存任何其他值,ClickHouse则抛出异常。插入语句如下:

1
2
insert into t_enum values ('hello'), ('world'), ('hello');   -- 可以执行成功
insert into t_enum values ('hellos'); -- 执行失败

如果需要看到对应行的数值,则必须将Enum值转换为整数类型。

1
select cast(x,'Int8') from t_enum;

数组

Array(T):由T类型的元素组成的数组。T可以是任意类型,包含数组类型。不推荐使用多维数组,ClickHouse对多维数组的支持有限。创建数组案例:

1
2
3
-- 数组中可以有不同的数据类型,但是需要相互兼容
select array(1,2.0) as x,toTypeName(x);
select [1, 2] as x, toTypeName(x);

在定义表字段的时候需要指明数据类型

元组

Tuple(T1,T2,…):元组,其中每个元素都有单独的类型。示例如下:

1
select tuple(1,'a') as x,toTypeName(x);

在定义表字段的时候需要指明数据类型

Date、DateTime

日期类型,用两个字节存储,表示从1970-01-01(无符号)到当前日期值。

布尔型

没有单独的类型来存储布尔值。可以使用UInt8类型,取值限制为0或者1。