下一篇【第02篇】ClickHouse横空出世——天下武功唯快不破


摘要

数据分析技术的发展历程,本质上是一部不断追求"更快、更高、更强"的性能优化史。从最早的关系型数据库到 Hadoop 生态,再到现在以 ClickHouse 为代表的现代 OLAP 引擎,每一次技术浪潮都解决了一批旧问题,同时也带来了新的挑战。本文从 BI 系统的发展演变出发,系统梳理了 OLAP 技术的架构分类与演进路径,深入剖析了 ROLAP、MOLAP、HOLAP 三大架构的原理与取舍,并通过详实的架构对比和 SQL 示例,帮助读者建立对 OLAP 技术生态的完整认知。最终引出一个核心命题:是否存在一种技术,能够兼具 ROLAP 的灵活性与 MOLAP 的高性能?ClickHouse 的诞生正是对这一问题的有力回应。

关键词:OLAP、数据仓库、列式存储、星型模型、ROLAP、MOLAP、HOLAP、Hive、ClickHouse


1. 引言:一座桥梁的诞生

想象一下这样一个场景:一家电商平台的运营团队,每天要处理数亿条交易记录,需要实时查看今日GMV、各品类销售额、用户复购率等关键指标。如果使用传统的 Oracle 数据库,查询可能需要几分钟甚至更长时间——这对于分秒必争的业务决策来说无异于灾难。但如果告诉你,有一种技术可以在毫秒级别完成这些聚合查询,同时支持数十亿行数据的深度分析,你是否会感到惊讶?

这就是 ClickHouse——一款来自俄罗斯的列式存储分析型数据库,它的名字虽然听起来像一个轻巧的"点击仓库",但其性能却足以让整个数据分析领域为之侧目。在深入了解 ClickHouse 之前,我们需要先理解它所处的大背景:数据分析技术是如何一步步演进到今天的?传统 BI 系统遇到了哪些困境?现代 OLAP 技术又是如何解决这些问题的?

本文将带你踏上一段从传统 BI 到现代 OLAP 的技术演进之旅。


2. 传统BI系统之殇

2.1 BI的诞生与数据孤岛问题

要理解 BI(Business Intelligence,商业智能),我们需要把时间拨回到上世纪90年代。那时的企业信息化建设刚刚起步,ERP(企业资源计划)系统处理日常事务,CRM(客户关系管理)系统管理销售和客户数据。然而,随着企业数据量的增长,一个尖锐的问题浮现出来——数据孤岛

所谓数据孤岛,指的是企业各个业务系统之间数据相互隔离、无法互通的状态。销售部门的数据在 CRM 里,财务数据在 ERP 里,仓储数据在 WMS 里。这些数据就像一座座孤岛,彼此无法联通,企业管理层想要获取一份全面的经营报告,往往需要 IT 部门耗费数周时间,从各个系统导出数据、手工清洗合并。

数据仓库(Data Warehouse)的概念正是在这一背景下提出的。1990年,Bill Inmon 首次提出了数据仓库的定义:一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。数据仓库的核心思想是将企业各个数据源的数据统一抽取、转换、加载(ETL)到一个集中式存储中,从而打破数据孤岛,为企业提供一个统一的数据视图。

2.2 传统BI的三大困境

数据仓库虽然解决了数据孤岛问题,但传统 BI 系统在实际应用中又遇到了新的瓶颈。我将其总结为"三高"困境:

第一高:门槛高。传统 BI 系统对企业的信息化水平要求极高。企业需要具备完善的数据治理体系、规范的数据模型、高素质的数据团队。中小企业往往无力承担这些成本。

第二高:受众窄。传统 BI 的主要用户是企业管理层和决策层。普通业务人员想要自助分析数据?门都没有。数据分析成了一项"贵族运动"。

第三高:周期长。一个典型的传统 BI 项目,从需求调研、方案设计、数据建模、开发部署到最终上线,往往需要半年甚至更长时间。业务需求变化快,BI 系统的响应却慢如蜗牛。

┌──────────────────────────────────────────────────────────────┐
│                    传统 BI 系统的困境                         │
├─────────────────┬───────────────────────────────────────────┤
│     困境类型     │                   具体表现                 │
├─────────────────┼───────────────────────────────────────────┤
│    门槛高        │ 需要专业数据团队、规范数据治理、高额投入    │
│    受众窄        │ 仅服务于管理层,普通员工难以自助分析        │
│    周期长        │ 项目周期半年起步,无法快速响应业务变化      │
│    性能差        │ 数据量增长后查询缓慢,无法支撑实时分析      │
└─────────────────┴───────────────────────────────────────────┘

2.3 传统数据库的性能瓶颈

除了上述业务层面的问题,传统 BI 在技术层面也面临严峻挑战。回想一下,当数据量从 GB 级别增长到 TB 级别时,Oracle、MySQL 这类行式存储数据库的查询性能会出现什么样的变化?

答案是:灾难性的下降。

假设我们有一张存储了 10 亿行交易记录的 orders 表,业务需要统计每个月的销售额:

SELECT 
    DATE_FORMAT(order_date, '%Y-%m') AS month,
    SUM(order_amount) AS total_sales,
    COUNT(DISTINCT customer_id) AS unique_customers
FROM orders
WHERE order_status = 'completed'
GROUP BY DATE_FORMAT(order_date, '%Y-%m')
ORDER BY month;

在 MySQL 的行式存储引擎中,这条查询需要全表扫描——每一条订单记录都要读取,而且由于 SUMGROUP BY 操作,数据需要在内存中进行大量计算。当数据量达到数十亿行时,这样的查询可能需要数分钟甚至更长时间。

问题出在哪里?答案是存储架构。行式存储将一行的所有字段连续存放,读取时需要把整行数据都加载到内存中。但分析查询往往只需要某些列(如 order_dateorder_amount),其他列的数据完全是"陪读"。这种"读一整行却只用几列"的模式,在大数据场景下造成了巨大的 I/O 浪费。


3. 现代BI系统的新思潮

3.1 技术普惠浪潮

2010年以后,云计算、SaaS(软件即服务)和开源运动三股力量交汇,一股"技术普惠"的浪潮席卷了整个 IT 行业。数据分析领域也不例外:

  • 云计算降低了基础设施的门槛,企业不再需要自建机房即可获得海量计算和存储能力。
  • SaaS模式让 BI 工具变得轻量、易用,无需复杂的部署和培训即可上手。
  • 开源运动催生了大量优秀的数据工具,如 Hive、Spark、Kylin 等,极大地降低了技术成本。

3.2 现代BI的四大特征

在这股浪潮的推动下,现代 BI 系统呈现出与传统 BI 截然不同的面貌:

特征 传统BI 现代BI
用户定位 管理层少数人 全员普惠,一线业务人员
部署方式 重型私有化部署 轻量 SaaS 或云原生
数据时效 T+1 甚至 T+N 实时或准实时
分析深度 预定义报表 自助探索式分析

现代 BI 的核心变化可以用一句话概括:数据分析从"贵族运动"变成了"全民运动"。一线运营人员、市场营销人员甚至客服人员,都可以自助拖拽生成数据报表,实时洞察业务状态。

3.3 OLAP:现代BI的发动机

支撑现代 BI 变革的技术核心是 OLAP(Online Analytical Processing,联机分析处理)。与 OLTP(联机事务处理)不同,OLAP 专注于复杂查询和聚合分析,典型操作包括:

  • 切片(Slicing):在一个维度上筛选数据
  • 切块(Dicing):在多个维度上筛选数据
  • 钻取(Drilling):从汇总数据深入到明细数据
  • 旋转(Pivoting):变换维度的方向

OLAP 的经典查询场景可以用以下 SQL 体现——假设我们有一张电商宽表 dws_sales_daily

-- 场景1:按时间维度切片
SELECT 
    stat_date,
    category_name,
    SUM(sales_amount) AS total_sales,
    SUM(sales_quantity) AS total_qty,
    AVG(unit_price) AS avg_price
FROM dws_sales_daily
WHERE stat_date BETWEEN '2024-01-01' AND '2024-12-31'
  AND region = '华东'
GROUP BY stat_date, category_name
ORDER BY stat_date, total_sales DESC;

-- 场景2:钻取操作(从年到季度到月)
SELECT 
    YEAR(stat_date) AS year,
    QUARTER(stat_date) AS quarter,
    MONTH(stat_date) AS month,
    SUM(sales_amount) AS total_sales
FROM dws_sales_daily
WHERE YEAR(stat_date) = 2024
GROUP BY YEAR(stat_date), QUARTER(stat_date), MONTH(stat_date)
ORDER BY year, quarter, month;

OLAP 引擎的设计目标,就是让这类复杂聚合查询能够在海量数据上快速返回结果。那么,如何实现这一目标?这就引出了 OLAP 的架构分类。


4. OLAP常见架构分类

4.1 ROLAP:关系型OLAP

ROLAP(Relational OLAP) 是最符合直觉的一种 OLAP 架构。它的核心思想是:仍然使用关系型数据库存储数据,直接用 SQL 进行查询

在数据建模层面,ROLAP 通常采用星型模型(Star Schema)雪花模型(Snowflake Schema)

-- 星型模型示例
-- 事实表:销售事实表
CREATE TABLE fact_sales (
    id BIGINT PRIMARY KEY,
    date_key INT,
    product_key INT,
    customer_key INT,
    store_key INT,
    sales_amount DECIMAL(12, 2),
    sales_quantity INT
);

-- 维度表:日期维度
CREATE TABLE dim_date (
    date_key INT PRIMARY KEY,
    full_date DATE,
    year INT,
    quarter INT,
    month INT,
    day_of_week INT,
    is_weekend BOOLEAN
);

-- 维度表:产品维度
CREATE TABLE dim_product (
    product_key INT PRIMARY KEY,
    product_id VARCHAR(50),
    product_name VARCHAR(200),
    category_id INT,
    category_name VARCHAR(100),
    brand VARCHAR(100)
);

星型模型的特点是以事实表为中心,维度表围绕四周呈放射状。维度表通常是非规范化的(denormalized),以减少 JOIN 操作、提高查询性能。雪花模型则是将维度表进一步规范化拆分,形成类似雪花的层次结构。

ROLAP 的优势

  • 兼容标准 SQL,学习成本低
  • 数据存储在关系型数据库中,易于理解和管理
  • 支持任意维度的实时聚合,灵活性高
  • 可以查询明细数据

ROLAP 的劣势

  • 复杂聚合查询(如多表 JOIN + GROUP BY)的性能在大数据量下难以保证
  • 需要预计算大量中间结果时,资源消耗巨大
  • 维度组合爆炸时,查询性能急剧下降

4.2 MOLAP:多维型OLAP

MOLAP(Multidimensional OLAP) 采用了"空间换时间"的策略。它的核心思想是:预先将数据按照多维模型进行聚合,存储在专用的多维数组结构中

以 Apache Kylin 为例,它会在 HBase 中预计算各种维度组合的聚合结果:

┌─────────────────────────────────────────────────────────────┐
│                    MOLAP 预计算示意                          │
├─────────────────────────────────────────────────────────────┤
│  原始数据: 10亿行销售记录                                     │
│                                                              │
│  预计算的 Cuboid(维度组合):                                 │
│  - (date)              → 1个 Cuboid                          │
│  - (date, product)     → 1个 Cuboid                          │
│  - (date, store)       → 1个 Cuboid                          │
│  - (date, product, store) → 1个 Cuboid                      │
│  - ...                                                        │
│  总计: 2^N 个 Cuboid(N为维度数)                            │
│                                                              │
│  查询时: 直接从预计算的 Cuboid 中读取,性能极快               │
└─────────────────────────────────────────────────────────────┘

假设有 4 个分析维度(日期、产品、门店、用户等级),MOLAP 引擎会预先计算所有 2^4=16 种维度组合。当用户执行以下查询时:

SELECT 
    date,
    product,
    store,
    SUM(sales_amount) AS total
FROM fact_sales
GROUP BY date, product, store;

MOLAP 引擎只需要从预计算的 (date, product, store) Cuboid 中读取数据即可,无需实时计算——这就是它能够实现毫秒级响应速度的秘密。

MOLAP 的优势

  • 查询性能极快,适合固定报表场景
  • 不依赖底层数据库的计算能力
  • 适合高并发查询场景

MOLAP 的劣势

  • 维度组合爆炸问题:维度数量增长时,存储空间呈指数级增长。10个维度 = 1024个 Cuboid,20个维度 = 超过100万个 Cuboid
  • 无法实时分析:新数据需要经过预计算过程才能被查询到
  • 无法查询明细数据:只能看到预聚合的结果,细节信息丢失
  • 灵活性差:无法支持未预定义的维度组合查询

4.3 HOLAP:混合型OLAP

HOLAP(Hybrid OLAP) 是 ROLAP 和 MOLAP 的折中方案,试图结合两者的优势:

  • 对于常用的维度组合,使用 MOLAP 预计算以获得极快的查询速度
  • 对于非常用的查询或明细查询,回退到 ROLAP 模式实时计算
特性 ROLAP MOLAP HOLAP
数据存储 关系型数据库 多维数组 混合存储
查询性能 中等 极快 中等到快
实时性 中等
明细查询 支持 不支持 部分支持
存储开销 中等
灵活性 中等

5. OLAP实现技术的演进

5.1 传统关系型数据库阶段

回顾历史,OLAP 技术的发展可以划分为几个阶段。最早的 OLAP 能力是由传统关系型数据库提供的。Oracle 在 1998 年引入了 Bitmap Index(位图索引)物化视图 两大特性,试图在行式存储上实现 OLAP 加速:

-- 在日期维度上创建位图索引
CREATE BITMAP INDEX idx_order_date ON orders(order_date);

-- 创建聚合物化视图
CREATE MATERIALIZED VIEW mv_monthly_sales
BUILD IMMEDIATE
REFRESH COMPLETE ON DEMAND
AS
SELECT 
    TRUNC(order_date, 'MM') AS month,
    product_category,
    COUNT(*) AS order_count,
    SUM(order_amount) AS total_amount
FROM orders
GROUP BY TRUNC(order_date, 'MM'), product_category;

然而,当数据量从 GB 级跨越到 TB 级时,传统关系型数据库的扩展性成为致命瓶颈。Oracle RAC 虽然可以水平扩展,但成本高昂;MPP(大规模并行处理)数据库如 Teradata、Greenplum 虽然性能强劲,但动辄数百万的 licensing 费用让大多数企业望而却步。

5.2 大数据技术阶段

2006年,Hadoop 的开源标志着大数据时代的到来。Hive 的诞生让 SQL 技能的数据分析师也能处理海量数据:

-- Hive SQL 示例:按渠道和日期统计转化率
SELECT 
    dt AS stat_date,
    channel,
    COUNT(DISTINCT visitor_id) AS visitors,
    COUNT(DISTINCT CASE WHEN action = 'purchase' THEN visitor_id END) AS buyers,
    ROUND(
        COUNT(DISTINCT CASE WHEN action = 'purchase' THEN visitor_id END) * 100.0 
        / COUNT(DISTINCT visitor_id), 2
    ) AS conversion_rate
FROM user_behavior_log
WHERE dt >= '2024-01-01' AND dt <= '2024-12-31'
GROUP BY dt, channel
ORDER BY stat_date, conversion_rate DESC;

Hive 的底层是 HDFS + MapReduce。MapReduce 的批处理模式虽然能够处理海量数据,但延迟高、交互性差。随后出现的 ImpalaPrestoSpark SQL 等查询引擎,通过内存计算和向量化执行,显著提升了查询性能:

┌─────────────────────────────────────────────────────────────────┐
│              大数据 OLAP 引擎性能对比(示意)                      │
├──────────────────┬─────────────┬──────────────┬─────────────────┤
│      引擎         │   计算模型   │   延迟        │   优势场景       │
├──────────────────┼─────────────┼──────────────┼─────────────────┤
│    Hive          │  MapReduce  │  分钟~小时    │ 超大规模ETL      │
│    Spark SQL     │  内存计算    │  秒~分钟      │ 数据处理pipeline │
│    Impala         │  本地执行    │  秒           │ 交互式BI         │
│    Presto         │  分布式查询  │  秒           │ 跨数据源联邦查询  │
│    Kylin          │  MOLAP      │  毫秒~秒      │ 固定报表加速      │
└──────────────────┴─────────────┴──────────────┴─────────────────┘

然而,无论是 Hive、Spark 还是 Kylin,都未能完全解决"ROLAP 性能不足"或"MOLAP 灵活性受限"的问题。业界一直在追问:

是否存在一种技术,能够既保持 ROLAP 的灵活查询能力(支持任意维度组合、支持明细数据查询),又拥有 MOLAP 的极致性能(毫秒级响应)?

5.3 列式存储:性能革命的基石

在回答这个问题之前,我们需要了解一项关键技术——列式存储(Column-Oriented Storage)

在传统的行式存储中,数据在磁盘上是这样存放的:

Row 1: [id=1001, name=张三, amount=500, date=2024-01-01]
Row 2: [id=1002, name=李四, amount=300, date=2024-01-02]
Row 3: [id=1003, name=王五, amount=800, date=2024-01-03]

如果要执行 SUM(amount),需要读取每一行的完整数据,包括那些并不需要的 namedate 字段。

而在列式存储中,同一列的数据被连续存放:

Column id:    [1001, 1002, 1003, ...]
Column name:  [张三, 李四, 王五, ...]
Column amount:[500, 300, 800, ...]
Column date:  [2024-01-01, 2024-01-02, 2024-01-03, ...]

执行 SUM(amount) 时,只需要读取 amount 列的数据,其他列完全不需要读取——这在分析场景下带来了巨大的 I/O 节省。

列式存储的另一个优势是向量化执行(Vectorized Execution)。现代 CPU 的 SIMD(Single Instruction Multiple Data)指令集可以在单条指令中处理多个数据值。列式存储的数据在内存中连续排列,非常适合 CPU 缓存预取和向量化计算:

-- 向量化执行示意:一次处理一批数据而非逐行处理
-- 传统行执行:for each row → compute
-- 向量化执行:for batch of 1024 rows → SIMD compute

列式存储 + 向量化执行 + 高效压缩算法,构成了现代 OLAP 引擎的性能三角。接下来,让我们看看第一款将这套组合拳发挥到极致的开源数据库——ClickHouse。


6. 总结与展望

本文从 BI 系统的发展演变出发,系统梳理了从传统 BI 到现代 OLAP 的技术演进路径:

  1. 传统 BI 系统受困于"门槛高、受众窄、周期长"三大困境,传统关系型数据库的行式存储架构也无法满足大数据场景下的分析性能需求。

  2. 现代 BI 系统在云计算、SaaS 和开源运动的推动下,呈现出全民化、轻量化、实时化的新特征,OLAP 成为核心技术引擎。

  3. OLAP 架构三分天下:ROLAP 灵活但性能受限,MOLAP 快速但不够灵活,HOLAP 折中但增加了系统复杂度。

  4. 大数据技术的演进虽然降低了分析成本、提升了查询性能,但在"ROLAP 的灵活性 + MOLAP 的高性能"这一核心诉求面前,仍未给出完美答案。

正是这一技术空白,催生了 ClickHouse 的诞生。在下一篇文章中,我们将深入剖析 ClickHouse 的核心特性——它是如何通过列式存储、向量化执行、分布式架构等技术创新,实现了"唯快不破"的性能突破,成为 OLAP 领域的全新标杆。


下一篇【第02篇】ClickHouse横空出世——天下武功唯快不破

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐