“面对每天几十上百亿条的数据流入,Doris如何合理地设计存储模型?这是摆在每位数据工程师面前的一道必答题。 合适的表模型设计就像建筑的地基,一旦根基不稳,上层再华丽的架构都会成为空中楼阁。明细模型能留存全量数据但查询吃力,主键模型擅长实时更新但不适合预聚合,聚合模型查询飞快但失去了灵活性...每种模型都像是把双刃剑,用好了锦上添花,用错了徒增烦恼。 今天,一起来学习Doris不同表模型的应用场景,让你在处理海量数据时胸有成竹,不再迷茫。
不知道你有没有遇到过这样的场景:
刚接手一个数据分析项目,面对纷繁复杂的业务需求,一筹莫展 - 是选择明细模型保留所有原始数据,还是用聚合模型提升查询性能?数据需要更新时,又该如何选择合适的主键模型?
说实话,在Doris表模型的选择上,我也曾走过不少弯路。曾经因为盲目追求查询性能而处处使用聚合模型,结果遇到临时性的多维分析需求时,才发现数据的灵活性被极大地限制了。
数据就像流水,需要一个恰当的容器来承载。Doris提供了三种表模型,就像三种不同的容器,各自有着独特的特点和适用场景。今天,我们就一起深入了解这三种表模型,掌握它们的使用艺术。
明细模型是最简单直观的表模型,它保留了数据的原始面貌。就像一部高清纪录片,每一帧画面都清晰完整地记录下来。
在日志分析系统中,我们会记录用户的每次点击、每次操作、每条错误信息。这些数据没有聚合的需求,也不需要保证唯一性,使用明细模型再合适不过。它不仅能够保存全量数据,还能按照指定的列进行排序,方便后续的查询分析。
CREATE TABLE user_logs
(
timestamp DATETIME,
user_id BIGINT,
action VARCHAR(32),
device VARCHAR(64),
location VARCHAR(128)
)
DUPLICATE KEY(timestamp, user_id)
DISTRIBUTED BY HASH(user_id);
在用户画像系统中,我们需要存储用户的基础信息、标签属性等数据。这些数据会随着用户行为不断更新,需要保证每个用户ID只对应一条最新记录。主键模型通过保证key列的唯一性,完美地满足了这一需求。
新版本的Doris(2.1以后)默认采用写时合并实现,极大地提升了查询性能。它就像一个智能管家,在数据写入时就完成了整理工作,确保查询时能够快速找到需要的信息。
聚合模型是Doris中最富特色的表模型,它通过预聚合机制大幅提升了查询性能。让我们通过一个电商分析场景来深入理解它的魅力。
假设我们需要统计各个商家的每日销售额。在传统模式下,每次查询都需要扫描所有订单数据再做聚合,面对海量数据时性能往往难以满足需求。而使用聚合模型,我们可以这样设计:
CREATE TABLE shop_sales
(
shop_id BIGINT,
sale_date DATE,
province VARCHAR(32),
total_amount DECIMAL(16,2) SUM,
order_count BIGINT SUM,
user_count BIGINT COUNT_DISTINCT
)
AGGREGATE KEY(shop_id, sale_date, province);
这个设计有几个精妙之处:
经过多年的实践,X总结出一套模型选择的思路:
1.数据特征分析
2.性能目标权衡
3.场景匹配度
1.聚合模型性能优化
使用agg_state类型处理复杂聚合,它能在保持灵活性的同时提供优秀的性能:
CREATE TABLE user_metrics
(
user_id BIGINT,
metric_date DATE,
visit_stats agg_state<group_concat(string)> generic
)
AGGREGATE KEY(user_id, metric_date);
2.主键模型更新优化
对于频繁更新的场景,启用部分列更新能显著提升性能:
CREATE TABLE user_profile
(
user_id BIGINT,
nickname VARCHAR(32),
avatar VARCHAR(256),
tags VARCHAR(1024)
)
UNIQUE KEY(user_id)
PROPERTIES(
"enable_unique_key_merge_on_write" = "true",
"enable_unique_key_partial_update" = "true"
);
掌握了这些技巧,相信你已经能够从容基于Doris应对各种数据分析场景。
欢迎在评论区分享你在使用Doris表模型时的心得体会。下一篇,我们将深入探讨Doris的其它特性,敬请期待!