StarRocks 数据模型深度调研笔记

一、数据模型概览

StarRocks 提供四种表类型:Duplicate Key(明细模型)、Aggregate(聚合模型)、Unique Key(唯一键模型)和 Primary Key(主键模型)。建表时必须指定表类型并定义排序键,数据导入时按排序键排序后存储。

核心共性

  • 排序键(Sort Key):数据导入时按排序键排序存储,查询时可通过排序键快速过滤
  • 前缀索引(Prefix Index):基于排序键自动生成,限制 36 字节
  • 自 v3.0 起 Primary Key 表支持 ORDER BY 独立定义排序键;自 v3.3 起所有表模型均支持
  • 建表后不可修改表类型

参考:https://docs.starrocks.io/docs/table_design/table_types/


二、Duplicate Key 表(明细模型)

2.1 原理与机制

  • StarRocks 默认表模型,未指定时自动创建
  • 追加写入(Append-Only),不支持修改历史数据
  • 相同主键的记录全部保留,不做合并,源数据与存储行一一对应
  • 可定义排序键,查询包含排序键列时加速过滤

2.2 排序机制

  • 建表时通过 DUPLICATE KEYORDER BY 定义排序键
  • 数据导入时按排序键排序后存储
  • 自 v3.3.0 起,支持使用 ORDER BY 指定排序键,可以是任意列的组合
  • 如果同时使用 ORDER BYDUPLICATE KEYDUPLICATE KEY 不生效
  • 如果两者都未使用,默认取表的前三列作为排序键
  • 排序键构建 Prefix Index 加速查询

2.3 数据写入过程

  1. 数据按批次导入(Stream Load / Broker Load / Routine Load 等)
  2. 每批数据按排序键排序后写入数据文件
  3. 数据追加写入,不修改已有数据
  4. 相同键值的记录全部保留,不做合并

2.4 数据读取过程

  1. 根据查询条件,利用排序键和 Prefix Index 快速定位数据
  2. 读取数据文件中的数据
  3. 无需合并多版本,直接返回结果

2.5 适用场景

  • 原始日志分析(如访问日志、操作记录)
  • 时序数据写入(仅追加,不更新历史)
  • 多维度灵活查询,不受预聚合方式限制
  • 需要保留完整原始明细数据的场景

2.6 设计取舍

优势 劣势
完整保留原始数据,无损 不支持更新和删除
写入性能最优(无合并开销) 相同键值数据冗余存储
查询方式灵活,不受预聚合限制 数据量可能较大
支持所有列创建 Bitmap/Bloom Filter 索引 ---

2.7 关键参数

  • DUPLICATE KEY / ORDER BY:定义排序键
  • 自 v3.1 起支持 Random Bucketing(默认),无需指定 HASH 分桶键
  • 自 v2.5.7 起自动设置 BUCKETS 数量
  • 支持在所有列上创建 Bitmap 索引和 Bloom Filter 索引

参考:https://docs.starrocks.io/docs/table_design/table_types/duplicate_key_table/


三、Aggregate 表(聚合模型)

3.1 原理与机制

  • 建表时定义聚合键(Aggregate Key),并为值列指定聚合函数
  • 当多行数据具有相同聚合键时,值列的数据被聚合
  • 数据在三个阶段被多次聚合:
    1. 导入阶段:同一批次中相同聚合键的数据被聚合
    2. 后台 Compaction 阶段:多个版本文件合并时,相同聚合键数据再次聚合
    3. 查询阶段:跨版本相同聚合键数据最终聚合后返回结果

3.2 排序机制

  • 建表时通过 AGGREGATE KEY 定义聚合键(同时也是默认排序键)
  • 自 v3.3.0 起,排序键与聚合键解耦,支持通过 ORDER BY 独立定义排序键
  • 排序键和聚合键的列集合需相同,但列的顺序可以不同
  • 排序键列在聚合前过滤,值列在聚合后过滤 → 建议高频过滤列作为排序键
  • 排序键构建 Prefix Index 加速查询

3.3 数据写入过程

  1. 数据按批次导入,每批形成一个数据版本
  2. 同一版本内,相同聚合键的数据按指定聚合函数聚合
  3. 聚合后的数据按排序键排序写入数据文件
  4. 后台 Compaction 时,多个版本文件合并,相同聚合键数据再次聚合

3.4 数据读取过程

  1. 根据查询条件,利用排序键和 Prefix Index 快速定位数据
  2. 排序键列的过滤在聚合前执行
  3. 跨版本读取数据时,相同聚合键的数据按聚合函数合并
  4. 值列的过滤在聚合后执行
  5. 返回最终聚合结果

3.5 聚合函数类型

内置聚合函数:

  • SUM:求和,适用于数值累加场景
  • MAX:最大值,适用于取最新状态
  • MIN:最小值,适用于取最早状态
  • REPLACE:替换,用新值替换旧值
  • HLL_UNION:HyperLogLog 联合,用于近似去重计数
  • PERCENTILE_UNION:百分位数联合
  • BITMAP_UNION:位图联合,用于精确去重计数

通用聚合函数状态(v3.4+,Beta):

  • 支持所有内置聚合函数的中间状态存储
  • 定义方式:col_name agg_func_name(parameter1_type, [parameter2_type], ...)
  • 示例:avg(bigint)array_agg(int)ds_hll_count_distinct(varchar)
  • 通过 _state/_union/_merge 组合函数实现中间状态流转
  • 可用于同步物化视图和异步物化视图

3.6 适用场景

  • 网站流量统计(PV/UV)
  • 广告点击量/曝光量统计
  • 电商分时段/分区销售汇总
  • 查询以聚合为主(SUM/MAX/MIN),不需要原始明细
  • 历史数据不频繁更新,仅追加新数据

3.7 设计取舍

优势 劣势
减少存储数据量,查询效率高 丢失原始明细数据,无法回溯
导入即聚合,查询时聚合量小 只能更新全部列,不支持部分列更新
支持多种聚合函数 值列只能通过聚合函数访问
v3.4 支持通用聚合函数状态 聚合键具有唯一性约束

3.8 关键参数

  • AGGREGATE KEY:定义聚合键,必须在其值列之前
  • ORDER BY(v3.3+):独立定义排序键,列集合需与聚合键相同但顺序可不同
  • 仅支持在 Key 列上创建 Bitmap/Bloom Filter 索引
  • 导入时只能更新全部列

参考:https://docs.starrocks.io/docs/table_design/table_types/aggregate_table/


四、Unique Key 表(唯一键模型)--- Merge-on-Read

4.1 原理与机制

  • 可视为特殊的聚合模型,值列使用 REPLACE 聚合函数
  • 相同唯一键的多版本数据,查询时返回最大版本号的记录
  • 采用 Merge-on-Read 策略:写入时简单高效,读取时需在线合并多版本数据文件
  • 正在被 Primary Key 表逐步替代

4.2 排序机制

  • 建表时通过 UNIQUE KEY 定义唯一键(同时也是默认排序键)
  • 自 v3.3.0 起,排序键与唯一键解耦,支持通过 ORDER BY 独立定义排序键
  • 排序键和唯一键的列集合需相同,但列的顺序可以不同
  • 排序键构建 Prefix Index 加速查询
  • 查询时排序键列的过滤在合并前执行,值列的过滤在合并后执行

4.3 数据写入过程

  1. 数据分批导入,每批分配版本号
  2. 相同唯一键的记录可能存在于多个版本中
  3. 写入时简单追加,不做在线合并
  4. 后台 Compaction 阶段合并多版本文件

4.4 数据读取过程

  1. 根据查询条件,利用排序键定位数据
  2. 需在线合并多版本数据:对于相同唯一键的记录,取最大版本号的记录返回
  3. Merge 操作阻止谓词和索引下推到底层数据
  4. 版本数越多,查询性能越差

4.5 适用场景

  • 电商订单状态实时更新(数百亿订单,状态频繁变更)
  • 需要实时频繁数据更新的业务场景
  • 对查询延迟要求不极致的更新场景

4.6 设计取舍

优势 劣势
支持实时频繁更新 查询时需聚合多版本,性能受版本数影响
写入简单高效 Merge 操作阻止谓词和索引下推
保证最新数据可见 大量版本严重降低查询性能
--- 只能更新全部列,不支持部分列更新
--- 逐步被 Primary Key 表替代

4.7 关键参数与建议

  • UNIQUE KEY:定义唯一键,必须在其值列之前
  • ORDER BY(v3.3+):独立定义排序键
  • 建议控制导入频率,避免过多版本(如需分钟级数据,导入频率设为 1 分钟而非 1 秒)
  • 仅支持在 Key 列上创建 Bitmap/Bloom Filter 索引
  • 只能更新全部列

参考:https://docs.starrocks.io/docs/table_design/table_types/unique_key_table/


五、Primary Key 表(主键模型)--- Delete+Insert(Merge-on-Write)

5.1 原理与机制

  • 使用 StarRocks 专门设计的新存储引擎
  • 采用 Delete+Insert 策略(Merge-on-Write),而非 Merge-on-Read
  • 核心机制:主键索引 + DelVector(删除标记向量)
  • 主键具有 UNIQUE + NOT NULL 约束
  • 自 v3.0 起排序键与主键解耦
  • 自 v3.1 起支持 shared-data 集群
  • 自 v3.1.4 起支持持久化索引到本地磁盘
  • 自 v3.3.2 起支持持久化索引到对象存储

5.2 排序机制

  • 自 v3.0 起,排序键与主键解耦,通过 ORDER BY 独立定义
  • 排序键可由任意列组合构成
  • 数据导入时按排序键排序后存储
  • 排序键构建 Prefix Index 加速查询
  • 如果未指定排序键,Prefix Index 基于主键构建
  • 建表后可通过 ALTER TABLE ... ORDER BY ... 修改排序键

5.3 数据写入过程

  1. StarRocks 内部 Loadjob 接收一批数据变更操作(Insert/Update/Delete)
  2. 将对应 Tablet 的主键索引加载到内存
  3. DELETE 操作:通过主键索引定位原始行位置(数据文件+行号),在 DelVector 中标记为已删除
  4. UPDATE 操作:先标记旧行删除(DelVector),再将新行写入新数据文件(Delete+Insert)
  5. 主键索引同步更新,记录新行位置
  6. 数据按排序键排序后写入

5.4 数据读取过程

  1. 历史重复记录已在写入时标记删除,只需读取最新行
  2. 无需在线合并多版本数据文件
  3. 谓词和索引可以下推到底层数据
  4. 过滤算子和各种索引减少扫描开销
  5. 查询性能比 Unique Key 的 Merge-on-Read 提升 3-10 倍

5.5 与 Unique Key (MoR) 对比

特性 Unique Key (MoR) Primary Key (MoW)
写入策略 追加多版本 Delete+Insert
读取时合并 需要 不需要
谓词/索引下推 受限(需先合并) 完全支持
查询性能 受版本数影响 稳定高效(3-10x 提升)
内存消耗 需主键索引(可持久化)
部分列更新 不支持 支持
更新方式 只能更新全部列 支持部分列更新

5.6 主键约束

  • PRIMARY KEY 列具有 UNIQUE + NOT NULL 约束
  • 主键列必须在其值列之前定义
  • 主键列必须包含分区列和分桶列
  • 支持数据类型:数值(整数和 BOOLEAN)、字符串、日期(DATE 和 DATETIME)
  • 主键编码后最大长度默认 128 字节
  • 建表后不可修改主键
  • 主键值不可更新(为保持数据一致性)
  • 支持 AUTO_INCREMENT 列作为主键

5.7 主键索引

持久化索引enable_persistent_index = true,默认):

  • 仅小部分索引在内存,大部分存储在磁盘
  • SSD 推荐开启;HDD 低频加载也可开启
  • v3.1.4+ shared-data 支持持久化到本地磁盘
  • v3.3.2+ shared-data 支持持久化到对象存储(persistent_index_type = CLOUD_NATIVE
  • 查询和更新性能与全内存索引几乎等同

全内存索引enable_persistent_index = false):

  • 全部主键索引加载到内存
  • 适用于内存充足、数据量适中的场景

5.8 适用场景

  1. 实时数据流同步:从事务处理系统(MySQL等)通过 CDC 实时同步数据到 StarRocks,支持实时增删改,查询性能比 Unique Key 提升 3-10 倍
  2. 多流 Join + 部分列更新:用户画像场景,上游数据来自多个应用(购物/外卖/银行等),各应用只更新自己业务范围内的列

5.9 关键参数

  • PRIMARY KEY:定义主键
  • ORDER BY:定义排序键(v3.0+)
  • enable_persistent_index:是否持久化主键索引(默认 true)
  • persistent_index_type:持久化索引类型(CLOUD_NATIVE,v3.3.2+)
  • 只支持 Hash 分桶(DISTRIBUTED BY HASH
  • 支持 AUTO_INCREMENT 列作为主键

参考:https://docs.starrocks.io/docs/table_design/table_types/primary_key_table/


六、四种模型对比总结

特性 Duplicate Key Aggregate Unique Key Primary Key
数据合并策略 无(Append-Only) 导入+Compaction+查询聚合 Merge-on-Read Delete+Insert (MoW)
更新支持 不支持 仅全列替换 全列 REPLACE 支持部分列更新
删除支持 不支持 不支持 支持 支持
查询性能 优(无合并开销) 良(预聚合减少数据量) 受版本数影响 优(3-10x vs MoR)
数据完整性 完整保留原始 仅保留聚合结果 仅保留最新 仅保留最新
索引范围 所有列 仅 Key 列 仅 Key 列 所有列
内存开销 中(主键索引)
排序键独立性 v3.3+ ORDER BY v3.3+ ORDER BY v3.3+ ORDER BY v3.0+ ORDER BY
分桶方式 Random/Hash Hash Hash 仅 Hash
推荐场景 日志/时序 统计汇总 逐步淘汰 实时更新/用户画像

七、选型决策树

  1. 是否需要更新/删除数据?
    • 否 → Duplicate Key(明细模型)
    • 是 → 继续
  2. 更新模式是什么?
    • 仅聚合查询,不需原始明细 → Aggregate(聚合模型)
    • 需要保留最新完整记录 → 继续
  3. 对查询性能要求?
    • 极致查询性能 + 实时更新 → Primary Key(主键模型,推荐)
    • 可接受查询时的合并开销 → Unique Key(唯一键模型,逐步淘汰)
  4. 特殊需求?
    • 多流部分列更新(用户画像) → Primary Key
    • CDC 实时同步 → Primary Key

八、参考链接

  1. 表类型概览:https://docs.starrocks.io/docs/table_design/table_types/
  2. Duplicate Key 表:https://docs.starrocks.io/docs/table_design/table_types/duplicate_key_table/
  3. Aggregate 表:https://docs.starrocks.io/docs/table_design/table_types/aggregate_table/
  4. Unique Key 表:https://docs.starrocks.io/docs/table_design/table_types/unique_key_table/
  5. Primary Key 表:https://docs.starrocks.io/docs/table_design/table_types/primary_key_table/
  6. 数据分布:https://docs.starrocks.io/docs/table_design/data_distribution
  7. 索引设计:https://docs.starrocks.io/docs/table_design/indexes/
  8. GitHub 源码:https://github.com/StarRocks/starrocks
相关推荐
可涵不会debug3 小时前
工业大数据时序数据库选型方法论:核心指标与技术适配分析
大数据·数据库·时序数据库
二宝哥3 小时前
大数据之安装HBase2.2.6
大数据
AI_yangxi3 小时前
短视频矩阵系统机构
大数据·人工智能·矩阵
阿坤带你走近大数据3 小时前
Hbase的基本概念,基本用法及常见使用场景
大数据·数据库·hbase
纸鸢|3 小时前
边缘计算+AI:设备振动分析与故障诊断技术实践
大数据·人工智能
瑞华丽PLM3 小时前
国产PLM软件供应商
大数据·人工智能·国产plm·瑞华丽plm·瑞华丽
逆境不可逃3 小时前
【与我学 ClaudeCode】规划与协调篇 之 Skills:按需加载的领域知识框架
大数据·人工智能·elasticsearch·搜索引擎·agent·claudecode
大信说财务3 小时前
发票管理的技术底座:从架构支撑到可信归档
大数据·软件·财务管理·数电票·发票