diff --git a/docs/数据分区策略.md b/docs/数据分区策略.md index ee7600c..833dd74 100644 --- a/docs/数据分区策略.md +++ b/docs/数据分区策略.md @@ -31,11 +31,32 @@ SELECT create_hypertable('orders', 'created_date', |---------|---------|------| | orders | **是** | 数据量大(年 100W+),查询频繁 | | order_items | **是** | 与 orders 关联,数据量更大 | -| refunds | 否 | 数据量小,暂不需要 | +| refunds | **否(不建议)** | 见下方说明 | | products | 否 | 数据量小,暂不需要 | | inventory | 否 | 数据量小,暂不需要 | -> 未来如 refunds 等表数据量增长显著,可按同样方式启用分区。 +> 未来如 products、inventory 等表数据量增长显著,可按同样方式启用分区。 + +#### refunds 表不采用 Hypertable 的原因 + +refunds 表与 orders 表有本质区别:**业务聚合的时间维度与退款自身时间不一致**。 + +| 维度 | orders 表 | refunds 表 | +|------|----------|-----------| +| 分区键候选 | `created_date`(订单创建时间) | `created_date`(退款创建时间) | +| 业务聚合过滤字段 | `created_date`(一致) | `order_created_date`、`order_paid_date`、`completed_date`(不一致) | + +退款的核心业务场景是**营收聚合**,查询条件主要按 `order_created_date`(订单创建时间)、`order_paid_date`(订单付款时间)和 `completed_date`(退款完结时间)过滤,而非退款单自身的 `created_date`。例如: + +- "2025年12月已付款订单的退款总额" → 按 `order_paid_date` 过滤 +- "Q4 订单的退款率" → 按 `order_created_date` 过滤 +- "本月实际发生的退款金额" → 按 `completed_date` 过滤(退款完结才确认营收扣减) + +如果按退款的 `created_date` 做 Hypertable 分区,上述查询无法利用分区裁剪(一笔 2025-12 的订单,退款可能发生在 2026-02,跨多个 chunk),反而增加了复杂度。 + +此外,退款数据量远小于订单量,普通表 + B-tree 索引(`order_created_date`、`order_paid_date`、`completed_date`)足以满足查询性能要求。 + +> 如果未来退款数据量显著增长,建议使用 PostgreSQL **原生 RANGE 分区**按 `order_paid_date` 手动分区,而非 Hypertable,以保证业务聚合查询的分区裁剪生效。 ### 为什么选择 Hypertable 而非原生分区