3.1. 数据类型
整数类型有Int8、Int16、Int32、Int64,分别表示8位、16位、32位和64位有符号整数。适用场景:存储整数值,如年龄、数量等。
浮点类型有Float32和Float64,分别表示32位和64位浮点数。适用场景:存储精确到小数点后几位的数值,如价格、评分等。
字符串类型有String和FixedString(n)。String是可变长字符串,FixedString(n)是长度固定为n的字符串。适用场景:存储文本数据,如名称、描述等。
注意事项:FixedString(n)的长度需提前定义好,如果插入的字符串长度超过n,则会被截断。
日期和时间类型有Date、DateTime、DateTime64。Date表示日期,DateTime表示日期和时间,DateTime64表示带有小数的日期和时间。适用场景:存储日期和时间信息,如订单时间、生日等。
注意事项:DateTime64需要指定小数位数,如DateTime64(3)表示精确到毫秒。
数组类型表示一组相同数据类型的元素组成的集合。例如,Array(Int32)表示一个整数数组。适用场景:存储具有相同类型的多个值,如标签、分类等。
枚举类型表示有限个可能值的类型,如Enum8和Enum16。适用场景:存储有限个可能值的数据,如性别、状态等。
注意事项:枚举值需提前定义好,插入未定义的值会报错。
3.2. 表结构设计
CREATE TABLE table_name (
column_name1 data_type1 [options],
column_name2 data_type2 [options],
...
) ENGINE = engine_type [engine_options];
ALTER TABLE table_name
ADD COLUMN column_name data_type [options];
ALTER TABLE table_name
DROP COLUMN column_name;
DROP TABLE table_name;
3.3. 主键和索引
主键用于唯一标识表中的每一行数据,定义方式如下:
CREATE TABLE table_name (
...
column_name1 data_type1 [options],
column_name2 data_type2 [options],
...
) ENGINE = engine_type [engine_options] PRIMARY KEY (column_name1, column_name2, ...);
注意事项:主键列应具有唯一性,且不允许为NULL。
ClickHouse支持多种索引类型,如位图索引、跳表索引、全文索引等。使用时,需在表创建时指定索引类型和对应的参数。
3.4. 分区和分片
分区是将数据按照某个条件进行划分的方法,通常用于优化查询性能。在ClickHouse中,分区通常是按照时间进行划分,但也可以根据其他条件进行划分。
创建带有分区键的表:
CREATE TABLE table_name (
...
) ENGINE = engine_type
PARTITION BY partition_expression;
注意事项:合理设计分区键,有助于提高查询性能。但过多的分区可能导致元数据管理开销增加。
分片是指将数据分布在多个节点上,以实现横向扩展和高可用性。在ClickHouse中,通过配置分布式表引擎和集群设置,可以实现数据分片。
创建分布式表:
CREATE TABLE distributed_table_name (
...
) ENGINE = Distributed(cluster_name, local_database, local_table, sharding_key);
注意事项:分片需要合理规划,以充分利用集群资源。过多的分片可能导致数据分布不均衡,影响查询性能。
以下是一个完整的示例:
CREATE TABLE orders (
order_id UInt64,
customer_id UInt64,
order_date Date,
total_amount Float64
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(order_date)
ORDER BY (order_id);
INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES
(1, 1001, '2022-01-01', 100.5),
(2, 1002, '2022-01-02', 200.3),
(3, 1003, '2022-02-01', 150.8),
(4, 1001, '2022-02-05', 320.0);
SELECT * FROM orders WHERE order_date >= '2022-02-01' AND order_date < '2022-03-01';
CREATE TABLE distributed_orders (
order_id UInt64,
customer_id UInt64,
order_date Date,
total_amount Float64
) ENGINE = Distributed('my_cluster', 'default', 'orders', rand());
SELECT * FROM distributed_orders WHERE customer_id = 1001;