ClickHouse数据类型

  • 整型
  • 浮点型
  • Decimal类型
  • Boolean类型
  • 字符串类型
  • Nullable
  • 枚举类型
  • 时间类型
  • 数组类型
  • Map


整型

CK中的整型统一标记为Int,后面追加的数字表述位数
整型分为两种,有符号和无符号

数据类型

数值范围

Int8

[-128,127]

Int16

[32768 , 32767]

Int32

[2147483648 , 2147483647]

Int64

[9223372036854775808 , 9223372036854775807]

可以看到上面三种实际和Java中byte、short、int、long类型相对应

无符号类型将上述数值类型的负值范围移动到了正值部分

数据类型

数值范围

UInt8

[0 , 255]

UInt16

[0 , 65535]

UInt32

[0 , 4294967295]

UInt64

[0 , 18446744073709551615]

浮点型

浮点型分为2种:Float32和Float64(分别对应Java中的Float和Double)

由于十进制数字转为二进制存储,浮点数本身存在误差,选用该类型时需要注意

java如何连接clickhouse数据库 java clickhouse_ClickHouse

Decimal类型

有符号的浮点数,再加减和乘法运算可以保持精度。对于除法,最低有效数字会被舍弃(并非四舍五入)

有三种类型:
Decimal32(s) ,相当于Decimal(9-s,s) ,有效位数为 1~9
Decimal64(s) ,相当于Decimal(18-s,s) ,有效位数为 1~18
Decimal128(s) ,相当于Decimal(38-s,s) ,有效位数为 1~38
s标识小数位

Boolean类型

ClickHouse种没有设置单独的布尔类型,可以使用其他类型表示。例如整型中的0表示false,1表示true。

字符串类型

ClickHouse中的字符串有两种,定长和不定长
String为不定长字符串,长度任意,可以包含任意字符集,包括空字节,是最经常使用的类型
FixedString(N)为定长字符串,N为字符串长度,当存储长度小于N的字符串时,会自动在原字符串后填充空字符补齐。当存储长度大于N的字符串时,会抛出异常。
FixedString(N)相较于String存储和读取效率相对较高,但是提高的性能相较于对字符串的限定来说并不明显,因此FixedString(N)并不常用

Nullable

ClickHouse中的数值类型默认是不支持存储空值的,如果确实需要存储空值,可以使用Nullable修饰,例如可存储空值的字符串表示为:Nullable(String)。普通String直接插入null会报错。

针对空值官方提示:支持空值绝大多数情况下都会对性能造成负面影响。

因为ClickHouse中每个列都设置单独的文件存储,而空值却需要额外单独存储,另一方面,空值会影响索引的性能,降低查询速度。

因此在设计数据库时,尽可能使用无关值来代表空,而不要直接使用Nullable。例如,字符串类型使用"null"来表示null,数值类型使用-1表示null

枚举类型

包括 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’

INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello');

java如何连接clickhouse数据库 java clickhouse_大数据_02


如果尝试保存任何其他值, ClickHouse 抛出异常

insert into t_enum values('a');

java如何连接clickhouse数据库 java clickhouse_值类型_03


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

SELECT CAST(x, 'Int8') FROM t_enum;

java如何连接clickhouse数据库 java clickhouse_整型_04

时间类型

目前 ClickHouse 有三种时间类型

  • Date 接受年-月-日的字符串比如 ‘2019-12-16’
  • Datetime 接受年-月-日 时:分:秒的字符串比如 ‘2019-12-16 20:50:10’
  • Datetime64 接受年-月-日 时:分:秒.亚秒的字符串比如‘2019-12-16 20:50:10.66’

日期类型,用两个字节存储,表示从 1970-01-01 (无符号) 到当前的日期值。
还有很多数据结构,可以参考官方文档

数组类型

Array(T): 由 T 类型元素组成的数组。
T 可以是任意类型,包含数组类型。 但不推荐使用多维数组, ClickHouse 对多维数组
的支持有限。例如,不能在 MergeTree 表中存储多维数组。

创建数组方式 1, 使用 array 函数

SELECT array(1, 2) AS x, toTypeName(x) ;

java如何连接clickhouse数据库 java clickhouse_字符串_05


创建数组方式 2: 使用方括号

SELECT [1, 2] AS x, toTypeName(x);

java如何连接clickhouse数据库 java clickhouse_ClickHouse_06

Map

ClickHouse也支持Map类型,不过目前版本仍为测试功能,需要打开测试功能支持配置(Set allow_experimental_map_type = 1)才可以使用;

建表:create table table_map (a Map(String,UInt32)) Engine=Memory;

需要注意,Key的数值类型有明确的限制:

java如何连接clickhouse数据库 java clickhouse_字符串_07


当使用其他类型时:

java如何连接clickhouse数据库 java clickhouse_大数据_08

插入数值:insert into table_map values ({'k1':1,'k2':2}),({'k1':3,'k2':4});

java如何连接clickhouse数据库 java clickhouse_字符串_09


查询Map中指定Key的Value值:

java如何连接clickhouse数据库 java clickhouse_字符串_10


可以看到每行数据中都会查出一个k1对应的Value如果单行同一个Key插入多条insert into table_map values ({'k1':5,'k2':6,'k1':10});

java如何连接clickhouse数据库 java clickhouse_ClickHouse_11


最终通过Key查询每行仍然只能得到一个值