ClickHouse数据定义

数据定义

 

ClickHouse的数据类型

ClickHouse是一款分析型数据库,有多种数据库类型,分为基础类型、复合类型和特殊类型。其中基础类型使用ClickHouse具备了描述数据的基本能力,而另外两种类型则是ClickHouse的数据表达能力更加丰富立体
 

基础类型

基础类型只有数值、字符串和时间三种类型,没有Boolean类型,但可以使用整型的0或1代替
 

数值

数值类型:整型、浮点型和定点数三类

Int

常用Tinyint、Smallint、Int和Bigint指代整型的不同取值范围。而ClickHouse则直接使用Int8、Int16、Int32、Int64指代4种大小的Int类型,其末尾的数字正好表名了占用字节的大小(8位=1字节)
ClickHouse支持无符号的整型,使用前缀U表示

Float

ClickHouse直接使用Float32和Float64代表单精度浮点数以及双精度浮点数
在使用浮点数的时候,应当要意识到它是有限精度的。例如,分别对Float32、Float64写入超过有效精度的值,会发生什么事?将拥有20位小数的数值分别写入Float32和Float64,此时结果就会出现数据误差

Decimal

如果要求更高精度的数值运算,则需要使用定点数。ClickHouse提供了Decimal32、Decimal64、Decimal128.可以通过两种形式声明定点:简写方式有Decimal32(S)、Decimal64(S)、Decimal128(S)三种,原生方式Decimal(P,S),其中:
P代表精度,决定总位数(整数部分+小数部分),取值范围是1~38
S代表规模,决定小数位数,取值范围是0~P
在使用定点数时还有一点值得注意:由于现代计算机系统只支持32位和64位CPU,所以Decimal128是在软件层面模拟实现,它的速度会明显慢于Decimal32与Decimal64
 

字符串类型

字符串类型可以细分为String、FixedString和UUID三类

String

字符串由String定义,长度不限。使用String的时候无须声明大小。他完全代替了传统意义上数据库的Varcaht、Text、Clob和Blob等字符类型。String类型不限定字符串,所以可以将任意编码的字符串存入其中。但是为了程序的规范性和可维护性,在同一套程序中应遵循使用统一的编码,例如“UTF-8”

FixedString

FixedString类型和传统意义上的Char类型有些类似,对于一些字符有明确长度的场合,可以使用固定长度的字符串。定长字符串通过FixedString(N)声明,其中N表示字符串长度。但是Char不同的是,FixedString使用null字节填充末尾字符,而Char通常使用空格填充。比如例子,字符串‘abc’虽然只有3位,但是长度却是5,因为末尾有2位空字符填充

UUID

UUID是一种数据库常见的主键类型,在ClickHouse中直接把它作为一种数据类型。UUID共有32位,它的格式为8-4-4-4-12。如果一个UUID类型的字段在写入数据时没有被赋值,则会依照格式使用0填充
 

时间类型

时间类型分为DateTime、DateTime64、Date。ClickHouse目前没有时间戳类型。时间类型最高的精度是秒,也就是说,如果需要毫秒、微妙等大于秒分辩率的时间,则只能借助UInt类型实现。

DateTime

DateTime类型包括时、分、秒信息,精确到秒,支持使用字符串形式写入

DateTime64

DateTime64可以记录亚秒,它在DateTime之上增加了精度的设置

Date

Date类型不包含具体的时间信息,只精度到天,同样支持字符串形式写入
 

复合类型

ClickHouse还提供了数组、元祖、枚举和嵌套四类复合类型。这些类型通常是其他数据库原生不具备的特性。拥有了复合类型之后,ClickHouse的数据模型表达能力更强

Array

数组有两种定义形式,常规方式array(T)或者[T]
ClickHouse数组拥有类型推断的能力,推断类型:以最小的存储代价为原则,即使用最小可表达的数据类型。例如array[1, 2]会通过自动推断将UInt8作为数组类型。但是数组元素中如果存在Null值,则元素将变为Nullable。
一个数组内可以包含多种数据类型,例如[1, 2.0],是可行的,但是各类型之间必须兼容,例如[1, '2']则会报错

Tuple

元祖类型由1~n个元素组成,每个元素之间允许设置不同的数据类型,且彼此之间不要求兼容。元祖同样支持类型推断,其推断依据仍然以最小存储代价为原价。与数组类型,元祖也可以使用两种方式定义,常规方式tuple(T)

Enum

ClickHouse支持枚举类型,这是一种定义常量时经常会使用数据类型。ClickHouse提供了Enum8和Enum16两种枚举类型,他们除了取值范围不同之外,没有其他不同。枚举固定使用(String:int)key/value键值对的形式定义数据,所以Enum8和Enum16分别对应(String:Int8)和(String:Int16)
Key和Value是不允许重复的,要确保唯一性。其次,Key和Value的值都不能为null,但Key允许是空字符串。在写入枚举的时候,只会用到key字符串部分
在数据写入过程中,会对照枚举集合项的内容逐一检查。如果Key字符串不在集合范围内则会抛出异常
是否可以使用String代替枚举?出于性能的考虑,因为虽然枚举定义中key属于string类型,但是在后续对枚举的操作中(排序、去重、分组等),会使用Int类型的Value值

Nested

嵌套类型,一张数据表,可以定义任意多个嵌套字段,但每个字段的嵌套层次支持一级,即嵌套表内不能继续使用嵌套类型。对于简单场景的层级关系或关联关系,使用嵌套也是一种不错的选择

特殊类型

Nullable,并不是一个独立类型,一种辅助修饰符,与基础类型一起使用,表示某个基础数据类型可以是Null值,不能用于数组和元组这些复合类型,也不能作为索引字段,其次,应该慎用Nullable类型,包括Nullable的数据表,不然会使查询和写入性能变慢,正常情况下,每个列字段的数据会被存储在对应[Column].bin文件中,如果一个列字段被Nullable类型修饰后,会额外生成一个[Collumn].null.bin文件专门保存它的null值,这意味着在读取和写入数据时,需要一倍的额外文件操作
Domain,IPv4和IPv6两类,本质上它们是对整型和字符串进一步封装,IPv4类型是基于UInt32封装的。和存储字符串存储不同的是?1. 出于便捷性的考虑,例如IPv4支持支持格式检查,格式错误IP数据是无法被写入的,2. 出于性能的考量,同样以IPv4为例,IPv4使用UInt32存储,相比String更加紧凑,占用的空间跟小,查询性能更快,IPv6类型是基于FixedString(16)封装的,它的使用方法与IPv4别无二致。Domain看上去是string,但Domain类型并不是字符串,所以它不支持隐式的自动类型转换,如果需要返回IP的字符串形式,显示调用IPv4NumToString或IPv6NumToString函数进行转换

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章