文章封面图: OLAP 数据库:是什么、真实用例和主要厂商

OLAP 数据库:是什么、真实用例和主要厂商

发布于:

阅读时间: 6 min

主题: 技术

作者: Leandro Valencia

#OLAP#OLTP#数据仓库#数据分析#ClickHouse#BigQuery#Snowflake#DuckDB

OLAP 数据库是什么、与 OLTP 有何不同、带真实 SQL 的实用案例,以及 2026 年的主要厂商。

目录

OLAP 是什么(以及不是什么)

OLAPOnline Analytical Processing(联机分析处理)的缩写。它是一种工作负载类别,而不是某个具体产品。

这个区分比看起来更重要。当有人说"我们需要一个 OLAP"时,他描述的其实是一种模式:扫描并聚合数百万到数十亿行数据,以回答业务问题的查询。"过去三年按产品和地区看月收入"是一个 OLAP 查询,无论你是在 Excel 里对着 1998 年的立方体跑,还是今天对着一张十亿行的表跑。

这个词是 E. F. Codd——关系模型的同一位 Codd——在 1993 年一篇题为 Providing OLAP to User-Analysts: An IT Mandate 的论文中提出的,他在文中定义了分析系统的十二条规则。

一个几乎没人提到的诚实注脚:那篇论文是由 Arbor Software 赞助的,这家公司做的是 Essbase,最早的 OLAP 产品之一。那十二条规则出奇地贴切地描述了 Essbase 已经在做的事。这是一次披着学术论文外衣的精彩营销操作;然而它提出的核心观点——分析型负载需要和事务型不同的设计——却完全正确,并在三十年后仍在定义这个领域。

"Online"这个词也容易误导人。它跟互联网毫无关系:在 1993 年它指的是交互式,与夜间生成的批处理报表相对。

OLAP 不是什么

它和数据仓库不是一回事。 OLAP 是一种处理类别;数据仓库是一种基础设施模式。数据仓库是为承载 OLAP 负载而构建的,但 OLAP 也可以跑在实时数据库、嵌入式引擎和语义层上。

它们不是"宽列"数据库。 因为名字的关系,这是一个经典又情有可原的误解。Cassandra、HBase 和 Bigtable 被描述成"列式",但内部其实是行存储:它们按分区键把行分组,把列作为键值对存在每一行内部。它们服务于灵活 schema 的 OLTP 负载,而不是分析聚合。如果有人给你的 dashboard 提议用 Cassandra,这里存在一个误解。

它不是"大数据"的同义词。 5 GB 数据完全可以构成一个完全合法的 OLAP 负载。定义这种模式的是查询的形状,而不是数据量。

OLAP vs OLTP:解释一切的区别

OLTP(Online Transaction Processing,联机事务处理)是 PostgreSQL、MySQL 或 Oracle 在做的事:以事务和强一致性,非常快地读写少量行。"给我看一下订单 8821。""库存减一个。"

OLAP 在几乎所有维度上都相反:

OLTP OLAP
存储 按行 按列
读模式 少列,少行 多行,少列
写模式 单行变更,高频率 批量插入,几乎只追加
目标延迟 毫秒级 亚秒到秒级
并发 数千用户,简单查询 几十或几百,复杂查询
Schema 规范化(3NF) 星型或宽表反规范化
典型问题 "订单 X 的状态是什么?" "订单按地区如何演变?"
例子 PostgreSQL、MySQL、Oracle ClickHouse、Snowflake、BigQuery、DuckDB

两种设计天然不兼容,而这正是两者都存在的原因。一个为以事务完整性写一行而优化的引擎,不可能同时也为扫描四亿行并把它们压成一个数而优化。

为什么列式存储改变了一切

物理上的差别很容易看清。一个按行存储的数据库在磁盘上是这样的:

[id:1|país:ES|ingresos:42|fecha:...] [id:2|país:MX|ingresos:17|fecha:...]

要累加 ingresos,你必须连 paísfecha 和其他你并不关心的三十列一起读出来。列式数据库则把每一列分开存:

ingresos: [42, 17, 88, 12, ...]
país:     [ES, MX, ES, AR, ...]

如果你的表有 40 列,而你的查询只用 2 列,你就只读 5% 的数据。而且相邻值类型相同、又常常重复,压缩效果好得多:磁盘上字节数更少,I/O 更少,查询更快。

在此之上,现代引擎还加入了向量化执行(用 SIMD 指令批量处理列,而不是逐行)、数据跳过(稀疏索引和 min/max 统计,跳过整个数据块不读)、以及计算与存储分离

历史:从立方体到列式(以及为什么和你有关)

这部分看起来像博物馆冷知识,但它解释了为什么你在网上找到的文档里到处都是已经没人用的概念。

MOLAP、ROLAP、HOLAP

在数十年里,标准的 OLAP 分类是这一套:

模型 存储 查询路径 优势 问题
MOLAP 预聚合立方体(Essbase、Analysis Services) MDX → 查立方体 在预定义维度上亚秒级响应 构建要几小时;加维度存储就爆炸;schema 死板
ROLAP 关系表(Snowflake、BigQuery、ClickHouse) SQL → 按需聚合 即席查询、任意维度、灵活 schema 单次查询延迟更高(除非引擎非常快)
HOLAP 两者混合 汇总走立方体,明细走 SQL 私有技术栈里的历史折中 运维两套系统的成本

MOLAP 是九十年代和两千年代的王者。OLAP 立方体的思路是预先把层级维度(时间、地区、商品)上所有可能的聚合都算好,这样查询就变成查找而不是计算。

它确实管用,但代价惨重。第一:构建要几小时,所以你的数据永远是昨天的。第二,更阴险:立方体只能回答在设计时被预想到的问题。如果分析师想交叉两个谁也没料到的维度,就得重新设计并重建立方体。回答一个新问题要几周。

立方体为什么会死

这个过渡是渐进的。Sybase IQ 在 1994 年推出了列式引擎。Vertica 由 C-Store 的作者构建,2007 年商业化。Google 在 2010 年发表了 Dremel 论文——BigQuery 的基础。ClickHouse 在 2016 年开源。

到 2010 年代后期,一件决定性的事情发生了:过去需要在立方体里预聚合才能达到的延迟,现在在原始数据上就能做到了。在那一刻,立方体层就不再是收益,而是纯粹的摩擦。所有成本(慢构建、僵化、又多一套要运维的系统)全都白付了。

立方体并没有完全消失:Essbase、Microsoft Analysis Services 和 Excel PowerPivot 里的 MDX 在大企业里还活着。但对任何新项目,答案都是列式引擎,而需要预聚合时,用增量计算、可像普通表一样查询的物质化视图来解决。

我对"为什么这事重要,即使你根本不会碰立方体"的看法:你去搜 OLAP 资料,会看到大量默认 MOLAP 范式的内容——谈 MDX、谈维度、谈构建——会引导你用 2003 年的心智模型去设计系统。这套分类主要活在教科书和认证考试里。把这些概念当历史读,而不是当指南。

活下来的词汇

虽然立方体死了,谈分析查询的语言却没变。翻译成现代 SQL:

Roll-up(聚合层级上卷):从日销售到月销售。

SELECT toStartOfMonth(fecha) AS mes, sum(importe) AS ingresos
FROM ventas GROUP BY mes ORDER BY mes;

Drill-down(下钻到明细):从月到当月的每一天。

SELECT fecha, sum(importe) AS ingresos
FROM ventas WHERE toStartOfMonth(fecha) = '2026-07-01'
GROUP BY fecha ORDER BY fecha;

Slice(按固定值切一个维度):只要西班牙。

SELECT fecha, sum(importe) FROM ventas WHERE pais = 'ES' GROUP BY fecha;

Dice(多过滤条件的子立方体):西班牙和墨西哥,具体某品类,一个季度。

SELECT pais, categoria, sum(importe)
FROM ventas
WHERE pais IN ('ES','MX') AND categoria = 'hardware'
  AND fecha BETWEEN '2026-04-01' AND '2026-06-30'
GROUP BY pais, categoria;

Pivot(行转列):在现代 OLAP 里就是条件函数。

SELECT
    toStartOfMonth(fecha)         AS mes,
    sumIf(importe, pais = 'ES')   AS espana,
    sumIf(importe, pais = 'MX')   AS mexico,
    sumIf(importe, pais = 'AR')   AS argentina
FROM ventas GROUP BY mes ORDER BY mes;

九十年代需要专用服务器和专用语言的五个概念,今天就是五条 SQL。

星型 schema:OLAP 数据如何建模

分析领域的主导逻辑模型是星型 schema:中央一张事实表,周围是维度表。

事实表存放可度量的事件,行多列少:一次销售、一次点击、一次传感器读数。维度表存放描述性上下文:这个客户是谁、这个商品属于什么品类、这家店在哪个地区。

-- 事实表:不停增长
CREATE TABLE hechos_ventas (
    fecha       Date,
    producto_id UInt32,
    cliente_id  UInt32,
    tienda_id   UInt16,
    unidades    UInt32,
    importe     Decimal(12, 2)
) ENGINE = MergeTree
ORDER BY (tienda_id, fecha, producto_id);

-- 维度:小而稳定
CREATE TABLE dim_producto (
    producto_id UInt32,
    nombre      String,
    categoria   LowCardinality(String),
    marca       LowCardinality(String)
) ENGINE = MergeTree ORDER BY producto_id;

这里有个把理论和实践区分开的细节。在经典数据仓库里,星型 schema 是教条。在现代列式 OLAP 引擎里,很多时候应该反规范化,把 categoriamarca 直接塞进事实表里。听起来像异端——你在重复数据——但因为这些列用 LowCardinality 压缩效果惊人,存储成本几乎为零,而每次查询都省下一个 JOIN。

我的规则:几乎从不变化的东西(商品品类、门店国家)一开始就反规范化;经常变化或体量大的东西保留为独立维度。

用真实 SQL 讲的实用案例

到了这里,OLAP 就不再是理论了。这些才是你真正会遇到的模式。

1. 产品分析:转化漏斗

产品里最常见的场景。你想知道有多少人从看页面走到注册,再走到购买,以及他们在哪里流失。

标准 SQL 里这是 CTE 和自连接的噩梦。在现代 OLAP 引擎里它是一个函数:

SELECT nivel, count() AS usuarios
FROM (
    SELECT
        usuario_id,
        windowFunnel(86400)(
            timestamp,
            evento = 'pageview',
            evento = 'signup',
            evento = 'purchase'
        ) AS nivel
    FROM eventos
    WHERE fecha >= today() - 30
    GROUP BY usuario_id
)
GROUP BY nivel
ORDER BY nivel;

windowFunnel(86400) 统计每个用户在 24 小时窗口里连续完成了多少步。结果直接给你漏斗的形状。

为什么这里需要 OLAP: 这条查询触及一个月内每个用户的每个事件。在数千万行的 Postgres 上,这是一次会压垮生产库的顺序扫描。

2. 可观测性:日志、指标、trace

日志是 OLAP 最典型的案例,但很多人看不出来,因为他们把它和 Elasticsearch 绑定。它是带时间戳的事件,写得多,按聚合读,几乎不更新。

SELECT
    toStartOfMinute(timestamp)                    AS minuto,
    servicio,
    count()                                       AS total,
    countIf(nivel = 'ERROR')                      AS errores,
    round(countIf(nivel = 'ERROR') / count(), 4)  AS tasa_error,
    quantile(0.95)(duracion_ms)                   AS p95,
    quantile(0.99)(duracion_ms)                   AS p99
FROM logs
WHERE timestamp >= now() - INTERVAL 3 HOUR
GROUP BY minuto, servicio
HAVING tasa_error > 0.01
ORDER BY minuto DESC;

一次遍历算出百分位、错误率、按分钟分组。加一个 TTL 让 90 天前的数据自动删除,你就有一套完整的可观测性平台。

一条改变了我的账的经济提示: 把日志从 SaaS 可观测性方案迁到自托管的 OLAP 数据库,是小项目能拿到的最大成本削减之一。日志平台的定价按摄入量计算,而日志量只会增长。

3. 电商和 BI dashboard

经典场景:按多个维度聚合的业务指标。

SELECT
    toStartOfWeek(fecha)                       AS semana,
    categoria,
    sum(importe)                               AS ingresos,
    count()                                    AS pedidos,
    uniq(cliente_id)                           AS clientes,
    round(sum(importe) / count(), 2)           AS ticket_medio,
    round(sum(importe) / uniq(cliente_id), 2)  AS ingreso_por_cliente
FROM hechos_ventas
WHERE fecha >= today() - 180
GROUP BY semana, categoria
ORDER BY semana DESC, ingresos DESC;

注意 uniq():它用 HyperLogLog 近似计数 distinct,典型误差低于 1%,内存占用比 uniqExact() 低得离谱。对业务 dashboard 来说,这种近似完全可以接受,而性能差距巨大。

4. 时序和 IoT

传感器、基础设施指标、市场价格。高频到达、以较低分辨率被查询的数据。

SELECT
    toStartOfFifteenMinutes(timestamp)  AS intervalo,
    sensor_id,
    round(avg(temperatura), 2)          AS media,
    min(temperatura)                    AS minima,
    max(temperatura)                    AS maxima,
    count()                             AS lecturas
FROM metricas_sensores
WHERE timestamp >= now() - INTERVAL 7 DAY
  AND sensor_id IN (101, 102, 103)
GROUP BY intervalo, sensor_id
ORDER BY intervalo;

让这件事可持续的模式是渐进式降采样:秒级读数存一周,小时级存一年,日级无限期保存。用聚合 TTL,这件事是自动的。

5. 面向用户的分析(嵌入式分析)

最苛刻的场景。这不是三个人看的内部 dashboard:这是你产品里的"统计"页,你所有客户同时查询。

SELECT
    toDate(timestamp)     AS dia,
    count()               AS visitas,
    uniq(visitante_id)    AS visitantes,
    countIf(rebote)       AS rebotes
FROM eventos_web
WHERE tenant_id = {tenant:UInt32}      -- 永远放在 ORDER BY 第一位!
  AND timestamp >= {desde:DateTime}
GROUP BY dia
ORDER BY dia;

这里设计的关键是 tenant_id 作为排序键的第一列。这样每个客户只扫描自己的数据,即使表里有所有客户合起来几十亿行,延迟也能保持在毫秒级。这是一个能扩展的功能和一个客户来了一百个就垮掉的功能之间的区别。

6. 留存和队列分析

某月注册的用户中,几个月后还有多少活跃。

SELECT
    cohorte,
    mes_relativo,
    uniq(usuario_id) AS usuarios
FROM (
    SELECT
        usuario_id,
        fecha,
        toStartOfMonth(min(fecha) OVER (PARTITION BY usuario_id)) AS cohorte,
        dateDiff('month', cohorte, toStartOfMonth(fecha))         AS mes_relativo
    FROM eventos
)
GROUP BY cohorte, mes_relativo
ORDER BY cohorte, mes_relativo;

小心 OVER 的位置:它必须紧贴 min(fecha),在 toStartOfMonth() 内部。如果你写 toStartOfMonth(min(fecha)) OVER (...),ClickHouse 会把 toStartOfMonth 当成窗口函数,然后报 Aggregate function with name 'toStartOfMonth' does not exist

这种查询——对整张表做窗口——正是会把事务数据库压垮、而列式库几秒就能解决的事。

2026 年的主要 OLAP 厂商

市场分成了五个相当清晰的类别。我按它们与真实项目的契合度排序,而不是按市场份额。

实时 OLAP 引擎(开源)

亚秒延迟、持续摄入、面向实时 dashboard 和嵌入式分析。

ClickHouse 是这个类别的标杆。列式、单二进制、Apache 2.0 协议、从笔记本扩展到数百节点。它是自托管的默认选择,也有自己的托管服务(ClickHouse Cloud)。要细节,我有 ClickHouse 完整指南

Apache Druid 多年在大规模实时时序分析上表现突出。对来自 Kafka 的摄入非常强,但运维成本高:六种进程外加 ZooKeeper。

Apache Pinot 出生于 LinkedIn,为数亿用户提供分析。它是为超高并发下的最低延迟最专门设计的,缺点同样是运维复杂。

StarRocksApache Doris 是近亲,列式 MPP,JOIN 优化器比 ClickHouse 更强。如果你的 schema 是规范化的数仓,是好选择。

托管云数据仓库

零运维、几乎无限扩展、按消费计费。

Snowflake 普及了计算与存储分离,主导企业市场。在数据治理和权限方面非常成熟。按 warehouse 计算时间收费。

Google BigQuery 是真正的 serverless:不管理集群,写 SQL 就行。主要按扫描数据量收费,这意味着写得烂的查询会很贵。

Amazon Redshift 是 AWS 生态的选项。更老、需要更多手动调优,但与 Amazon 其他服务原生集成。

Databricks SQLlakehouse 架构的参考,把数据工程、机器学习和分析统一在同一份存储上。当有非结构化数据和 AI 流水线时很强。

Azure Synapse 为已经生活在微软生态里的人补齐了三大云厂商的阵容。

我对这个类别的警告(在对比文章里重复过,这里也适用):按消费计费的模式,正好惩罚的是交互式分析的典型模式,也就是大量频繁的小查询。一个每 30 秒自动刷新的 dashboard 可能产生不成比例的账单。如果你预算紧张,变动的账单是业务风险,不只是技术风险。

嵌入式引擎

没有服务器,跑在你的进程里。

DuckDB 是分析版的 SQLite:pip install duckdb 你就拿到一个向量化列式引擎,方言兼容 PostgreSQL。它直接读 Parquet 和 CSV。对能装进一台机器的数据集,在简洁性上无敌。MotherDuck 是它的云层。

chDB 是嵌入 Python 的 ClickHouse 引擎,API 风格类似 pandas。

专用型

kdb+ 主导高频交易。在时序上极快,有自己的语言(q),价格也配得上它的利基。

QuestDB 是开源的、面向时序、带扩展 SQL。

TimescaleDB——这家公司在 2025 年改名为 TigerData,但开源扩展仍叫 TimescaleDB——把 PostgreSQL 变成时序数据库。如果你已经在用 Postgres,而且数据量中等,这是摩擦最小的迁移。

FireboltSingleStore 在高性能加云管理的利基市场竞争。

数据湖上的查询引擎

Trino(原 PrestoSQL)和 Apache Spark SQL 查询的是以开放格式(Apache IcebergDelta Lake 或 Parquet)存在对象存储上的数据。它们不是数据库:它们是把 SQL 放在你的文件之上的引擎。

这个类别正在模糊"数据湖"和"OLAP 数据库"的边界。很多列式引擎——ClickHouse 也是——已经能直接读 Iceberg 和 Parquet,这意味着你可以不摄入任何东西就查询你的湖。

以及更上层的

值得提一下,OLAP 是处理层,不是展示层。Tableau、Looker、Power BI、Metabase 和 Grafana 是 BI 工具,连接到 OLAP 数据库以在背后执行查询。数据库提供速度和结构;BI 提供界面。

怎么选:我用四个问题给出的标准

翻译成实操决策。

你的数据装得下一台机器(比如几百 GB 以内)? 从 DuckDB 起步。零运维、性能出色、SQL 熟。这是最被忽视、又最常正确的推荐。

你需要一个带持续写入和多个读者的共享服务吗? ClickHouse。这是当今性能与运维复杂度的最佳平衡点,并且跑在一台普通 VPS 上。

你已经在 PostgreSQL 里,数据量中等? TimescaleDB。你加的是一个扩展而不是一个新服务。无聊的选项往往是正确的。

你有团队、有预算、把零基础设施放在首位? Snowflake、BigQuery 或 Databricks。第一天就设好成本告警。

以及先于这一切的问题:你真的需要 OLAP 吗? 如果你最大的表有 200 万行,而你的查询在 Postgres 里 200 ms 就回来了,答案是不需要。加一套分析系统就是加一个要维护、备份、监控的服务。时机到了的信号很具体:某条对你产品至关重要的聚合超过 5 秒,而你已经尝试过加索引。

关于为什么这件事比看起来更重要的反思

很多年里,我都以为"OLAP"是企业黑话,是给在银行里摆弄立方体的人用的。这是开发者中相当普遍的偏见,而它让我付出了昂贵代价。

让我改变看法的,是意识到几乎每个数字产品都在产生事件数据,而几乎没人利用它们,因为默认基础设施——关系型数据库——让查询这些数据很痛苦。于是它们被扔掉,被存进一张没人敢碰的表,或者付钱给一个只给你本来能有东西的 10% 的分析 SaaS。

采用 OLAP 数据库并没有改变我能测量的东西,它改变了我提问的频率。一条查询要 40 秒时,一次会话我探索两个假设;要 300 毫秒时,我探索二十个。而正是这种频率差异,最终产出了你没在找的发现。

这才是支持 OLAP 的真正论点,它不会出现在任何 benchmark 里:不是查询更快了,而是你提了更多问题

结论

OLAP 既不是某项具体技术,也不是一时风尚:它就是为回答"关于大数据量的问题"而构建的系统类别,以不同名字存在了三十年。彻底改变的是实现:从夜里构建的僵硬立方体,到在原始数据上毫秒级聚合的列式引擎。

对今天的小项目而言,这种演进意味着一件非常具体的事:2005 年需要一个专门团队和一份六位数许可证的分析能力,今天能装进一个跑在每月 20 欧元 VPS 上的二进制里。

如果你想从理论走到能跑起来的东西,最短路径是:


常见问题

OLAP 是什么意思?

Online Analytical Processing(联机分析处理)。它指一类分析型工作负载——对数百万行做聚合和分组——以及为承载这些负载而构建的系统。这个词由 E. F. Codd 于 1993 年提出,"online"是交互式的意思,与互联网无关。

OLAP 和 OLTP 有什么区别?

OLTP 是面向行的,优化为以毫秒级延迟读写少量记录。OLAP 是面向列的,优化为扫描并聚合数百万行。两者设计相反,因此它们在同一架构里共存而不是互相替代。

PostgreSQL 是 OLAP 数据库吗?

不是。PostgreSQL 是 OLTP:它的行式存储和 B 树索引是为点查和小写入设计的。TimescaleDB、Citus 或 pg_duckdb 等扩展能加上有限的分析能力,但规模化时的标准模式是 Postgres 写、OLAP 数据库读,中间用 CDC 连接。

OLAP 立方体在 2026 年还有用吗?

只在遗留环境里。列式引擎靠按需计算聚合就能达到同等延迟,需要预聚合时,用的是增量物质化视图而不是立方体。

Cassandra 是 OLAP 数据库吗?

不是。Cassandra、HBase 和 Bigtable 是"宽列"存储,但存储层是面向行的。它们服务于灵活 schema 的 OLTP 负载,而不是分析聚合。

我能在小项目里用 OLAP 吗?

能,而且越来越容易。DuckDB 作为库跑在你的应用里,ClickHouse 作为单个二进制跑在 VPS 上。要起步已经不需要企业级基础设施。

OLAP 数据库要多少钱?

自托管的开源选项(ClickHouse、DuckDB、StarRocks)没有许可证成本,你付的是服务器和你的运维时间。托管服务按计算和存储收费,模型差异很大:BigQuery 主要按扫描数据量收费,Snowflake 按活跃计算时间收费。

相关文章

继续探索您可能感兴趣的相似内容

OLAP 数据库:是什么、真实用例和主要厂商