当前位置: 首页 > 科技观察

大数据和Hadoop时代的维度建模和Kimball数据集市

时间:2023-03-14 14:51:14 科技观察

维度建模已死?在回答这个问题之前,让我们先回过头来看看什么叫做维度数据建模。为什么需要对数据建模?有一个普遍的误解,认为数据建模的目的是用ER图来设计物理数据库,其实远不止于此。数据建模代表了企业业务流程的复杂性,记录了重要的业务规则和概念,有助于规范企业的关键术语。它阐明并帮助公司发现业务流程中的模糊想法和歧义。此外,数据模型可用于与其他利益相关者进行有效沟通。没有蓝图就不可能建造房屋或桥梁。那么,如果没有数据模型这样的蓝图,为什么要构建数据应用程序,比如数据仓库呢?为什么我们需要维度建模?维度建模是一种特殊的数据建模方法。维度建模有两个同义词,数据集市和星型模式。星型结构是为了更好的数据分析。参考下图的维度模型可以有一个非常直观的认识。通过它,您可以立即知道如何按客户、产品、时间划分订单,以及如何通过指标的聚合和比较来评估订单业务流程的绩效。维度建模最关键的一点是定义事务业务流程中的最大粒度是多少。如果您切割或钻取数据,则无法钻取到叶级别。从另一个角度看,星型结构中的最大粒度,即事实和维度之间没有聚合。数据建模和维度建模标准数据建模的任务是消除重复和冗余数据。当数据发生变化时,我们只需要在一处进行修改,这样有助于保证数据的质量,避免异地数据不同步。考虑下图所示的模型,其中包含几个代表地理概念的表格。在规范化模型中,每个实体都有一张独立的表,数据建模只有一张表:geography。在这个表中,city会出现很多次。而且对于每一个城市,如果国家改了名字,很多地方都要更新。注意:标准数据模型始终遵循3NF模式。标准数据建模本身并不是为商业智能工作负载设计的。表太多会导致关联太多,表关联又会导致性能下降。我们在数据分析中一定要尽量避免这种情况。在数据建模过程中,通过反规范化将多个相关表合并为一个表。例如,前面例子中的多个表被预先合并成一个地理表。那么为什么有些人认为维度建模已经死了呢?大多数人都认同数据建模的方式,将维度建模视为一种特殊的处理方式。它们都很有价值。那为什么在大数据和Hadoop时代,有人认为维度建模没有用呢?“数据仓库之死”首先,有些人混淆了维度建模和数据仓库。他们认为数据仓库已经死了,并得出结论,维度建模也可以被扔进历史的垃圾箱。这个论点在逻辑上是一致的,但是,数据仓库的概念远未过时。我们总是需要集成的、可靠的数据来生成商业智能仪表盘(BIDashboards)。只读结构的误区经常听到的第二种说法,比如“我们以只读的方式遵循结构(Schema),所以不需要再对数据进行建模”。在我看来,这是数据分析中最大的误解之一。我同意起初只转储原始数据,此时不要过多考虑结构是有道理的。但是,这不应成为不对数据建模的借口。只读结构只是降低了下游系统的能力和责任,有些人不得不硬着头皮定义数据类型。每个访问无模式数据转储的进程都需要弄清楚自己发生了什么,这是完全多余的。通过定义数据类型和适当的结构可以很容易地避免这些工作。有关非规范化和物理模型的更多信息促进维度建模的想法真的过时了吗?确实有一些想法比上面列出的两个更好,理解它们需要对物理建模和Hadoop的工作原理有一定的了解。前面简要提到的采用维度建模的原因之一与数据的物理存储方式有关。标准数据建模中的每个现实世界实体都有自己的表。我们这样做是为了避免数据冗余和质量问题在数据中蔓延。表越多,需要的关联就越多,这是标准建模的缺点。表连接很昂贵,尤其是在关联链接数据集中的大量记录时。当我们考虑维度建模时,将多个表组合在一起,这称为预关系或数据反规范化。最终结果是更少的表、更少的连接、更低的延迟和更好的查询性能。参与LinkedIn上的相关讨论。彻底反规范化为什么不彻底反规范化?删除所有表关联并只保留一个表?确实,这不需要任何表关联,但可想而知,它会带来一些负面影响。首先,由于要存储大量冗余数据,因此需要更多的存储空间。现在随着用于数据分析的列式存储格式的出现,这不再是一个令人担忧的问题。反规范化最大的问题是,每次一个属性值发生变化,都要更新很多地方,可能要更新几千甚至几百万。一种解决方案是在晚上完全重新加载模型,这通常比增量更新更快、更容易。列式数据库通常采用这种方法,首先将要进行的更新存储在内存中,然后将它们异步写入磁盘。分布式关系数据库(MPP)上的数据分布在Hadoop上,如Hive、SparkSQL建立维度模型。有必要对一个技术核心特性有一个很好的理解,那就是它在分布式关系数据库(MPP)上的建立。方式不同。通过在MPP中跨节点分布数据,可以控制每个数据记录的位置。基于Hash、List、Range等分区策略,每条记录的键值可以跨表co-located在同一个节点上。由于数据局部性得到保证,因此关联速度非常快,因为不需要通过网络发送数据。参考下图示例,ORDER表和ORDER_ITEM表中ORDER_ID相同的记录存储在同一个节点上:ORDER表和ORDER_ITEM表中ORDER_ID对应的键值位于同一个节点上。Hadoop上的数据分布基于Hadoop的系统中的数据分布非常不同,我们将数据分成大块(chunks),并在Hadoop分布式文件系统(HDFS)中跨节点分布和复制。这种数据分布策略不能保证数据的一致性。参考下面的示例,记录ORDER_ID的键存储在不同的节点上:为了关联它们,需要通过网络发送数据,这会影响性能。处理此问题的一种策略是在集群中的所有节点上复制要连接的表,这种策略称为广播连接。如果将相同的策略用于MPP,可以想象它只能用于较小的查找表或维度表。那么当关联一个大的事实表和一个大的维表,比如customer或者product,甚至是两个大的事实表,我们应该怎么办呢?为了解决性能问题,Hadoop上的维度建模可以使用非规范化将大维度表放入事实表中以确保数据共存,而较小的维度表可以在所有节点上广播。当关联两个大型事实表时,可以将较低粒度的表嵌套在较高粒度的表中,例如将ORDER_ITEM表嵌套在ORDER表中。高级查询引擎,例如Impala或Drill,可以扁平化数据:嵌套数据的策略很有用,类似于使用桥接表表示维度模型中的M:N关系的Kimball概念。Hadoop和缓慢变化的维度Hadoop文件系统中的存储是不可变的,换言之,记录只能插入和追加,数据不能修改。如果您熟悉关系数据仓库,这可能看起来有点奇怪。但从内部机制来看,数据库的工作机制是类似的。在进程异步更新数据文件中的数据之前,所有更改都保存在一个不可变的预写日志(WAL-write-aheadlog,Oracle)中。称为重做日志)。不变性如何影响维度模型?您可能还记得维度建模课程中的渐变维度(SCDS)概念。SCDS可选择保留属性值变化的历史记录,以便可以在某个时间点测量属性值。但这不是默认的做事方式。默认情况下,维度表将更新为最新值。那么在Hadoop上如何选择呢?记住!我们无法更新数据。我们可以简单地为SCD选择默认值并审核每个更改。如果您想根据当前值运行报告,您可以在SCD之上创建一个仅检索最新值的视图,这可以使用Windows功能轻松完成。或者,可以运行所谓的压缩服务,以物理方式创建具有最新值的维度表的单独版本。Hadoop存储演进Hadoop平台供应商并没有忽视这些Hadoop限制,例如Hive提供了符合ACID的事务和可更新的表。根据众多重大未解决问题和个人经验,此功能尚未准备好用于生产部署。Cloudera另辟蹊径,利用Kudu建立了一种新的可变存储格式,这种存储格式不基于HDFS,而是基于本地OS操作系统。完全摆脱了Hadoop的约束,类似于传统的列式MPP的存储层。一般来说,任何在MPP上跑BI和Dashboard的使用场景,比如Impala+Kudu,都会比Hadoop好。话虽如此,它在弹性、并发性和可伸缩性方面有其自身的局限性。当遇到这些限制时,Hadoop及其近亲Spark是解决BI工作负载的不错选择。结论:维度模型和星型模式是否过时了?众所周知,RalphKimball已经退休,但他的思想和设计原则概念仍然有效并将继续存在。即使我们必须使它们适应新技术和存储类型,它们仍然可以提供巨大的价值。