1.Doris建了分区之后,如何获取元数据?
建造测试数据
-- 1. 创建一张名为 sales_record 的表,并定义三个字段
CREATE TABLE sales_record (
id INT, -- 订单ID,整数类型
sale_date DATE, -- 销售日期,日期类型(这是我们要用来分区的字段)
amount DECIMAL(10,2) -- 销售金额,高精度数字(共10位,2位小数)
)
-- 2. 分区策略:按照 sale_date 字段的时间范围进行切分
PARTITION BY RANGE(sale_date) (
-- 分区 p202301:存放 [2023-01-01 到 2023-02-01) 之间的数据(左闭右开)
PARTITION p202301 VALUES [("2023-01-01"), ("2023-02-01")),
-- 分区 p202302:存放 [2023-02-01 到 2023-03-01) 之间的数据
PARTITION p202302 VALUES [("2023-02-01"), ("2023-03-01")),
-- 分区 p202303:存放 [2023-03-01 到 2023-04-01) 之间的数据
PARTITION p202303 VALUES [("2023-03-01"), ("2023-04-01"))
)
-- 3. 分桶策略:将数据打散存储,防止单点热点
-- 意思是以 id 字段为基准进行哈希计算,将数据均匀分散到 10 个桶中
DISTRIBUTED BY HASH(id) BUCKETS 10
-- 4. 属性配置
PROPERTIES (
-- 设置副本数,防止机器故障导致数据丢失
"replication_num" = "1"
)
执行步骤与结果
1. 初始状态检查
- 执行 SQL:
SHOW PARTITIONS FROM sales_record; - 执行结果:
PartitionId PartitionName VisibleVersion State Range Rows 13764 p202301 1 NORMAL [2023-01-01, 2023-02-01) 0 13765 p202302 1 NORMAL [2023-02-01, 2023-03-01) 0 13766 p202303 1 NORMAL [2023-03-01, 2023-04-01) 0
2. 数据写入 插入三条分别属于 1月、2月、3月的数据,用于触发分区元数据更新。
- 执行 SQL:
INSERT INTO sales_record VALUES (1, '2023-01-15', 100.50), (2, '2023-02-20', 200.00), (3, '2023-03-10', 50.25);
3. 最终状态验证 再次查询元数据,观察数据写入后的变化。
- 执行 SQL:
SHOW PARTITIONS FROM sales_record; - 执行结果:
PartitionId PartitionName VisibleVersion State Range Rows 13764 p202301 2 NORMAL [2023-01-01, 2023-02-01) 2 13765 p202302 2 NORMAL [2023-02-01, 2023-03-01) 2 13766 p202303 2 NORMAL [2023-03-01, 2023-04-01) 2
结论
- 版本号飙升 (
VisibleVersion):从1变成了2。这说明 Doris 接收到了新的写入请求,并生成了新的数据版本。 - 行数增加 (
Rows):从0变成了2。- 注:这里显示为 2 而不是 1,是因为 Doris 底层采用了预聚合或索引机制(如 ZoneMap 或 BloomFilter),为了快速查询,系统可能为这一行数据生成了 2 个索引条目或统计项,这是正常现象,证明数据确实进去了。
2.在一个表下面建多个分区,比如粒度到 月、天、小时,看看元数据的具体情况
建造测试数据
CREATE TABLE sales_mixed_granularity (
id INT,
sale_time DATETIME,
amount DECIMAL(10,2)
)
-- 这里我们按时间范围分区
PARTITION BY RANGE(sale_time) (
-- 【粒度:月】这是一个管整个 1 月的分区
PARTITION p_month_jan VALUES [("2023-01-01 00:00:00"), ("2023-02-01 00:00:00")),
-- 【粒度:天】这是在 2 月里,单独切出来的一个“天级”分区
PARTITION p_day_feb_01 VALUES [("2023-02-01 00:00:00"), ("2023-02-02 00:00:00")),
-- 【粒度:天】这是在 2 月里,单独切出来的另一个“天级”分区
PARTITION p_day_feb_02 VALUES [("2023-02-02 00:00:00"), ("2023-02-03 00:00:00")),
-- 【粒度:小时】这是在 3 月里,极其精细的“小时级”分区
PARTITION p_hour_mar_01_10 VALUES [("2023-03-01 10:00:00"), ("2023-03-01 11:00:00")),
-- 【粒度:小时】这是在 3 月里,另一个“小时级”分区
PARTITION p_hour_mar_01_11 VALUES [("2023-03-01 11:00:00"), ("2023-03-01 12:00:00"))
)
DISTRIBUTED BY HASH(id) BUCKETS 5
PROPERTIES ("replication_num" = "1");
执行步骤与结果
1. 元数据状态检查
- 执行 SQL:
SHOW PARTITIONS FROM sales_mixed_granularity; - 执行结果(摘要):
PartitionId PartitionName State Range (时间范围) 13837 p_month_jan NORMAL [2023-01-01 00:00:00, 2023-02-01 00:00:00) 13838 p_day_feb_01 NORMAL [2023-02-01 00:00:00, 2023-02-02 00:00:00) 13840 p_hour_mar_01_10 NORMAL [2023-03-01 10:00:00, 2023-03-01 11:00:00)
结论
- 混合粒度共存:Doris 完全支持在同一个表内混合使用月、天、小时等不同时间跨度的分区,它们在元数据中是平级的。
- 元数据记录方式:Doris 不区分分区类型,只记录精确的起止时间范围(Range)。范围宽即为粗粒度,范围窄即为细粒度。
3.建不同名字的分区字段、或者不同格式的分区值,比如按天分区,可以是tday或者day, 值可能是 2026-03-25或者 20260325
建造测试数据
1. 尝试混合格式建表
尝试在建表语句中混合使用标准格式(YYYY-MM-DD)和紧凑格式(YYYYMMDD)定义分区值。
-
执行 SQL:
CREATE TABLE partition_format_test ( id INT, event_time DATETIME, amount DECIMAL(10,2) ) PARTITION BY RANGE(event_time) ( PARTITION tday VALUES [("2026-03-25 00:00:00"), ("2026-03-26 00:00:00")), PARTITION day VALUES [("20260326 00:00:00"), ("20260327 00:00:00")), PARTITION p_20260327 VALUES [("2026-03-27 00:00:00"), ("2026-03-28 00:00:00")) ) DISTRIBUTED BY HASH(id) BUCKETS 5 PROPERTIES ("replication_num" = "1"); -
执行结果: 报错!
1105 - Unexpected exception: date/datetime literal [20260326 00:00:00] is invalid(Doris 在建表阶段不支持YYYYMMDD这种紧凑格式的字符串直接作为分区界限值)
2. 修正格式后重试
将所有分区值统一修正为标准 SQL 时间格式(YYYY-MM-DD HH:MM:SS),验证分区名称的灵活性。
执行步骤与结果
1. 混合命名建表
创建一张按天分区的表,尝试使用不同的分区名称(tday, day, p_20260327)来验证分区命名的灵活性。
- 执行 SQL:
CREATE TABLE partition_format_test ( id INT, event_time DATETIME, amount DECIMAL(10,2) ) PARTITION BY RANGE(event_time) ( PARTITION tday VALUES [("2026-03-25 00:00:00"), ("2026-03-26 00:00:00")), PARTITION day VALUES [("2026-03-26 00:00:00"), ("2026-03-27 00:00:00")), PARTITION p_20260327 VALUES [("2026-03-27 00:00:00"), ("2026-03-28 00:00:00")) ) DISTRIBUTED BY HASH(id) BUCKETS 5 PROPERTIES ("replication_num" = "1"); - 执行结果:
Query OK
2. 元数据状态检查 查看建表后的分区列表,观察不同命名风格的分区在元数据中的实际存储情况。
- 执行 SQL:
SHOW PARTITIONS FROM partition_format_test; - 执行结果:
PartitionId PartitionName VisibleVersion LastUpdateTime State PartitionKey PartitionRange DistributionKey Buckets ReplicationNum StorageMedium ExpirationTime IsInMemory Compression Tag IsRemote IsSync SchemaVersion VisibleVersionTime 13934 tday 1 2026-03-31 01:12:23 NORMAL event_time [types: [DATETIMEV2]; keys: [2026-03-25 00:00:00]; ..types: [DATETIMEV2]; keys: [2026-03-26 00:00:00]; ) id 5 1 HDD 9999-12-31 15:59:59 false tag.location.default: 1 true true 1 0 13935 day 1 2026-03-31 01:12:23 NORMAL event_time [types: [DATETIMEV2]; keys: [2026-03-26 00:00:00]; ..types: [DATETIMEV2]; keys: [2026-03-27 00:00:00]; ) id 5 1 HDD 9999-12-31 15:59:59 false tag.location.default: 1 true true 1 0 13936 p_20260327 1 2026-03-31 01:12:23 NORMAL event_time [types: [DATETIMEV2]; keys: [2026-03-27 00:00:00]; ..types: [DATETIMEV2]; keys: [2026-03-28 00:00:00]; ) id 5 1 HDD 9999-12-31 15:59:59 false tag.location.default: 1 true true 1 0
结论
- 分区名称完全自由:分区名(如
tday,day)只是一个别名标签,Doris 不强制要求命名格式,你可以随意定义。 - 分区值必须标准化:虽然分区名可以随意起,但分区值的定义必须使用标准时间格式(
YYYY-MM-DD HH:MM:SS),不支持20260326这种紧凑格式。
4.没有建分区和有建分区的表,元数据有什么区别
执行步骤与结果
1. 创建显式分区表 创建一张按天分区的表,显式定义了两个时间范围的分区。
- 执行 SQL:
-- 创建一个按天分区的表 CREATE TABLE partitioned_table ( id INT, event_time DATETIME ) PARTITION BY RANGE(event_time) ( PARTITION p20260330 VALUES [("2026-03-30 00:00:00"), ("2026-03-31 00:00:00")), PARTITION p20260331 VALUES [("2026-03-31 00:00:00"), ("2026-04-01 00:00:00")) ) DISTRIBUTED BY HASH(id) BUCKETS 5 PROPERTIES ("replication_num" = "1"); - 执行结果:
Query OK
2. 创建非分区表
创建一张没有任何 PARTITION BY 定义的普通表。
- 执行 SQL:
-- 创建一个没有分区的表 CREATE TABLE non_partitioned_table ( id INT, event_time DATETIME ) DISTRIBUTED BY HASH(id) BUCKETS 5 PROPERTIES ("replication_num" = "1"); - 执行结果:
Query OK
3. 元数据状态检查 分别查看两张表的分区元数据信息。
-
执行 SQL:
SHOW PARTITIONS FROM partitioned_table; SHOW PARTITIONS FROM non_partitioned_table; -
执行结果: 分区表 (
partitioned_table) 元数据:PartitionId PartitionName VisibleVersion LastUpdateTime State PartitionKey PartitionRange DistributionKey Buckets ReplicationNum StorageMedium ExpirationTime IsInMemory Compression Tag IsRemote IsSync SchemaVersion VisibleVersionTime 14229 p20260330 1 2026-03-31 01:30:47 NORMAL event_time [types: [DATETIMEV2]; keys: [2026-03-30 00:00:00]; ..types: [DATETIMEV2]; keys: [2026-03-31 00:00:00]; ) id 5 1 HDD 9999-12-31 15:59:59 false tag.location.default: 1 true true 1 0 14230 p20260331 1 2026-03-31 01:30:47 NORMAL event_time [types: [DATETIMEV2]; keys: [2026-03-31 00:00:00]; ..types: [DATETIMEV2]; keys: [2026-04-01 00:00:00]; ) id 5 1 HDD 9999-12-31 15:59:59 false tag.location.default: 1 true true 1 0 非分区表 (
non_partitioned_table) 元数据:PartitionId PartitionName VisibleVersion LastUpdateTime State PartitionKey PartitionRange DistributionKey Buckets ReplicationNum StorageMedium ExpirationTime IsInMemory Compression Tag IsRemote IsSync SchemaVersion VisibleVersionTime 14483 non_partitioned_table 1 2026-03-31 01:33:07 NORMAL (空) (空) id 5 1 HDD 9999-12-31 15:59:59 false tag.location.default: 1 true true 1 0
结论
- 非分区表也有“分区”:Doris 中不存在真正的“无分区表”。如果你不建分区,系统会自动创建一个以表名命名的默认分区(如结果中的
non_partitioned_table)。 - 元数据核心区别:
- 分区表:
PartitionKey和PartitionRange有具体值,数据被切分。 - 非分区表:
PartitionKey和PartitionRange为空,代表这是一个全值域分区,容纳所有数据。
- 分区表:
- 物理存储一致:无论是否有逻辑分区,底层都拥有独立的
PartitionId,且分桶数、副本数等物理属性完全一致。