前言
Doris是百度自研的交互式 SQL 数据仓库,其前身是 Palo ,Palo 是百度自研的基于 MPP 的交互式 SQL 数据仓库,主要用于解决报表和多维分析。现简单介绍Doris的数据模型。
基本概念
Doirs与传统的关系库相同,都是以表(Table)的形式存储数据,其中一张表包括行Row和列Column。
Column分为两类:Key和Value,从业务角度看,Key和Value可以分别对应维度和指标列。
Doris主要包括三种数据模型:Aggregate、Uniq和Duplicate,也是这篇文章主要介绍的。
Aggregate 模型(聚合模型)
假设业务有如下数据表
ColumnName | Type | AggregationType | Comment |
---|---|---|---|
user_id | LARGEINT | 用户id | |
date | DATE | 数据灌入日期 | |
city | VARCHAR(20) | 用户所在城市 | |
age | SMALLINT | 用户年龄 | |
sex | TINYINT | 用户性别 | |
last_visit_date | DATETIME | REPLACE | 用户最后一次访问时间 |
cost | BIGINT | SUM | 用户总消费 |
max_dwell_time | INT | MAX | 用户最大停留时间 |
min_dwell_time | INT | MIN | 用户最小停留时间 |
表中的列没有设置Aggregation Type的列称为Key,而设置了Aggregation Type的称为Value。
目前共有四种Aggregation Type聚合类型,如下所示:
1 sum:求和,多行value累加
2 replace:替代,后插入的Value替代之前的Value
3 max:保留Value最大值
4 min:保留Value最小值
原理:实际导入数据中相当于会根据Key进行Group By,然后Value值输出相应Aggregation Type的结果。与使用聚合函数后的sql相同,明细数据会丢失,只保留聚合后的结果。如果想要保留明细数据,可以加入Key字段Timestamp从而保证每一行的Key都不相同。
Uniq模型(唯一主键)
在某些多维分析场景下,用户更关注的是如何保证 Key 的唯一性,即如何获得 Primary Key 唯一性约束。因此Doris引入了 Uniq 的数据模型。该模型本质上是聚合模型的一个特例,也是一种简化的表结构表示方式。
假设业务有如下数据表
ColumnName | Type | IsKey | Comment |
---|---|---|---|
user_id | BIGINT | Yes | 用户id |
username | VARCHAR(50) | Yes | 用户昵称 |
city | VARCHAR(20) | No | 用户所在城市 |
age | SMALLINT | No | 用户年龄 |
sex | TINYINT | No | 用户性别 |
phone | LARGEINT | No | 用户电话 |
address | VARCHAR(500) | No | 用户住址 |
register_time | DATETIME | No | 用户注册时间 |
而这个表结构,完全同等于以下使用聚合模型描述的表结构:
ColumnName | Type | AggregationType | Comment |
---|---|---|---|
user_id | BIGINT | 用户id | |
username | VARCHAR(50) | 用户昵称 | |
city | VARCHAR(20) | REPLACE | 用户所在城市 |
age | SMALLINT | REPLACE | 用户年龄 |
sex | TINYINT | REPLACE | 用户性别 |
phone | LARGEINT | REPLACE | 用户电话 |
address | VARCHAR(500) | REPLACE | 用户住址 |
register_time | DATETIME | REPLACE | 用户注册时间 |
Duplicate 模型(冗余模型)
在某些多维分析场景下,数据既没有主键,也没有聚合需求。例如常见的日志表log。
假设业务有如下数据表
ColumnName | Type | SortKey | Comment |
---|---|---|---|
timestamp | DATETIME | Yes | 日志时间 |
type | INT | Yes | 日志类型 |
error_code | INT | Yes | 错误码 |
error_msg | VARCHAR(1024) | No | 错误详细信息 |
op_id | BIGINT | No | 负责人id |
op_time | DATETIME | No | 处理时间 |
建表语句如下:
CREATE TABLE IF NOT EXISTS example_db.expamle_tbl
(
`timestamp` DATETIME NOT NULL COMMENT "日志时间",
`type` INT NOT NULL COMMENT "日志类型",
`error_code` INT COMMENT "错误码",
`error_msg` VARCHAR(1024) COMMENT "错误详细信息",
`op_id` BIGINT COMMENT "负责人id",
`op_time` DATETIME COMMENT "处理时间"
)
DUPLICATE KEY(`timestamp`, `type`)
... /* 省略 Partition 和 Distribution 信息 */
;
这种数据模型区别于 Aggregate 和 Uniq 模型。数据完全按照导入文件中的数据进行存储,不会有任何聚合。即使两行数据完全相同,也都会保留。 而在建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。(更贴切的名称应该为 “Sorted Column”,这里取名 “DUPLICATE KEY” 只是用以明确表示所用的数据模型。
reference
https://github.com/apache/incubator-doris/wiki/Data-Model%2C-Rollup-%26-Prefix-Index