早期,数据库写入通常与一笔商业交易(commercial transaction)相对应:如销售、订单等。虽然随数据库发展到不涉及金钱交易的领域,术语 交易/事务(transaction) 仍保留下来,指一组读写操作构成的一个逻辑单元。
事务不一定具备ACID。事务处理只是意味着允许客户端进行低延迟读取和写入,而不是只能周期运行(如每天一次)的批量处理作业。
即使数据库开始被用于许多不同类型的数据,如博客评论,游戏的动作,通讯录的联系人等,但基本访问模式仍类似处理商业交易。应用程序通常使用索引通过某K查找少量记录。根据用户输入新增或更新记录。由于这些应用程序是交互式的,这种访问模式被称为 在线事务处理(OLTP, onLine Transaction Processing) 。
但数据库也越来越多用于数据分析,它们有着很不同的访问模式。通常,分析查询需扫描大量记录,每个记录只读取几列,并计算汇总统计信息(如计数,总和或平均值),而非将原始数据返给用户。例如,若数据是个销售交易表,则分析查询可能包含:
- 一月份每个商店的总收入?
- 在最近的推广活动中多卖了多少香蕉?
- 哪个牌子的婴儿食品最常与X品牌的尿布同时购买?
这些查询通常由业务分析师编写,并提供给帮助公司管理层做出更好决策(商业智能)的报告。为将这种使用数据库的模式和事务处理区分,被称为在线分析处理(OLAP, onLine Analytice Processing)。
表1:事务处理 V.S 分析系统
起初,相同数据库可同时用于事务处理和分析查询。SQL在这方面证明是非常灵活:可同时胜任OLTP及OLAP类型查询。但1980s末和1990s初期,公司放弃使用OLTP系统用于分析,而是在单独数据库上运行分析:数据仓库。
数据仓库(data warehouse)
企业可能有几十个不同交易处理系统:面向终端客户的网站,控制实体店的收银系统,跟踪仓库库存,规划车辆路线,供应链管理,员工管理等。这些系统中每个都很复杂,需专人维护,所以系统最终都是彼此独立运行。
这些OLTP系统往往对业务运作至关重要,因而通常要求高可用 与处理事务时 低延迟。所以DBA会密切关注他们的OLTP数据库,DBA一般不愿意让业务分析人员在OLTP数据库上运行临时分析查询,因为这些查询通常开销巨大,会扫描大量数据集,这会损害并发执行事务的性能。
相比之下,数据仓库是个独立数据库,分析人员可查询他们想要的内容而不影响OLTP操作。数据仓库包含公司各种OLTP系统的只读副本。从OLTP数据库(使用周期数据转储或连续更新流)中提取数据,转换成适合分析的模式,清理并加载到数据仓库中。将数据存入仓库的过程称为“提取-转换-加载(Extract-Transform-Load,ETL)”:
图8:数据仓库和简化的ETL过程
大厂几乎都有数仓,但小厂却少闻。可能是因为小厂没那么多不同OLTP系统,一般只有少量数据,完全可以在传统SQL数据库中直接查询分析,甚至可以在Excel分析。而在大厂,做一些在小厂很简单的事,往往需大量繁重工作。
使用单独的数仓,而非直接查询OLTP系统进行分析,一大优势是数仓能针对分析访问模式进行优化。之前讨论的索引算法对OLTP工作效果很好,但不擅长应对分析查询。
OLTP数据库 V.S 数据仓库
数仓的数据模型通常是关系型,因为SQL通常很适合分析查询。有许多GUI数据分析工具可生成SQL查询,可视化结果,并允许分析人员探索数据(通过下钻,切片和切块等操作)。
表面上,数仓和关系OLTP数据库相似,因为它们都有SQL查询接口。但系统内部很不同,它们针对迥然不同的查询模式,各自进行了优化。许多数据库供应商都专注支持事务处理或分析工作负载,而不是同时支持。
一些数据库(如Microsoft SQL Server和SAP HANA)支持在同一产品中支持事务处理和数仓。但它们正在日益成为两个独立的存储和查询引擎,这些引擎恰好能通过一个通用SQL接口进行访问。
最近,大量开源的基于Hadoop的SQL项目出现,虽然还很年轻,但在与商业数仓系统竞争。入Apache Hive,Spark SQL,Cloudera Impala,Facebook Presto。
星型和雪花型的分析模式
根据应用程序需要,在事务处理领域使用了多种不同数据模型。分析型业务的数据模型则少得多。许多数仓都以相当公式化的方式使用,称为星型模式(也称为维度建模)。
图9中的模式显示了可能在食品零售商处找到的数仓。模式的中心是个事实表(该案例中称为fact_sales)。事实表的每行表示在特定时间发生的事件(这里的每行代表客户购买的产品)。若分析网站流量而非零售量,则每行可能代表一个用户的页面浏览量或点击量:
图9:用于数据仓库的星型模式的示例**
一般事实被捕获为单独事件,因为这样之后的分析中获得最大的灵活性。但是,这意味着事实表可能很大。像苹果这样巨头在数仓可能有几十PB交易历史,其中大部分保存在事实表。
事实表中的列是属性,如产品销售的价格和从供应商处购买的成本(可计算出利润率),其它列是对其他表(称为维度表)的外键引用。由于事实表中的每一行都表示一个事件,因此这些维度代表事件的发生地点,时间,方式和原因。
如图9中,其中一个维度是销售的产品。 dim_product 表中的每行代表一种出售产品,包括库存单位(SKU),说明,品牌名称,类别,脂肪含量,包装尺寸等。fact_sales 表中的每行都使用外键表示在特定交易中销售了哪些产品。(为简单起见,如果客户一次购买几种不同产品,则它们在事实表中被表示为单独行)。
日期和时间通常使用维度表来表示,因为这允许对日期的附加信息(如公共假期)进行编码,从而允许查询区分假期和非假期的销售。
“星型模式”名字来源:当表关系可视化时,事实表在中间,被一系列维度表包围;与这些表的连接就像星星的光芒。
该模板的变体为雪花模式,其中维度被进一步分解为子维度。如品牌和产品类别可能有单独表格,且dim_product 表格中的每行都能再次将品牌和类别作为外键,而不是将它们作为字符串直接存储在 dim_product 表。雪花模式比星形模式更规范化,但星形模式是首选,因为对于分析师,它更简单。
典型数仓中,表格通常很宽:
- 事实表格通常超过100列,有时甚至数百列;
- 维度表也可能很宽,因为它们包括可能与分析相关的所有元数据。如dim_store 表可能包括在每个商店提供哪些服务的细节,是否具有店内面包房,店面面积,商店开张日期,最后一次装修时间,距离最近的高速公路有多远等。