基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

讲讲Doris 的三大数据模型:明细模型(Duplicate)、聚合模型(Aggregate)和主键模型(Unique)和各自的适用场景是什么?

Apache Doris 是一款高性能的 MPP 分析型数据库,其存储引擎在设计之初就引入了数据模型(Data Model)的概念。选择合适的数据模型是使用 Doris 的第一步,它直接决定了数据的存储方式、更新逻辑以及查询性能。

Doris 的三大核心数据模型分别是:明细模型(Duplicate)聚合模型(Aggregate)主键模型(Unique)

下面为您详细讲解这三种模型及其适用场景:


1. 明细模型 (Duplicate Model)

🔍 概念讲解:
明细模型是最基础、最简单的模型。在明细模型中,数据是按原样追加存储的。即使你插入了两条完全相同的数据,Doris 也会原封不动地保留这两条记录,不会进行任何去重或聚合操作。你可以指定排序键(Sort Key),它的作用仅仅是建立前缀索引以加速查询,并不具备唯一性约束。

✨ 核心特点:

  • Append-Only(仅追加): 写入性能极高,因为不需要在底层做任何数据的合并或查找。
  • 保留所有历史细节: 每一条操作记录、每一行日志都会被完整记录。

🎯 适用场景:
适用于需要保留所有原始数据记录、不需要修改旧数据、只关注数据追加的场景。

  • 日志分析: 服务器日志、应用运行日志(如 Log4j 产生的日志)。
  • 用户行为埋点: 用户的每一次点击、浏览、跳转都需要被单独记录,以供后续做漏斗分析或路径分析。
  • 物联网(IoT)时序数据: 传感器每秒上报一次的温度、湿度数据。

💡 举个例子:
记录用户点击流。同一用户在同一秒钟疯狂点击了某个按钮 3 次,明细模型会原样记录这 3 次点击事件,方便后续查阅这 3 次独立的动作。


2. 聚合模型 (Aggregate Model)

🔍 概念讲解:
聚合模型是为了加速统计分析而设计的。在建表时,你需要将列分为维度列(Key)指标列(Value),并为指标列指定聚合函数(如 SUM, MAX, MIN, REPLACE 等)。
当新数据写入时,Doris 会在后台(导入时或 Compaction 时)自动将维度列相同的多行数据合并为一行,并根据指定的聚合函数计算指标列的值。

✨ 核心特点:

  • 预聚合: 在数据存储层面就完成了计算,极大减少了数据量(Data Volume)。
  • 查询极快: 因为查询时大部分数据已经聚合完毕,直接读取结果即可,属于典型的“空间换时间”或“写入时计算换取查询时性能”。

🎯 适用场景:
适用于数据报表、BI 看板等不需要查询原始明细,只关注统计结果的场景。

  • 网站流量统计: 统计每天、每个网页的 PV(SUM)、UV(BITMAP_UNION)等。
  • 财务报表: 统计每个门店、每天的营业总额、最大单笔交易额等。
  • 广告计费: 按天/小时统计某个广告位的点击量和消耗金额。

💡 举个例子:
表维度为“日期”、“城市”,指标为“销售额(SUM)”。
早上写入:[2023-10-01, 北京, 100]
下午写入:[2023-10-01, 北京, 200]
在底层存储中,这两条数据会自动合并为一条:[2023-10-01, 北京, 300]。你再也查不到 100 和 200 这两条明细了。


3. 主键模型 (Unique Model)

🔍 概念讲解:
主键模型可以看作是聚合模型的一种特殊形式(指标列的聚合函数全部为 REPLACE 的变种),但在语义和底层实现上又有所不同。
它的核心作用是保证主键(Key)的唯一性。当写入主键相同的新数据时,新数据会覆盖(Upsert)旧数据。

注:Doris 在较新版本(1.2 之后)为主键模型引入了 Merge-on-Write (MoW) 机制,使得主键模型在支持高频更新的同时,查询性能得到了质的飞跃(与明细模型相当)。

✨ 核心特点:

  • 支持行级别更新与删除: 能够精确修改或删除某一条特定数据。
  • 状态最新: 针对同一个主键,永远只保留最新的一条状态数据。

🎯 适用场景:
适用于数据会发生状态变更、需要与业务关系型数据库(OLTP)保持同步的场景。

  • CDC 数据同步: 从 MySQL、Oracle 等数据库通过 Flink CDC / Canal 实时同步过来的业务数据(如 Binlog)。
  • 订单状态流转: 订单从“待付款” -> “已付款” -> “已发货”,同一个订单号的数据需要不断被更新。
  • 用户画像: 用户的基本信息(如会员等级、手机号)发生了修改。

💡 举个例子:
同步电商订单表。主键为“订单ID”。
昨天写入:[订单001, 待付款, 09-01 10:00]
今天写入:[订单001, 已发货, 09-02 15:00]
由于订单ID相同,底层只会保留今天写入的“已发货”这条最新数据。


🌟 总结与对比表格

为了方便记忆,可以用下表进行对比:

模型对比 明细模型 (Duplicate) 聚合模型 (Aggregate) 主键模型 (Unique)
数据处理方式 原样追加,保留所有重复记录 按维度键合并,指标列自动计算聚合 按主键合并,新数据覆盖旧数据
是否支持更新 ❌ 否 (Append Only) 🔺 支持部分 (通过 Replace 聚合) ✅ 是 (Row-level Upsert/Delete)
底层数据量 最大 (保留所有明细) 最小 (自动合并压缩) 较小 (只留最新状态)
写入性能 ⭐️⭐️⭐️⭐️⭐️ (极高) ⭐️⭐️⭐️⭐️ (较高) ⭐️⭐️⭐️ (中等,因需要处理更新逻辑)
适用场景关键词 日志、埋点、明细流水 报表、BI看板、大盘统计 CDC同步、订单状态、数据覆盖

选型建议:

  1. 业务需要查明细吗?如果需要,但也有更新需求,选 Unique
  2. 业务只需要看宏观统计汇总,不需要查任何明细?选 Aggregate
  3. 数据就像流水一样不断产生,永远不会被修改?闭眼选 Duplicate
00:00
00:00