一、数据类型
Clickhouse数据类型可以划分为三种,分别是基础类型、复合类型和特殊类型。
1. 基础类型
1.1 数值类型
1)Int
有着无符号整数和有符号整数两种。
名称 | 大小(字节) | 范围 | 普遍观念 |
Int8 | 1 | -128 到 127 | Tinyint |
Int16 | 2 | -32768 到 32767 | Smallint |
Int32 | 4 | -2147483648 到 2147483647 | Int |
Int64 | 8 | -9223372036854775808 到 9223372036854775807 | Bigint |
UInt8 | 1 | 0 到 255 | Tinyint Unsigned |
UInt16 | 2 | 0 到 65535 | Smallint Unsigned |
UInt32 | 4 | 0 到 4294967295 | Int Unsigned |
UInt64 | 8 | 0 到 18446744073709551615 | Bigint Unsigned |
2) Float
与整数相似,Clickhouse用Float32和Float64来分别表示单精度浮点数以及多精度浮点数。但是这两种浮点数都是有精度限制的,当超出精度限制它会发生精度溢出。Clickhouse中的浮点数也可以用来表示正无穷和负无穷以及非数字。
名称 | 大小(字节) | 精度范围(位数) | 普遍概念 |
Float32 | 4 | 7 | Float |
Float64 | 8 | 16 | Float |
名称 | 表达方式 | 获取方式 |
正无穷 | inf | 0.1/0 |
负无穷 | -inf | -0.1/0 |
非数字 | nan | 0/0 |
3) Decimal
Decimal的用法和Mysql中相同。方式为Decimal(P,S)
•P:总位数,范围1~38•S:小数位数,范围0~P
Clickhouse提供了简写方式Decimal32(S)、Decimal64(S)、Decimal128(S)
名称 | 等效说明 | 范围 |
Decimal32(S) | Decimal(1~9,S) | -1 * 10^(9-S) 到 1 * 10^(9-S) |
Decimal64(S) | Decimal(10~18,S) | -1 * 10^(18-S) 到 1 * 10^(18-S) |
Decimal128(S) | Decimal(19~38,S) | -1 * 10^(38-S) 到 1 * 10^(38-S) |
1.2 字符串类型
1) String
Clickhouse中String是没有长度限制的。它代替了传统数据库的varchar、Text、Clob和Blob。
2)FixedString
FixedString类似于Char,指定字符串长度确定的字符串。定长字符串通过FixedString(N)来指定字符串的长度。
3) UUID
Clickhouse中UUID作为一种数据类型,长度为32。它有着固定的格式8-4-4-4-12。当UUID没有被插入数据的时候,会用0去填充,即00000000-0000-0000-0000-000000000000
1.3 时间类型
1) DateTime
DateTime包含时、分、秒,最大的精度为秒级,例如2000-12-01 00:00:00
2) DateTime64
DateTime64的精度在DateTime之上,最大精度为亚秒级,例如2000-12-01 00:00:00.00
3) Date
Date的精度只到于天,即2000-12-01
2. 复合类型
1) Array
数组类型,有着两种定义方式,array(T)和[T]。一个数组中的字段类型需要可以兼容,否则会报错。
定义方式 | 案例 |
array(T) | select array(1,2) |
[T] | select [1,2] |
2) Tuple
元组类型,有着两种定义方式,tuple(T)和(T)。元组中字段的数据类型可以不同。
定义方式 | 案例 |
tuple(T) | select tuple(1,'a') |
(T) | select (1,'a') |
3) Enum
枚举类型,一般用于定义常量。Clickhouse中有Enum8和Enum16两种枚举类型,他们只有取值范围之差。枚举使用(String:Int)Key/Value键值对的形式定义。
•Enum8对应(String:Int8)•Enum16对应(String:int16)
Key和Value都不能重复,且都不能为Null。但是Key可以是空字符串。
4) Nested
嵌套类型,也就是嵌套表结构。举个🌰
# 创建表
CREATE TABLE nested_test(
name String,
parent Nested(
name String
)
) ENGINE = Memory;
# 插入数据的时候
INSERT INTO nested_test VALUES('zhangsan',['lisi','wangwu']);
复制
3. 特殊类型
1) Nullable
Nullable需要和基础类型搭配使用。不能用于修饰特殊类型和复杂类型。举个🌰
CREATE TABLE nullable_test(
name Nullable(String)
) ENGINE = Memory;
复制
注意:使用Nullable要特别注意,正常情况下,一个列会被存储在对应的[Column].bin文件下,如果一个列被Nullable修饰,则会多生成一个[Column].null.bin文件用于保存它的Null值。在读取和写入操作时,相当于产生了额外的IO开销。
2) Domain
域名类型分为IPv4和IPv6两种。IPv4类型是基于UInt32封装的,IPv6则是根据FixedString(16)封装的。举个🌰
# 创建表
CREATE TABLE domain_test(
ip_v4 IPv4,
ip_v6 IPv6
) ENGINE = Memory;
# 插入数据
INSERT INTO domain_test VALUES('127.0.0.1','2a02:e980:1e::1');
复制
3) LowCarditality
低基数类型,可以用于修饰出了Decimal外的基础类型。举个🌰
# 创建表
CREATE TABLE lowCarditality_test(
name LowCarditality(String)
) ENGINE = Memory;
# 插入数据
INSERT INTO lowCarditality_test VALUES('zhangsan');
复制
注意:LowCarditality适用于字段值的多样性不大的列。字典包含少于10000个不同的值,那么ClickHouse可以进行更高效的数据存储和处理。反之如果字典多于10000,效率会表现的更差。
4) AggregateFunction
聚合函数的中间状态,可以通过聚合函数名称加-State后缀的形式得到它。与此同时,若访问该类型的最终状态数据时,需要以相同的聚合函数名加-Merge后缀的形式来得到最终状态数据。举个🌰
# 创建表
CREATE TABLE aggregateFunction_test(
id String,
col1 AggregateFunction(uniq, String),
col2 AggregateFunction(sum, UInt32)
) ENGINE = Memory;
# 插入数据
INSERT INTO aggregateFunction_test select '111',uniqState('xxx'), sumState(toUInt32(100));
INSERT INTO aggregateFunction_test select '111',uniqState('xxx'), sumState(toUInt32(100));
# 查询数据
select id,uniqMerge(col1),sumMerge(col2) from aggregateFunction_test group by id;
复制
查询结果:

5) SimpleAggregateFunction
聚合函数的中间状态,但是SimpleAggregateFunction(name, types_of_arguments…) 数据类型存储聚合函数的当前值,而不将其完整状态存储为 AggregateFunction 有 此优化可应用于具有以下属性的函数:应用函数的结果 f 到行集 S1 UNION ALL S2 可以通过应用来获得 f 行的部分单独设置,然后再次应用 f 到结果: f(S1 UNION ALL S2) = f(f(S1) UNION ALL f(S2)). 此属性保证部分聚合结果足以计算组合结果,因此我们不必存储和处理任何额外的数据。相比较AggregateFunction而言,它拥有更好的性能。
# 创建表
CREATE TABLE simpleAggregateFunction_test(
id String,
col1 SimpleAggregateFunction(sum, UInt64),
col2 SimpleAggregateFunction(any, String)
) ENGINE = Memory;
# 插入数据
INSERT INTO simpleAggregateFunction_test select '111',toUInt64(100), 'xxx1';
INSERT INTO simpleAggregateFunction_test select '111',toUInt64(200), 'xxx2';
# 查询数据
select id,uniqMerge(col1),sumMerge(col2) from aggregateFunction_test group by id;
复制
查询结果:
