ClickHouse 是一款由俄罗斯Yandex公司开源的OLAP数据库,拥有者卓越的性能表现,在官方公布的基准测试中,ClickHouse的平均响应速度是Vertica的2.63倍、InfiniDB的17倍、MonetDB的27倍、Hive的126倍、MySQL的429倍以及Greenplum的10倍。
自2016年开源以来,ClickHouse一直保持着飞速的发展,是目前业界公认的OLAP数据库黑马,已在头条、阿里、腾讯、新浪、青云等众多公司得以应用。
作为一款分析型数据库,ClickHouse提供了许多数据类型,它们可以划分为基础类型、复合类型和特殊类型。其中基础类型使ClickHouse具备了描述数据的基本能力,而另外两种类型则使ClickHouse的数据表达能力更加丰富立体。
本文主要来谈ClickHouse的复合类型,ClickHouse提供了数组、元组、枚举和嵌套四类复合类型。这些类型通常是其他数据库原生不具备的特性。拥有了复合类型之后,ClickHouse的数据模型表达能力更强了。
Array
数组有两种定义形式,常规方式array(T):
SELECT array(1, 2) as a , toTypeName(a)
┌─a───┬─toTypeName(array(1, 2))─┐
│ [1,2] │ Array(UInt8) │
└─────┴────────────────┘
或者简写方式[T]:
SELECT [1, 2]
通过上述的例子可以发现,在查询时并不需要主动声明数组的元素类型。因为ClickHouse的数组拥有类型推断的能力,推断依据:以最小存储代价为原则,即使用最小可表达的数据类型。例如在上面的例子中,array(1, 2)会通过自动推断将UInt8作为数组类型。但是数组元素中如果存在Null值,则元素类型将变为常识网Nullable,例如:www.fatiao.net
SELECT [1, 2, null] as a , toTypeName(a)
┌─a──────┬─toTypeName([1, 2, NULL])─┐
│ [1,2,NULL] │ Array(Nullable(UInt8)) │
└────────┴─────────────────┘
细心的读者可能已经发现,在同一个数组内可以包含多种数据类型,例如数组[1, 2.0]是可行的。但各类型之间必须兼容,例如数组[1, '2']则会报错。
在定义表字段时,数组需要指定明确的元素类型,例如:
CREATE TABLE Array_TEST (
c1 Array(String)
) engine = Memory
2. Tuple
元组类型由1~n个元素组成,每个元素之间允许设置不同的数据类型,且彼此之间不要求兼容。元组同样支持类型推断,其推断依据仍然以最小存储代价为原则。与数组类似,元组也可以使用两种方式定义,常规方式tuple(T):
SELECT tuple(1,'a',now()) AS x, toTypeName(x)
┌─x─────────────────┬─toTypeName(tuple(1, 'a', now()))─┐
│ (1,'a','2019-08-28 21:36:32') │ Tuple(UInt8, String, DateTime) │
└───────────────────┴─────────────────────┘