目录
在系统表中检查数据类型名称是否区分大小写
SELECT * from system.data_type_families;
一、数值类型
1. 整型
固定长度的整型,包括有符号整型或无符号整型。ClickHouse 则直接使用 Int8、Int16、Int32 和Int64 指代 4 种大小的 Int 类型,其末尾的数字正好表明了占用字节的大小(8 位 = 1 字节)。
- 整型范围(-2n-1~2n-1-1)
- 无符号整型范围(0~2n-1)
2. 浮点型(存在精度损失问题)
- Float32 - float
- Float64 - double
建议尽可能以整型形式存储数据。例如,将固定精度的数字转换为整数值,如果时间用毫秒为单位表示,因为浮点型进行计算时可能引起四舍五入的误差
3. Decimal
ClickHouse 提供了 Decimal32、Decimal64 和 Decimal128 三种精度的定点数。
-
简写方式有 Decimal32(S)、Decimal64(S)、Decimal128(S) 三种。
-
原生方式为 Decimal(P,S),其中:P 代表精度,决定总位数(整数部分+小数部分),取值范围是 1 ~38;·S 代表规模,决定小数位数,取值范围是 0~P
使用场景: 一般金额字段、汇率、利率等字段为了保证小数点精度,都使用 Decimal 进行存储。
二、字符串类型
1. String
2. FixedString
与String 相比,极少会使用 FixedString,因为使用起来不是很方便。
3. UUID
UUID 是一种数据库常见的主键类型,在 ClickHouse 中直接把它作为一种数据类型。UUID 共有 32 位,它的格式为 8-4-4-4-12 。如果一个 UUID 类型的字段在写入数据时没有被赋值,则会依照格式使用 0 填充
CREATE TABLE test_uuid(
`uid` UUID,
`name` String
)
ENGINE=Memory;
INSERT INTO test_uuid
SELECT generateUUIDv4(), 'zss';
三、时间类型
1. Date
Date 类型不包含具体的时间信息,只精确到天,支持字符串形式写入
2. DateTime
DateTime 类型包含时、分、秒信息,精确到秒,支持字符串形式写入
3. DateTime64
DateTime64 可以记录亚秒,它在 DateTime 之上增加了精度的设置
四、复杂类型
1. Enum
- Enum8 用
'String'=Int8
对描述。 - Enum16 用
'String'=Int16
对描述。
在定义常量时经常会使用的数据类型,Enum 保存 'string' = integer
的对应关系。
CREATE TABLE test_enum
(
id UInt8,
color Enum8('RED'=1, 'GREEN'=2, 'BLUE'=3)
)ENGINE = Memory;
DESC test_enum;
INSERT INTO test_enum VALUES(1, 'RED'), (3,'GREEN');
-- 没有声明的值是不能插入
INSERT INTO test_enum VALUES(4, 'pink');
-- 节省存储空间,提升处理效率;底层存储 Int 类型,占用空间小
SELECT id, toInt32(color) FROM test_enum;
SELECT id, CAST(color,'Int8') FROM test_enum;
2. Array(T)
Array(T):由 T 类型元素组成的数组。
T 可以是任意类型,包含数组类型。但不推荐使用多维数组,ClickHouse 对多维数组的支持有限。例如,不能在 MergeTree 表中存储多维数组。
数组是强数据类型
--toTypeName 查看变量的数据类型
SELECT array(1,2,3) AS arr, toTypeName(arr);
CREATE TABLE test_array
(
name String,
hobby Array(String)
) ENGINE = Log;
INSERT INTO test_array VALUES('张三2', ['读书', '爬山', '散步']);
INSERT INTO test_array VALUES('李四2', ['read', 'hiking', 'dance']);
INSERT INTO test_array VALUES('王五2', array('吃', '睡', '喝',' 玩'));
-- clickhouse 会利用多核处理器将数据分块存储、计算
SELECT * FROM test_array;
-- 查询数组中的数据
SELECT *, hobby[1] FROM test_array;
-- 遍历数组中每个元素,给每个元素加上'abc'
SELECT arrayMap(e -> concat(e, 'abc'), hobby) FROM test_array;
3. Tuple 元组
可以存储任意的数据类型,在定义的时候声明数据类型和数据元素个数
CREATE TABLE test_tuple
(
name String,
info Tuple(String, String, UInt8)
)ENGINE=Memory;
INSERT INTO test_tuple VALUES
('zss', ('M', 'coder', 23)),
('lss', tuple('F', 'coder', 23));
SELECT * FROM test_tuple;
-- 通过下标查询 tuple 数据
SELECT name, info.1 AS sex, info.2, info.3 age FROM test_tuple;
4. Nested
Nested 是一种嵌套表结构。一张数据表,可以定义任意多个嵌套类型字段,但每个字段的嵌套层级只支持一级,即嵌套表内不能继续使用嵌套类型。
CREATE TABLE test_nested
(
id Int8,
name String,
hobby Nested(
hid Int8,
h1 String,
h2 String
)
)ENGINE=Memory;
-- 查看表结构:
DESC test_nested;
/**
嵌套类型本质是一种多维数组的结构。嵌套表中每个字段都是一个数组,并且行与行之间数组的长度无须对齐。
需要注意的是,在同一行数据内每个数组字段的长度必须相等。
*/
-- 插入数据
INSERT INTO test_nested VALUES (1, 'zss', [1,2,3],['吃','喝','睡'],['eat','drink','sleep']);
INSERT INTO test_nested VALUES (2, 'lss', [1,2,3],['吃','喝','睡'],['eat','drink','sleep']);
-- 查询数据
SELECT * FROM test_nested;
-- 复杂查询数据
SELECT id, name, hobby.hid, hobby.h1, hobby.h1[1] FROM test_nested;
5. Domain
域名类型分为 IPv4 和 IPv6 两类,本质上它们是对整型和字符串的进一步封装。IPv4 类型是基于 UInt32 封装的,IPv6 类型是基于 FixedString(16) 封装的。
- 出于便捷性的考量,例如 IPv4 类型支持格式检查,格式错误的 IP 数据是无法被写入的
- 出于性能的考量,同样以 IPv4 为例,IPv4 使用 UInt32 存储,相比 String 更加紧凑,占用的空间更小,查询性能更快
- Domain 类型并不是字符串,所以它不支持隐式的自动类型转换。如果需要返回 IP 的字符串形式,则需要显式调用 IPv4NumToString 或 IPv6NumToString 函数进行转换。
CREATE TABLE test_domain
(
id Int8,
ip IPv4
)ENGINE=Memory;
INSERT INTO test_domain VALUES(1, '192.168.133.1');
INSERT INTO test_domain VALUES(1, '192.168.133'); -- 插入数据时会进行数据的检查所以这行数据会报错
6. Boolean 和 Nullable
ck 中没 有 Boolean 类型, 使用 1 和 0 来代表 true 和 false
Nullable 某种数据类型允许为 null, 或者是没有给值的情况下模式是 NULL