找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

344

积分

0

好友

46

主题
发表于 昨天 02:15 | 查看: 3| 回复: 0

做Doris开发,几乎都踩过表模型的坑:用聚合表查明细,翻遍结果也找不到单条记录;用主键表做统计,查询跑了很久还没出结果;明细表里订单数据重复堆积却无法去重……

其实问题根源很明确:没吃透Doris的三种核心表模型——明细表(Duplicate Key)、主键表(Unique Key)、聚合表(Aggregate Key)。它们本身没有优劣之分,关键在于“场景适配”。选对模型能让查询性能提升数倍,选错则可能拖累整个集群,甚至无法满足业务需求。

本文将深入解析这三种表模型的底层逻辑、创建方法和适用边界,助你建表时精准决策,一击即中。

一、核心区别:如何处理重复与聚合?

理解表模型的关键在于抓住两个核心:如何处理数据重复以及是否进行预聚合。这两点直接决定了数据的存储方式、查询性能和适用场景。下表清晰地概括了三者的核心差异:

表模型 核心特征 数据存储逻辑 查询优势 核心局限
明细表(Duplicate Key) 允许Key重复,保留全量原始数据 按指定Key排序存储,写多少存多少,不聚合不去重 支持任意维度即席查询,列存优势明显(只读所需列) 无预聚合,聚合查询速度慢,存储开销大
主键表(Unique Key) Key唯一,只保留最新版本数据 按主键去重,新数据覆盖旧数据,后台清理历史版本 支持高频更新、部分列更新,保证数据唯一性 不支持ROLLUP预聚合,聚合查询性能一般
聚合表(Aggregate Key) 按Key预聚合,只存聚合结果 写入时自动按Key分组,指标列执行预聚合(SUM/MAX等) 聚合查询速度极快,存储开销小 不保留原始数据,即席查询能力弱

⚠️ 重要提醒:Doris表类型一旦创建便无法修改!建表前务必与业务、产品方确认清楚:是否需要保留原始记录、是否需要唯一性约束、是否需要高频更新。

二、深度解析:原理、建表与场景避坑

1. 明细表:存储原始全量数据

新手常误解“Duplicate Key”,它并非“去重键”,而是“排序键”。数据写入时按此键排序存储,目的是优化查询时的过滤效率,而非去重。例如,指定 (dt, user_id) 为排序键,相同用户的记录会集中存储,查询该用户数据时能快速定位。

(1)建表示例

场景:存储用户行为日志(需保留全量原始记录,支持多维度临时查询)

CREATE TABLE user_behavior_duplicate (
    dt DATE COMMENT '日期(排序键列,高频过滤)',
    user_id BIGINT COMMENT '用户ID(排序键列,高频过滤)',
    action_type VARCHAR(20) COMMENT '行为类型:点击/下单/支付',
    goods_id BIGINT COMMENT '商品ID(高频过滤,可建布隆过滤器索引)',
    action_time DATETIME COMMENT '行为时间',
    device_id VARCHAR(50) COMMENT '设备ID',
    channel VARCHAR(30) COMMENT '来源渠道'
)
DISTRIBUTED BY HASH(dt, user_id) BUCKETS 10
DUPLICATE KEY(dt, user_id)
PROPERTIES (
    "replication_num" = "3"
);
(2)适用场景
  • 原始数据留存:用户行为日志、设备监控日志、金融交易流水存档
  • 多维度即席查询:需灵活组合过滤条件,如“查询某日某地区使用特定设备的用户行为”。
  • 发挥列存优势:查询仅涉及部分列时,列式存储能大幅减少I/O开销。

2. 主键表:保证唯一性与支持更新

主键表的核心是“唯一性约束+版本管理”。指定的Unique Key是真正的主键,保证唯一性。数据写入时,相同主键的新记录会覆盖旧版本,后台通过Compaction机制清理历史数据。其最实用的特性是“部分列更新”,例如只更新订单状态,无需传递全量字段,这在处理高频更新的数据库业务表时效率提升显著。

(1)建表示例

场景:电商订单表(订单ID唯一,需高频更新状态)

CREATE TABLE order_unique (
    order_id BIGINT COMMENT '订单ID(主键,唯一标识)',
    user_id BIGINT COMMENT '用户ID',
    goods_id BIGINT COMMENT '商品ID',
    order_amt DECIMAL(16, 2) COMMENT '订单金额(静态列,很少更新)',
    order_status TINYINT COMMENT '订单状态(高频更新列)',
    create_time DATETIME COMMENT '创建时间',
    pay_time DATETIME COMMENT '支付时间(高频更新列)',
    operator VARCHAR(50) COMMENT '操作人'
)
DISTRIBUTED BY HASH(order_id) BUCKETS 30
UNIQUE KEY(order_id)
PROPERTIES (
    "replication_num" = "3"
);
(2)适用场景
  • 主键唯一约束:订单、用户、商品等核心业务表,避免数据重复。
  • 高频更新:订单状态、物流节点、商品库存的实时更新。
  • 部分列更新:仅更新少数字段,无需回填所有列值。

3. 聚合表:预聚合加速查询

聚合表的核心是“写入时预聚合,查询时直接取结果”。建表时指定“聚合Key列”(维度)和带聚合函数的“指标列”,数据写入时即自动按Key分组聚合。例如,100条同一商品的订单记录,最终只存储1条包含总销量的聚合数据。优势是存储量小、聚合查询极快,代价是丢失原始明细。

(1)建表示例

场景:电商运营日报表(按天+商品维度统计,支撑看板秒级查询)

CREATE TABLE goods_sales_aggregate (
    dt DATE COMMENT '日期(聚合Key列)',
    goods_id BIGINT COMMENT '商品ID(聚合Key列)',
    goods_name VARCHAR(100) COMMENT '商品名称(聚合Key列)',
    category VARCHAR(50) COMMENT '商品分类(聚合Key列)',
    order_cnt SUM BIGINT COMMENT '下单数量(指标列,求和)',
    sales_amt SUM DECIMAL(16, 2) COMMENT '销售金额(指标列,求和)',
    max_price MAX DECIMAL(10, 2) COMMENT '最高单价(指标列,取最大)'
)
DISTRIBUTED BY HASH(dt, goods_id) BUCKETS 20
AGGREGATE KEY(dt, goods_id, goods_name, category)
PROPERTIES (
    "replication_num" = "3"
);
(2)适用场景
  • 固定维度报表:运营日报、管理层驾驶舱、销量排行榜,查询维度固定。
  • 高频聚合查询实时GMV统计、实时用户活跃度大盘,要求秒级响应。
  • 只需汇总结果:仅关心统计结果(如总销量、平均价),不关心单条明细。

三、场景速查与关键注意事项

场景速查表

业务场景 推荐模型 核心原因
用户行为日志分析 明细表 需保留原始日志,支持多维度即席查询
电商订单管理 主键表 订单ID唯一,需高频更新状态,兼顾明细查询
运营日报/看板统计 聚合表 固定维度预聚合,查询速度快,支持秒级响应
商品维度表(每日更新) 主键表 商品ID唯一,每日更新价格、库存等信息

关键注意事项

  1. 表类型不可修改:如果选错模型,只能删除表后重建。建议建表前用小批量数据测试验证。
  2. ROLLUP仅限聚合表:主键表和明细表不支持创建ROLLUP进行进一步预聚合,想利用ROLLUP加速查询只能使用聚合表。
  3. 更新语义差异:主键表的更新是“覆盖旧值”,而聚合表指标列(如SUM)的更新是“聚合叠加”(新值会与原有结果相加)。

总结

Doris的三种表模型,是为不同数据使用场景量身定制的工具:

  • 明细表如同“数据仓库”,负责存储原始明细,保障查询的灵活性。
  • 主键表如同“在线业务系统”,保障核心数据的唯一性与实时性。
  • 聚合表如同“分析仪表盘”,致力于提供极速的汇总查询体验。

常见的踩坑原因往往不是模型本身不好用,而是“场景与模型错配”。建表前,对照上述决策逻辑与场景速查表仔细斟酌,结合业务需求调整建表参数,便能有效规避性能陷阱,充分发挥Doris的数据处理能力。




上一篇:CVE-2025-55182漏洞复现与利用:Next.js原型链污染导致远程代码执行(RCE)
下一篇:Python字典操作与面向对象编程入门:数据结构与OOP基础实践
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-7 00:35 , Processed in 0.072371 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表