Doris进阶(进阶使用)

是什么

海量大数据进行快速分析的MPP(Massively Parallel Processing 大规模并行处理)数据库。

干嘛的

就是数据库存储数据,重点是不光能存储明细数据,还支持数据聚合。

三种数据模型

Aggregate 模型

聚合模型,几列值定义为key(维度列) ,其余列定义为value(指标列),当我们导入数据时,对于 Key 列相同的行会聚合成一行,而 Value 列会按照设置的 AggregationType 进行聚合。 AggregationType 目前有以下四种聚合方式:

  • SUM:求和,多行的 Value 进行累加。
  • REPLACE:替代,下一批数据中的 Value 会替换之前导入过的行中的 Value。
  • MAX:保留最大值。
  • MIN:保留最小值。

 

例子,参考官网提供:

建表:

 CREATE TABLE IF NOT EXISTS example_db.expamle_tbl ( `user_id` LARGEINT NOT NULL COMMENT "用户id", `date` DATE NOT NULL COMMENT "数据灌入日期时间", `city` VARCHAR(20) COMMENT "用户所在城市", `age` SMALLINT COMMENT "用户年龄", `sex` TINYINT COMMENT "用户性别", `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间", `cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费", `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间", `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间", ) AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) ... /* 省略 Partition 和 Distribution 信息 */ ;

导入数据(原始数据):

user_id

date

city

age

sex

last_visit_date

cost

max_dwell_time

min_dwell_time

10000

2017-10-01

北京

20

0

2017-10-01 06:00:00

20

10

10

10000

2017-10-01

北京

20

0

2017-10-01 07:00:00

15

2

2

10001

2017-10-01

北京

30

1

2017-10-01 17:05:45

2

22

22

10002

2017-10-02

上海

20

1

2017-10-02 12:59:12

200

5

5

10003

2017-10-02

广州

32

0

2017-10-02 11:20:00

30

11

11

10004

2017-10-01

深圳

35

0

2017-10-01 10:00:15

100

3

3

10004

2017-10-03

深圳

35

0

2017-10-03 10:20:22

11

6

6

 

导入到 Doris 中后,Doris 中最终存储如下:

user_id

date

city

age

sex

last_visit_date

cost

max_dwell_time

min_dwell_time

10000

2017-10-01

北京

20

0

2017-10-01 07:00:00

35

10

2

10001

2017-10-01

北京

30

1

2017-10-01 17:05:45

2

22

22

10002

2017-10-02

上海

20

1

2017-10-02 12:59:12

200

5

5

10003

2017-10-02

广州

32

0

2017-10-02 11:20:00

30

11

11

10004

2017-10-01

深圳

35

0

2017-10-01 10:00:15

100

3

3

10004

2017-10-03

深圳

35

0

2017-10-03 10:20:22

11

6

6

可以看到,用户 10000 只剩下了一行聚合后的数据。

 

数据的聚合三个阶段:

  1. 每一批次数据导入的 ETL 阶段。该阶段会在每一批次导入的数据内部进行聚合。
  2. 底层 BE 进行数据 Compaction 的阶段。该阶段,BE 会对已导入的不同批次的数据进行进一步的聚合。
  3. 数据查询阶段。在数据查询时,对于查询涉及到的数据,会进行对应的聚合。

 

Uniq 模型

特殊的Aggregate 模型,value列所有的AggregationType均为replace。

建表语句:(这里的主键为 user_id + username)

CREATE TABLE IF NOT EXISTS example_db.expamle_tbl ( `user_id` LARGEINT NOT NULL COMMENT "用户id", `username` VARCHAR(50) NOT NULL COMMENT "用户昵称", `city` VARCHAR(20) COMMENT "用户所在城市", `age` SMALLINT COMMENT "用户年龄", `sex` TINYINT COMMENT "用户性别", `phone` LARGEINT COMMENT "用户电话", `address` VARCHAR(500) COMMENT "用户地址", `register_time` DATETIME COMMENT "用户注册时间" ) UNIQUE KEY(`user_id`, `user_name`) ... /* 省略 Partition 和 Distribution 信息 */ ;

 

表结构:

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

用户注册时间

 

完全等价于

建表语句:

CREATE TABLE IF NOT EXISTS example_db.expamle_tbl ( `user_id` LARGEINT NOT NULL COMMENT "用户id", `username` VARCHAR(50) NOT NULL COMMENT "用户昵称", `city` VARCHAR(20) REPLACE COMMENT "用户所在城市", `age` SMALLINT REPLACE COMMENT "用户年龄", `sex` TINYINT REPLACE COMMENT "用户性别", `phone` LARGEINT REPLACE COMMENT "用户电话", `address` VARCHAR(500) REPLACE COMMENT "用户地址", `register_time` DATETIME REPLACE COMMENT "用户注册时间" ) AGGREGATE KEY(`user_id`, `user_name`) ... /* 省略 Partition 和 Distribution 信息 */ ;

表结构:

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 模型

明细存储,数据既没有主键,也没有聚合需求。

建表语句:

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 信息 */ ;

表结构:

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

处理时间

 

重点功能:ROLLUP

“上卷”,将数据按某种指定的粒度进行进一步聚合。

两个作用:

1、在聚合表的基础上,按照其他维度再进一步聚合,提升查询效率。

原表结构:

Base 表结构如下:

ColumnName

Type

AggregationType

Comment

user_id

LARGEINT

 

用户id

date

DATE

 

数据灌入日期

timestamp

DATETIME

 

数据灌入时间,精确到秒

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

用户最小停留时间

存储的数据如下:

user_id

date

timestamp

city

age

sex

last_visit_date

cost

max_dwell_time

min_dwell_time

10000

2017-10-01

2017-10-01 08:00:05

北京

20

0

2017-10-01 06:00:00

20

10

10

10000

2017-10-01

2017-10-01 09:00:05

北京

20

0

2017-10-01 07:00:00

15

2

2

10001

2017-10-01

2017-10-01 18:12:10

北京

30

1

2017-10-01 17:05:45

2

22

22

10002

2017-10-02

2017-10-02 13:10:00

上海

20

1

2017-10-02 12:59:12

200

5

5

10003

2017-10-02

2017-10-02 13:15:00

广州

32

0

2017-10-02 11:20:00

30

11

11

10004

2017-10-01

2017-10-01 12:12:48

深圳

35

0

2017-10-01 10:00:15

100

3

3

10004

2017-10-03

2017-10-03 12:38:20

深圳

35

0

2017-10-03 10:20:22

11

6

6

在此基础上,我们创建一个 ROLLUP:

ColumnName

user_id

cost

该 ROLLUP 只包含两列:user_id 和 cost。则创建完成后,该 ROLLUP 中存储的数据如下:

user_id

cost

10000

35

10001

2

10002

200

10003

30

10004

111

可以看到,ROLLUP 中仅保留了每个 user_id,在 cost 列上的 SUM 的结果。那么当我们进行如下查询时:

SELECT user_id, sum(cost) FROM table GROUP BY user_id;

Doris 会自动命中这个 ROLLUP 表,从而只需扫描极少的数据量,即可完成这次聚合查询。

2、Doris索引是固定的前缀索引,用rollup改变索引顺序

Base 表结构如下:

ColumnName

Type

user_id

BIGINT

age

INT

message

VARCHAR(100)

max_dwell_time

DATETIME

min_dwell_time

DATETIME

我们可以在此基础上创建一个 ROLLUP 表:

ColumnName

Type

age

INT

user_id

BIGINT

message

VARCHAR(100)

max_dwell_time

DATETIME

min_dwell_time

DATETIME

可以看到,ROLLUP 和 Base 表的列完全一样,只是将 user_id 和 age 的顺序调换了。那么当我们进行如下查询时:

SELECT * FROM table where age=20 and massage LIKE "%error%";

会优先选择 ROLLUP 表,因为 ROLLUP 的前缀索引匹配度更高。

 

相关语法:

partiiton

show partitions from table;

alter table table_name drop partition IF EXISTS p20200926;

alter table table_name add partition IF NOT EXISTS p20201004 values less than('20201004');

ROLLUP

可以通过 EXPLAIN your_sql; 命令获得查询执行计划,在执行计划中,查看是否命中 ROLLUP。

可以通过 DESC tbl_name ALL; 语句显示 Base 表和所有已创建完成的 ROLLUP。

 

ALTER TABLE table1 ADD ROLLUP rollup_city(citycode, pv); 创建作业

SHOW ALTER TABLE ROLLUP 可以查看当前正在执行或已经完成的 Rollup 作业。

CANCEL ALTER TABLE ROLLUP FROM tbl_name;

 

原理:敬请期待,进阶再进阶

 

参考文档:

http://doris.apache.org/master/zh-CN/

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值