首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Doris建表不踩坑的秘籍

Doris建表不踩坑的秘籍

作者头像
数据极客圈
发布2025-12-24 15:55:03
发布2025-12-24 15:55:03
1610
举报

做Doris开发的同学,几乎都踩过表模型的坑:

“用聚合表查用户明细,翻遍结果都找不到单条记录”“主键表做日报统计,跑了5分钟还没出结果”“明细表存订单数据,重复数据堆成山还没法去重”……

其实问题根源很简单:没吃透Doris的表模型——明细表(Duplicate Key Table)、主键表(Unique Key Table)、聚合表(Aggregate Key Table)。这3种模型没有“好坏”之分,只看“适配与否”,选对模型能让查询速度提升数倍,选错则可能让集群性能大打折扣,甚至不适配业务。

今天这篇选型指南,把3种表模型的“底层逻辑、创建方式、场景边界”一次性讲透,确保你建表时“一选即中”。

一、先破局:3种表模型的核心区别是什么?

很多人混淆表模型,本质是没抓住核心差异点:如何处理数据重复是否预聚合数据。这两个点直接决定了数据的存储方式、查询性能和适用场景,建表前先把这个表格刻在脑子里:

表模型

核心特征

数据存储逻辑

查询优势

核心局限

明细表(Duplicate Key)

允许Key重复,保留全量原始数据

按指定Key排序存储,写多少存多少,不聚合不去重

支持任意维度Ad-hoc查询,列存优势明显(只读所需列)

无预聚合,聚合查询速度慢,存储开销大

主键表(Unique Key)

Key唯一,只保留最新版本数据

按主键去重,新数据覆盖旧数据,后台清理历史版本

支持高频更新、部分列更新,保证数据唯一性

不支持ROLLUP预聚合,聚合查询性能一般

聚合表(Aggregate Key)

按Key预聚合,只存聚合结果

写入时自动按Key分组,指标列执行预聚合(SUM/MAX等)

聚合查询速度极快,存储开销小

不保留原始数据,Ad-hoc查询能力弱,count(*)不友好

重要提醒:Doris表类型一旦创建无法修改!建表前必须和业务、产品确认清楚“数据是否要原始记录、是否要唯一约束、是否要高频更新”这三个核心问题。

二、逐个解析:原理+建表+场景+避坑

1. 明细表:原汁原味存数据

新手最容易误解“Duplicate Key”——它不是“去重键”,而是“排序键”。数据写入时会按该Key排序存储,目的是优化查询过滤效率,而非去重。比如指定“dt+user_id”为排序键,相同user_id的记录会集中存储,查该用户数据时能快速定位范围。

(1)建表模版

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

代码语言:javascript
复制
CREATE TABLE user_behavior_duplicate (
    dt DATECOMMENT'日期(排序键列,高频过滤)',
    user_id BIGINTCOMMENT'用户ID(排序键列,高频过滤)',
    action_type VARCHAR(20) COMMENT'行为类型:点击/下单/支付',
    goods_id BIGINTCOMMENT'商品ID(高频过滤,建布隆索引)',
    action_time DATETIME COMMENT'行为时间',
    device_id VARCHAR(50) COMMENT'设备ID(高频过滤,建布隆索引)',
    channel VARCHAR(30) COMMENT'来源渠道'
)
DISTRIBUTEDBYHASH (dt, user_id) BUCKETS 10
DUPLICATEKEY (dt, user_id)
PROPERTIES (
    "replication_num" = "3"
);

(2)适用场景
  • 原始数据留存场景:用户行为日志、设备监控日志、金融交易流水;
  • 多维度Ad-hoc查询场景:比如查“20250801北京地区用安卓设备的用户下单行为”,需要灵活组合过滤条件;
  • 列存优势场景:查询时只读取部分列(如只查user_id和action_type),列存架构能大幅减少IO开销。

2. 主键表:唯一约束+高频更新

主键表的核心是“唯一性约束+版本管理”。指定的Unique Key是真正的主键,会强制保证唯一性;数据写入时,相同主键的记录会自动覆盖旧版本,后台通过Compaction机制清理历史版本(注意区分读时合并和写时合并),兼顾更新效率和存储开销。

它最实用的特性是“部分列更新”——比如订单表只需更新“状态”和“支付时间”,不用传全量字段,大幅提升更新效率。

(1)建表模版

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

代码语言:javascript
复制

CREATE TABLE order_unique (
    order_id BIGINTCOMMENT'订单ID(主键,唯一标识,不可更新)',
    user_id BIGINTCOMMENT'用户ID',
    goods_id BIGINTCOMMENT'商品ID',
    order_amt DECIMAL(16,2) COMMENT'订单金额(静态列,很少更新)',
    order_status TINYINTCOMMENT'订单状态:0-待支付,1-已支付,2-已取消(高频更新列)',
    create_time DATETIME COMMENT'创建时间(静态列)',
    pay_time DATETIME COMMENT'支付时间(高频更新列)',
    operatorVARCHAR(50) COMMENT'操作人'
)
DISTRIBUTEDBYHASH (order_id) BUCKETS 30
UNIQUEKEY (order_id)
PROPERTIES (
    "replication_num" = "3"
);
(2)适用场景
  • 主键唯一约束场景:订单表(order_id)、用户表(user_id)、商品表(goods_id),避免数据重复写入;
  • 高频更新场景:订单状态(每秒数百次更新)、物流节点更新、商品库存调整;
  • 部分列更新场景:只更新部分字段(如支付时间、状态),无需传全量数据;

3. 聚合表:预聚合提速

聚合表的核心是“写入时预聚合,查询时直接取结果”。建表时指定“聚合Key列”(维度列)和“指标列”(带聚合函数),数据写入时就自动按Key分组聚合,旧数据会被聚合后的结果覆盖——比如100条同一商品的订单记录,最终只存1条“商品ID+总销量”的聚合数据。

它的优势是“存储量小、聚合查询快”,但代价是“丢失原始数据”,只适合固定维度的报表查询。

(1)建表模板

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

代码语言:javascript
复制

CREATE TABLE goods_sales_aggregate (
    dt DATECOMMENT'日期(聚合Key列,维度)',
    goods_id BIGINTCOMMENT'商品ID(聚合Key列,维度)',
    goods_name VARCHAR(100) COMMENT'商品名称(聚合Key列,维度,需和Key列一起聚合)',
    categoryVARCHAR(50) COMMENT'商品分类(聚合Key列,维度)',
    order_cnt SUMBIGINTCOMMENT'下单数量(指标列,求和)',
    sales_amt SUMDECIMAL(16,2) COMMENT'销售金额(指标列,求和)',
    max_price MAXDECIMAL(10,2) COMMENT'最高单价(指标列,取最大)',
    pay_user_cnt COUNT(DISTINCT) BIGINTCOMMENT'支付用户数(指标列,去重计数)'
)
DISTRIBUTEDBYHASH (dt, goods_id) BUCKETS 20
AGGREGATEKEY (dt, goods_id, goods_name, category)
PROPERTIES (
    "replication_num" = "3"
);

(2)适用场景
  • 固定维度报表场景:运营日报、管理层驾驶舱、商品销量排行,查询条件固定(如按天+地区+分类);
  • 高频聚合查询场景:实时GMV统计、实时用户活跃度统计,需要秒级响应;
  • 无需原始数据场景:只关心汇总结果(如商品总销量),不关心单条订单详情;

场景速查表

业务场景

推荐模型

核心原因

用户行为日志分析

明细表

需保留原始日志,支持多维度Ad-hoc查询

电商订单管理

主键表

订单ID唯一,需高频更新状态,兼顾明细查询

运营日报/看板统计

聚合表

固定维度预聚合,查询速度快,支持秒级响应

金融交易流水存档

明细表

监管要求保留全量原始流水,需追溯单条记录

商品维度表(每日更新)

主键表

商品ID唯一,每日更新价格、库存等信息

实时GMV统计

聚合表

按天+地区预聚合,支持秒级查询,存储量小

关键注意点

  • 表类型不可修改:如果选错模型,只能删表重建,建议建表前先做小批量测试;
  • ROLLUP只支持聚合表:主键表和明细表不支持ROLLUP预聚合,想靠ROLLUP提速只能用聚合表;
  • 部分列更新差异:主键表的更新是“覆盖旧值”,聚合表的更新是“聚合叠加”(如SUM列更新是新增值加原有结果)。

经验总结

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

  • 明细表是“仓库”——负责存好原始数据,支持灵活调取;
  • 主键表是“业务系统”——负责核心数据的唯一性和动态更新;
  • 聚合表是“仪表盘”——负责快速展示汇总结果,支撑决策。

很多人建表踩坑,不是模型不好用,而是“用错了场景”——比如用聚合表查明细、用主键表做统计。下次建表前,先对照决策指南过一遍,再结合建表模板调整参数,基本不会出错。

你建表时踩过表模型的坑吗?比如用错模型导致查询慢、更新失败?评论区说下你的场景,我帮你分析该换哪种模型~

往期推荐

Doris BE节点下线卡住?快速排障技巧全攻略!

Apache Doris 索引的全面剖析与使用指南

Apache Doris 湖仓一体:打破数据边界,解锁实时分析的终极答案

Doris vs ClickHouse 企业级实时分析引擎怎么选?

Doris查询报错-230?别慌,教你几招秒解!

Doris Tablet 损坏如何应对?能恢复数据吗?

Doris 导入慢该如何排查和优化

Doris 建表与分区问题全解析

数据极客圈子介绍

圈子1

Apache Doris社区是目前国内最活跃的开源社区(之一)。Apache Doris(Apache 顶级项目) 聚集了世界全国各地的用户与开发人员,致力于打造一个内容完整、持续成长的互联网开发者学习生态圈!

如果您对Apache Doris感兴趣,可以通过以下入口访问官方网站、社区论坛、GitHub和dev邮件组:

💡官网文档:https://doris.apache.org

💡社区论坛:https://ask.selectdb.com

💡GitHub:https://github.com/apache/doris

💡dev邮件组:dev@doris.apache.org

可以加作者微信(Faith_xzc)直接进Doris官方社区群

圈子2

PowerData是由一群数据从业人员,因为热爱凝聚在一起,以开源精神为基础,组成的数据开源社区。

社区群内会定期组织模拟面试、线上分享、行业研讨、线下Meetup、城市聚会、求职内推等活动,同时在社区群内你可以进行技术讨论、问题请教,结识更多志同道合的数据朋友。

社区整理了一份每日一题汇总及社区分享PPT,内容涵盖大数据组件、编程语言、数据结构与算法、企业真实面试题等各个领域,帮助您提升自我,成功上岸。

可以加作者微信(Faith_xzc)直接进PowrData官方社区群

叮咚✨ “数据极客圈” 向你敞开大门,走对圈子跟对人,行业大咖 “唠” 数据,实用锦囊天天有,就缺你咯!快快关注数据极客圈,共同成长!

点击上方公众号关注我们

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据极客圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、先破局:3种表模型的核心区别是什么?
  • 二、逐个解析:原理+建表+场景+避坑
    • 1. 明细表:原汁原味存数据
      • (1)建表模版
      • (2)适用场景
    • 2. 主键表:唯一约束+高频更新
      • (1)建表模版
      • (2)适用场景
    • 3. 聚合表:预聚合提速
      • (1)建表模板
      • (2)适用场景
    • 场景速查表
    • 关键注意点
  • 经验总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档