十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

数据立方体从OLAP到大数据引擎的演进与BI建模实战

数据立方体从OLAP到大数据引擎的演进与BI建模实战 数据立方体这个词放到现在很多人第一反应是“老古董”。但你真去用Excel拉一张数据透视表或者在Power BI里拖几个字段做聚合图表本质上都在跟数据立方体打交道。从传统BI时代到大数据分析时代这一套“按维度预组织数据”的思想一直没有消失只是不断换载体、换实现方式。这篇文章不打算讲太多教科书定义我更想以一个实际做过报表、搭过数仓的人的角度把数据立方体从OLAP到大数据引擎的演进脉络讲清楚顺带说一些能直接用在工作里的建模和踩坑经验。如果你正准备入门BI学习或者已经在用Power BI、FineBI、永洪这类工具但总觉得“模型调优”是个玄学那这篇内容应该能帮你把底层逻辑补上。看懂数据立方体怎么演进你才能真正理解为什么有的报表秒开有的报表拖死数据库。1. 从Excel数据透视表说起理解数据立方体的第一课1.1 你早就用过数据立方体了很多人第一次接触“多维分析”不是从什么高大上的数据仓库开始的而是在Excel里做数据透视表。比如你手里有一张销售明细表字段大概是日期、门店、品类、销售额。你在Excel里把“门店”拖到行标签把“品类”拖到列标签把“销售额”拖到值区域再拖一个“月份”作为筛选器。这一套操作做完你实际上已经完成了一次典型的多维查询维度是门店和品类度量是销售额筛选器就是切片条件。把门店、品类、日期看成三条互相垂直的坐标轴每个坐标轴的刻度就是该维度的成员坐标轴围出来的那个空间里每一个格点都对应一个聚合值。这就是数据立方体的直观印象。当维度是三个的时候它确实是个“立方体”。真实业务里维度往往是十个二十个这时候它已经不是几何意义上的立方体了而是“超立方体”但大家还是习惯叫它数据立方体。这个视角很重要。因为当你明白了透视表的“行、列、筛选器、值”就是立方体里的“维度拆解、切片、度量”你就能明白后面所有BI工具的核心逻辑——无论工具多先进底层都是这一套。1.2 OLAP与“切片、切块、钻取”那套标准动作数据立方体真正成体系是在OLAP这个概念被提出之后。OLAP在线分析处理英文全称On-Line Analytical Processing它和OLTP是相对的——OLTP处理的是交易OLAP处理的是分析。OLAP把数据分析人员面对的操作规范成了四类动作切片Slice、切块Dice、钻取Drill Down/Up、旋转Pivot。切片就是固定其中一个维度只看剩下的维度。你只看“华东区”这一家门店的数据就是把“门店”这个维度切掉了一层。切块是同时固定多个维度圈定一个子集。钻取是从高粒度往低粒度走比如从“年”下钻到“季度”再钻到“月”很多报表做的“点击图表下钻”就是这个操作。旋转简单说就是互换行列维度就像透视表里把行标签和列标签对调。这四类操作组合起来覆盖了业务分析里90%以上的探索式查询。数据立方体之所以在传统BI时代这么重要就是因为它提前把这四类操作对应的聚合结果算好了分析人员点击报表的时候系统直接返回预计算结果而不是现场去扫描几百万行明细再临时聚合所以体验是“秒开”。2. 传统BI时代数据立方体如何撑起企业报表体系2.1 维度建模与星形模型要理解传统BI里的数据立方体是怎么搭起来的得先说维度建模。维度建模是数据仓库领域的老祖宗Kimball提出的一套方法论核心就两样东西事实表和维表。事实表存度量比如订单金额、销售数量、成本同时它存一堆外键用来关联各个维表。维表存描述属性比如日期维表里有年、季度、月、日、星期几门店维表里有区域、城市、店名、店长。事实表在中间维表像星星一样散在周围这个结构就是星形模型。比如一张销售事实表CREATE TABLE sales_fact ( date_key INT, store_key INT, product_key INT, customer_key INT, sales_amount DECIMAL(12,2), sales_qty INT, cost_amount DECIMAL(12,2) );对应的维表有日期维、门店维、产品维、客户维。查询的时候把事实表和维表做JOIN就能在任意维度组合上做聚合。为什么星形模型这么流行因为它契合了数据立方体的基本需求维表提供“坐标轴的刻度信息”事实表提供“坐标格点上的度量值”。同时维表被独立出来之后维度属性的修改不会影响事实表维护成本低。我见过不少刚接触数仓的同学一上来就把所有字段塞进一张大宽表里觉得这样查询快。但宽表一旦维度过高字段多到几百上千列BI前端建模反而寸步难行。事实表维表的结构本质上是给数据立方体做了一个清晰的“坐标系统”。2.2 MOLAP、ROLAP、HOLAP哪种方案更合适传统BI时代搭建数据立方体主要面临三种存储方式的选择MOLAP、ROLAP、HOLAP。MOLAP把聚合结果提前算好存成多维数组结构。查询时不需要访问明细所以速度极快。但它的代价是构建时间长、存储空间膨胀严重。假设你有5000万行事实数据10个维度每个维度平均有100个成员不做任何优化地做全量预聚合结果集规模可能会膨胀到原始数据的数十倍。ROLAP的思路是明细仍然留在关系数据库里系统不真正预计算所有聚合结果而是查询时动态生成SQL去执行聚合。它的好处是能处理超大数据量数据更新及时缺点就是查询速度没法和MOLAP比复杂度高的查询可能几十秒甚至几分钟。HOLAP则是混合方案高频聚合结果预计算低频、高维度组合的查询回落到明细层。我自己的经验是如果数据量在千万级以下查询模式固定MOLAP体验是最好的如果数据量到了亿级甚至更高报表查询又比较灵活全量MOLAP会非常痛苦。早期很多做传统BI报表优化的都把精力花在寻找“哪些组合预聚合、哪些组合不预聚合”的平衡点上这个矛盾后来也直接催生了大数ew一代引擎的解法。2.3 传统立方体的几个软肋传统BI里的立方体在时代背景下立了大功但它的缺点也相当明显。首先是预聚合构建时间不可控。我曾经处理过一套保险行业的报表事实表两亿多行十几个维度。每次立方体刷新要在晚间跑批先抽取数据、再做校验、再执行全量预聚合一个流程下来经常要跑六到八个小时。如果当天临时发现源数据有问题意味着整晚白跑。其次是存储膨胀。预聚合结果会复制大量中间计算数据原本2TB的事实数据构建完立方体可能要占用6TB甚至更多存储。老项目组最头疼的就是扩容申请因为领导很难理解“为什么数据没多存储却涨了几倍”。再有就是扩展性差。传统BI的立方体大多跑在单机或者几台服务器上处理能力有天花板。数据量翻倍的时候不是简单加一台机器就能解决的很多时候要重新设计模型。而且传统立方体的架构比较封闭分析人员必须在相对固定的维度体系内做探索一旦出现新的维度和度量维度组合就要重新设计和构建。人员和公司如果刚好用了杂牌厂商的BI产品还容易遇到bi publisher下载也好、文档也罢都很零碎的问题踩起坑来格外费劲。3. 大数据分析时代立方体从“重型构建”变成“轻量策略”3.1 打破“全量预聚合”的神话进入大数据时代之后数据量从TB级跃升到PB级维度更多、更新更快、查询更灵活传统那种“一次性把全维度组合全部预计算好”的思路彻底走不通了。你想一下如果事实表有100亿行20个维度每个维度取两个粒度光组合数就是2的20次方也就是100多万种组合。如果一个组合平均需要扫描一遍事实表这个构建工程在传统架构下根本没法做。所以新一代大数据OLAP引擎的第一个突破口就是放弃“全量预聚合”改成“部分预聚合”加“查询时计算兜底”。这是什么意思呢简单说引擎会判断哪些维度组合被高频查询比如日期城市、日期品类就把这些组合的聚合结果预先算好。剩下的组合比如日期城市品类客户等级这种低频组合不预先计算查询时可以直接回落到明细数据做实时聚合或者用上层粒度的结果再做二次聚合。这套思路的本质还是“数据立方体”的预聚合思想只是从“全都要”变成了“按需来”。3.2 开源引擎们如何“重新设计”立方体这个思路落地到工程上催生了大量我们耳熟能详的开源OLAP引擎。拿Apache Kylin举例它是非常典型的“全量/增量预聚合”引擎。用户定义好一个Cube模型指定维度、度量、层级Kylin会在构建任务里生成成千上万个Cuboid同一Cube的各个维度组合的聚合结果然后持久化到HBase或者对象存储里。查询时直接命中Cuboid所以响应速度是毫秒级。Kylin的短板在于Cube的构建和更新偏重适合固定的分析场景。再说Apache Druid它做的事情是把时序数据和事件数据做预聚合Segment内会按时间做粗粒度聚合同时保留明细段设计思路非常贴近“按时间维度切片”的立方体。ClickHouse严格来说不是传统意义上的数据立方体引擎但它的MergeTree系列表引擎和物化视图能力配合AggregatingMergeTree其实完全可以实现“维度预聚合实时查询兜底”的数据立方体效果。我实际项目里就用ClickHouse做过一张日维度的预聚合表只有原始明细的几十分之一大小却能支撑绝大部分报表查询。还有Apache Pinot、StarRocks、Doris等等它们虽然各有侧重但核心路径不外乎列式存储、向量化执行、稀疏索引、物化视图。列式存储本身就可以理解为把数据按“列维度”预组织好物化视图更是直接复制了预聚合的思想。3.3 为什么查询快本质还是预聚合很多人会有一个误解大数据引擎查询快是因为分布式计算能力强。这当然没错但你让一个查询去扫描100亿行并且实时GROUP BY十几个字段再强的分布式集群也得几秒钟甚至更久。真正让交互式看板达到毫秒级响应的是“聪明的预组织”把高频的查询结果提前算好查询时直接读取结果。这就是数据立方体思想的精髓。它没有消失而是下沉了。以前数据立方体是BI软件里的一个独立模块需要专门构建、专门维护。现在它变成了存储引擎的底层能力变成了物化视图、变成了预聚合表、变成了Column Family设计。所以你在用大数据平台看报表的时候表面上看是在“查数据”背后的技术架构里往往静悄悄地藏了一整套“基于维度预聚合”的立方体逻辑。你理解了这一点再去看任何BI工具的优化文档都会通透很多。4. 现代数据分析实战用Cube思想建模、查询与调优4.1 现代多维建模的通用流程不管你是用传统BI还是大数据OLAP引擎建模流程大同小异核心其实就是四个问题业务过程是什么、粒度是什么、维度是什么、度量是什么。以零售行业为例。业务过程是“订单销售”粒度定到“订单行项目”也就是每一行明细代表一个商品在一个订单中的销售记录。维度包括日期、门店、品类、客户。度量包括销售额、销售量、成本。建模时先把这些定义清楚再落表。多花15分钟把口径理清后面至少省下三个晚上的返工时间。4.2 用SQL CUBE/Rollup在查询中复现立方体聚合理解了立方体的概念后你会发现标准SQL里早就内置了立方体的查询能力。比如用PostgreSQL、Spark SQL或者Hive你可以直接用GROUP BY CUBESELECT COALESCE(store_name, 全部门店) AS store, COALESCE(category_name, 全品类) AS category, SUM(sales_amount) AS total_sales FROM sales_fact f JOIN store_dim s ON f.store_key s.store_key JOIN category_dim c ON f.category_key c.category_key GROUP BY CUBE(s.store_name, c.category_name) ORDER BY store, category;执行结果会返回所有维度组合的聚合值门店品类、仅门店、仅品类、总计一共2的2次方等于4组聚合结果。多维拓展到3个字段就是8组依此类推。GROUP BY ROLLUP则是按维度层级逐级汇总适用于时间层级、组织层级的“钻取”逻辑。平时做大数据分析的时候很多同学习惯用多个GROUP BY语句分别算数再合并实际上一个CUBE子句就能全部搞定查询代码更简洁执行引擎还能共享中间结果性能有明显优势。4.3 从Excel透视表到Power BI、FineBI、永洪建模观念的统一到了BI工具层面数据立方体已经变成了一个“半自动”的能力但你的建模观念不能跟着变懒。Power BI的做法是把数据导入自身的内存列式引擎VertiPaq你建立表关系之后写DAX度量的时候它内部会自动做聚合和筛选。这个“表关系度量”的模型本质上就是一个数据立方体模型只是DAX帮你掩盖了底层实现。比如写一个累计销售额销售额累计 : CALCULATE( SUM(sales_fact[sales_amount]), FILTER( ALL(日期维), 日期维[日期] MAX(日期维[日期]) ) )这段DAX不是扫描明细而是依托Power BI内置的维度坐标做筛选聚合。你要是懂立方体的“钻取”逻辑写这种复杂度量的时候思路会清晰很多——很多时候度量不对不是DAX语法问题而是你的维度关系没建对。FineBI和永洪这类国产BI理念也类似。它们都提供了可视化建模界面连接数据源之后把维度字段、度量字段拖出来系统自动组织成多维模型。我见过不少同学在这些工具里拖字段拖半天做不出正确数据打开“数据模型定义”一看维度表关系完全断了当然不对。所以我的建议是不管用Power BI教程里的哪种技巧还是FineBI操作手册里的哪个功能先把你手上的表按照“事实表维表”的思路理一遍再进工具点鼠标。模型对了报表就成了一半。4.4 容量估算与性能调优的一个实例在实际做预聚合设计的时候最常被问到的问题就是“我要物化哪些组合物化后占多大空间”这里给一个粗糙但是非常有用的估算方法。假设你有一张2亿行的销售事实表需要支持的维度及成员数量是日期维度365天门店维度1000家品类维度50个。如果不做任何预聚合原始行数已经是2亿光扫描就够呛。如果选择物化“日期门店品类”这个三维组合可能的最大行数就是365100050等于1825万行。每条聚合记录假设50字节那么物化这份数据大概在91MB左右。这个体量完全可接受查询还是毫秒级。但如果你的模型里再加一个“客户维度”客户数量是100万那么日期门店品类客户这个组合的上限就是365100050*1000000这个数字已经大到没有任何存储系统能撑住全量预聚合。所以实践上高频报表只物化到“日期门店品类”这一层客户维度相关的分析回落到明细查询或者用“上卷”结果再二次聚合。这就是“部分预聚合”策略的工程落地。用这个估算方法你在设计数仓和BI模型的时候就能提前预判性能瓶颈而不是等报表上线后被打个措手不及。5. 常见问题与排查技巧实录5.1 高频问题速查表我把实际项目里经常踩的坑整理了一下做成速查表遇到类似情况可以先按这个方向排查问题现象可能原因解决思路BI报表聚合结果和SQL查明细对不上事实表重复比如关联维表时出现多对多度量口径定义不一致用COUNT(*)检查事实表唯一性对比两个查询的过滤范围是否一致立方体构建或刷新特别慢预聚合组合选得过全或者源数据抽取过程有跨库JOIN精简物化组合只保留高频维度把数据抽取改成增量同步预聚合占用空间太大存储成本飙升物化组合过多维度成员组合爆炸用上一节的容量估算方法复核砍掉低频组合BI工具连接SAP系统数据库后查询很慢直接在业务源库上做分析查询挤压生产系统资源把SAP数据通过ETL抽取到独立数仓或BI加速层不要在生产库上跑重型报表苹果手机使用FineBI平台时出现屏幕滑动异常退出Bug移动端页面元素过多低内存机型渲染崩溃先升级APP到最新版报表页面减少组件数量避免一次性加载大量图表问题持续就提工单并附复现路径同样的数据Power BI和Excel透视表结果不一样两边使用的日期表粒度不同或者筛选上下文不同统一数据口径在Power BI里显式建立独立的日期维度表不要依赖自动日期层级BI报表导出PDF/Excel时内容错乱BI Publisher类工具渲染机制不同分页规则不一致先预览再导出导出时禁用“自动分页”关键报表用固定宽度布局5.2 真正能救命的几个实操心得第一建模不要贪多。很多人一上来就把十几个维度全塞进立方体里结果半年之后发现其中一半维度从来没人用过构建时间却被这些无用维度拖慢了好几倍。我现在的习惯是模型上线前先和业务方确认前三名的分析视角会是什么只做主维度和高频维度跑通之后再迭代加维度。第二构建时长要和业务时效性对齐。有些项目非要追求“实时报表”但数据源本身每天才更新一次你就算把刷新频率提到每分钟也只是白白消耗计算资源。先看业务决策的真实时效再决定用批处理、微批还是实时计算不要为了技术上的“酷”去做过度设计。第三用历史最大数据量做性能测试。不少报表项目在demo阶段跑得飞快拿几千行测试数据测构建时间看着都是毫秒级结果一上线面对真实数据就直接超时。我在项目里会在联调阶段刻意准备一份“最大数据量场景”的测试数据集至少覆盖日常峰值的1.5倍用这份数据测构建、测查询、测并发。第四移动端BI的兼容性问题比想象中多。FineBI这类平台在手机浏览器上体验还可以但部分老款iPhone打开复杂报表页面时因为渲染元素太多确实容易出现卡顿甚至退出的问题。我的建议是移动报表单独做一套精简布局每个页面展示的图表控制在三四个以内不是把桌面端的十几个图表原样搬到手机端就叫“移动BI”。关于网关上跟SAP系统数据库对接我也多提一句。很多企业直接让BI工具直连SAP业务库图省事但SAP业务库往往对并发查询很敏感。我处理过一个案例BI报表日常跑批稳定一到月末财务结账高峰期报表查询就把SAP拖得死死的最后只能把财务相关报表全部切到数仓的旁路读取问题才解决。做数据分析的人一定要记住BI的查询尽量别压在生产系统上。回到开头说的数据立方体这个概念听起来像是上个时代的东西但实际上它从Excel数据透视表一路演进到了大数据OLAP引擎核心逻辑始终没变把数据按维度预先组织好让分析查询更快。个人这几年做下来越来越觉得工具可以换引擎可以换但“维度、度量、粒度、预聚合”这几个词想通了做什么都比别人快半拍。如果你正准备学数据分析我的建议还是那句先把Excel数据透视表玩明白把维度拆解搞清楚再上Power BI、FineBI或者任何一款大数据产品都会事半功倍。
返回列表