doris 数据模型
时间: 2025-06-30 18:19:51 浏览: 29
<think>我们正在讨论Doris的数据模型。根据引用内容,Doris主要有三种数据模型:Duplicate(明细模型)、Aggregate(聚合模型)和Unique(唯一主键模型)。下面我将详细解释这三种模型,并给出适用场景。1. **Duplicate模型(明细模型)**:-特点:存储原始数据,不进行任何聚合。即使两行数据完全相同,也会保留。-适用场景:需要保留所有原始数据的场景,如日志分析、行为轨迹等。-建表示例中的`DUPLICATE KEY`实际上是指定排序键(Sorted Column),用于数据排序和前缀索引(引用[3])。2.**Aggregate模型(聚合模型)**:-特点:按照指定的Key列进行聚合,Value列会按照指定的聚合函数(如SUM、MAX、MIN等)进行预聚合。-优点:减少存储空间,提升聚合查询性能。-缺点:对COUNT(*)查询不友好,且当Key字段多或数据量大时,查询性能可能受影响(引用[4])。-适用场景:固定模式的报表类查询,如统计报表、指标计算等(引用[2])。3.**Unique模型(唯一主键模型)**:-特点:根据主键进行去重,对于相同主键的数据,后导入的数据会覆盖之前的数据(或按照指定的序列列确定顺序)。-适用场景:需要实时更新的场景,如用户信息表、订单状态表等。注意:在Aggregate模型中,建表时需要指定Value列的聚合函数,例如:```sqlCREATE TABLEaggregate_tbl (site_idLARGEINT NOTNULL COMMENT"站点id",dateDATE NOTNULL COMMENT"日期",city_codeVARCHAR(20)COMMENT "城市编码",pvBIGINTSUM DEFAULT"0"COMMENT "总访问量")AGGREGATE KEY(site_id,date,city_code)--指定Key列...;```另外,引用[1]中提到一个例子,将用户信息和访问行为放在同一张表中,这在实际的星型模型中可能不是最佳实践,但为了解释数据模型而采用。在实际应用中,需要根据业务需求选择合适的数据模型。下面我们详细说明每种模型:###1. Duplicate模型(明细模型)-存储方式:完全按照导入的数据存储,不做任何聚合。-建表语句中`DUPLICATEKEY`的作用:指定排序键(SortedColumn),用于数据排序和前缀索引(引用[3])。注意,这里的“KEY”并不是数据库意义上的主键,而是用于排序的列。-适用场景:需要保留原始明细数据的场景,例如日志分析、行为分析等。###2.Aggregate模型(聚合模型)-存储方式:按照指定的Key列进行聚合,Value列会按照指定的聚合函数(如SUM、MAX等)进行聚合。-示例:假设我们有一张表记录每个站点每天的访问量,我们可以使用Aggregate模型,将站点ID和日期作为Key列,访问量作为Value列并使用SUM聚合。这样,相同站点和日期的记录会被合并为一条,访问量相加(引用[2])。-限制:-查询时,除了Key列,其他列必须使用聚合函数查询,否则结果可能不符合预期。-对COUNT(*)查询不友好,因为需要扫描所有行(引用[4])。-适用场景:固定模式的报表类查询,例如统计报表、指标计算等。###3.Unique模型(唯一主键模型)-存储方式:根据主键进行去重,相同主键的数据只保留一条(最新导入的数据覆盖旧数据,或者通过指定序列列来确定顺序)。-适用场景:需要实时更新的场景,例如用户信息表、订单状态表等。在选择数据模型时,需要根据业务需求来决定:-如果需要保留所有原始数据,选择Duplicate模型。-如果需要对数据进行预聚合,选择Aggregate模型。-如果需要按主键更新数据,选择Unique模型。此外,引用[3]还提到了ROLLUP和前綴索引。ROLLUP是Doris中一种预聚合的物化视图,可以在Aggregate模型上进一步建立ROLLUP以提高某些查询的性能。前缀索引则是Doris在排序键上建立的索引,用于加速查询。下面是一个三种模型的建表示例对比:
**Duplicate模型建表示例:**
```sqlCREATE TABLEduplicate_model(user_idBIGINT,event_timeDATETIME,event_type VARCHAR(20),device VARCHAR(50)
)DUPLICATE KEY(user_id, event_time)--排序键DISTRIBUTEDBY HASH(user_id)BUCKETS10;```
**Aggregate模型建表示例:**```sqlCREATETABLE aggregate_model (site_id LARGEINT,dateDATE,city_code VARCHAR(20),pvBIGINTSUM DEFAULT"0")
AGGREGATE KEY(site_id,date,city_code)--指定Key列DISTRIBUTED BYHASH(site_id)BUCKETS10;```
**Unique模型建表示例:**
```sqlCREATE TABLEunique_model(user_id BIGINT,usernameVARCHAR(50),emailVARCHAR(100),last_loginDATETIME)
UNIQUE KEY(user_id)--主键DISTRIBUTEDBY HASH(user_id)BUCKETS10;```总结:Doris的三种数据模型各有特点,适用于不同的业务场景。选择合适的数据模型可以极大地提升查询效率和降低存储成本。相关问题:1.在Doris中,如何根据业务需求选择合适的数据模型?2.Doris的Aggregate模型在哪些场景下性能最好?3. Unique模型如何实现数据的更新?4.在Duplicate模型中,排序键(DUPLICATE KEY)的作用是什么?</think>### Doris 数据模型详解
Doris 提供三种核心数据模型,分别针对不同的业务场景设计。以下是详细解析及适用场景对比:
---
#### 一、明细模型(Duplicate Model)
**核心特点**:
- 存储原始明细数据,不做任何聚合
- 即使两行数据完全相同,也会完整保留
- `DUPLICATE KEY` 实质是**排序键**(Sorted Column),用于数据物理排序和前缀索引加速[^3]
**适用场景**:
1. **原始日志存储**:用户行为日志、设备埋点数据
2. **全明细查询**:需要精确查询原始记录的审计场景
3. **无预聚合需求**:数据无主键或无需聚合的宽表
**建表示例**:
```sql
CREATE TABLE user_behavior (
user_id BIGINT,
event_time DATETIME,
event_type VARCHAR(20),
device VARCHAR(50)
)
DUPLICATE KEY(user_id, event_time) -- 排序键
DISTRIBUTED BY HASH(user_id) BUCKETS 8;
```
---
#### 二、聚合模型(Aggregate Model)
**核心特点**[^2][^4]:
- 对 Key 列相同的行自动聚合 Value 列
- Value 列需显式指定聚合函数(SUM/MAX/MIN/REPLACE)
- 查询时自动触发预聚合,大幅减少计算量
**适用场景**:
1. **报表类查询**:固定维度的指标统计(如日销售额)
2. **预计算加速**:高频访问的聚合指标
3. **存储优化**:通过预聚合减少数据量
**限制**:
- `COUNT(*)` 查询效率低(需扫描所有行)
- Key 列过多时影响性能
- 非聚合列查询需谨慎处理语义
**建表示例**:
```sql
CREATE TABLE sales_agg (
product_id BIGINT,
date DATE,
city_code VARCHAR(20),
sales_amount BIGINT SUM, -- 聚合列
max_price DOUBLE MAX
)
AGGREGATE KEY(product_id, date, city_code) -- Key列
DISTRIBUTED BY HASH(product_id) BUCKETS 10;
```
---
#### 三、更新模型(Unique Model)
**核心特点**:
- 基于主键(UNIQUE KEY)进行数据去重和更新
- 最新导入数据覆盖旧数据(或通过序列列指定更新顺序[^2])
- 本质是聚合模型的特殊形式(Value 列使用 REPLACE 聚合)
**适用场景**:
1. **实时数据更新**:用户画像、订单状态变更
2. **CDC 数据同步**:MySQL 等关系型数据库的实时同步
3. **需要主键约束**:避免重复数据的业务场景
**建表示例**:
```sql
CREATE TABLE user_profile (
user_id BIGINT,
username VARCHAR(50),
last_login DATETIME,
credit_score INT
)
UNIQUE KEY(user_id) -- 主键
PROPERTIES (
"function_column.sequence_type" = "DateTime" -- 按时间覆盖旧数据
);
```
---
### 模型对比与选型指南
| 特性 | 明细模型 | 聚合模型 | 更新模型 |
|---------------------|------------------|---------------------|------------------|
| **数据存储** | 原始明细 | 预聚合结果 | 主键最新值 |
| **写入速度** | 最快 | 中等(需聚合计算) | 中等 |
| **查询性能** | 扫描量大 | 聚合查询极快 | 点查极快 |
| **存储空间** | 最大 | 中到小(聚合压缩) | 小(主键去重) |
| **典型场景** | 行为日志分析 | 固定维度报表 | 实时数据更新 |
> **选型建议**:
> - 需要全量明细 → **明细模型**
> - 固定维度报表 → **聚合模型**
> - 主键数据更新 → **更新模型**
---
### 技术原理深度解析
1. **前缀索引机制**
Doris 基于排序键(DUPLICATE KEY)构建前缀索引,有效加速范围查询[^3]。例如 `(user_id, event_time)` 排序后,可快速定位特定用户的时间范围数据。
2. **ROLLUP 物化视图**
在聚合模型基础上,可通过 ROLLUP 创建更高维度的预聚合表:
```sql
ALTER TABLE sales_agg ADD ROLLUP rollup_city (city_code, sales_amount);
```
查询涉及 `city_code` 时将自动路由到 ROLLUP 表加速。
3. **数据更新原理**
更新模型采用 **Merge-on-Read** 机制:
- 写入时标记新旧版本
- 查询时自动合并版本返回最新值
- 后台线程定期压缩历史版本
---
### 实践建议
1. **排序键设计**
- 优先选择高频过滤条件列(如 `user_id`, `event_time`)
- 控制列数在 3-5 个避免索引膨胀
2. **聚合模型陷阱规避**
```sql
-- 错误:非聚合列未指定聚合方式
SELECT city_code, sales_amount, max_price
FROM sales_agg WHERE product_id=100;
-- 正确:显式指定聚合函数
SELECT city_code, SUM(sales_amount), MAX(max_price)
FROM sales_agg WHERE product_id=100
GROUP BY city_code;
```
3. **更新模型优化**
- 启用序列列自动清理旧版本:
```sql
PROPERTIES ("function_column.sequence_col" = "last_update_time")
```
- 控制更新频率,避免高频小批量写入
---
阅读全文
相关推荐



















