事务场景选关系型行式存储,分析场景选列式存储,混合负载要么走HTAP,要么用ETL把两条链路分开。
关系型数据库和列式数据库的区别:底层存储模型决定上层场景
关系型数据库默认走行式存储,一条记录的所有字段挨着存放在同一个数据块里,列式存储反过来,把同一列的数值连续存放在一起,这个存放顺序的差异,决定了它们面对事务和分析时表现完全不同。
拿一张订单表举例,字段有订单号、用户ID、金额、创建时间,行式存储读一行时,四个字段一次取出,点查和更新很顺手,列式存储读金额列时,只遍历金额这一列的所有值,扫描和聚合特别快。
| 对比维度 | 关系型行式存储 | 列式存储 |
|---|---|---|
| 存储单元 | 按行连续存放 | 按列连续存放 |
| 写入方式 | 单行插入、更新快 | 批量写入快,单行更新慢 |
| 读取特点 | 点查、小范围扫描 | 大范围列扫描、聚合 |
| 压缩率 | 一般 | 同列数据类型一致,压缩率高 |
| 索引结构 | B+树、哈希索引 | 排序键、稀疏索引、分区裁剪 |
| 典型产品 | MySQL、PostgreSQL、Oracle | ClickHouse、Doris、Parquet、ORC |
| 适用场景 | 事务处理OLTP | 分析处理OLAP |
这个区别不是人为划分的,事务系统要频繁小块读写,分析系统要顺序大块读,存储引擎的性格从底层就分开了。
事务型数据库选型:行式存储凭什么成为默认答案
行式存储的点查与更新优势
事务系统的核心操作很固定:根据主键查单行、更新某几个字段、插入新记录,行式存储把一行数据放在同一个数据页,一次磁盘I/O就能拿到整行记录,B+树索引定位到主键后直接访问数据页,不需要跨多个列文件拼装。
列式存储更新一行时,要把一行拆成多个列值分别写入不同列段,还要维护各个列段之间的一致性,单行更新代价高,高频小更新会把列式引擎拖得很慢。

拿银行转账举例,执行下面这条SQL时:
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1001;
行式数据库只锁一行,写一个数据页,列式引擎可能涉及多个独立列段的合并写入,不适合这种高频点更新,想知道MySQL点查是否走对索引,用执行计划看一下:
EXPLAIN SELECT FROM orders WHERE order_id = 1001;
看输出里的type是const或eq_ref,key是PRIMARY,就说明走的是主键索引,点查路径最短。
事务的ACID靠什么保证
关系型数据库的行式引擎有成熟事务机制,这是它被信任的核心原因。
- 预写日志:先写redo log,再刷数据页,即使宕机,也能从日志恢复已提交事务。
- 回滚日志:undo log支持回滚和MVCC多版本并发控制,读写不互相阻塞。
- 行级锁与间隙锁:控制并发更新,防止脏写和幻读。
查看MySQL事务隔离级别,执行:
SELECT @@transaction_isolation;
MySQL InnoDB默认是REPEATABLE READ,PostgreSQL默认是READ COMMITTED,业内专家指出,事务负载的性能瓶颈多数落在行级锁竞争和日志刷盘上,而不是单纯的计算吞吐。
OLAP分析场景用什么存储?列式引擎的用武之地
列式存储适合什么场景:从扫描到聚合的天然优势
分析查询通常只涉及少数几列,但要扫描大量行,比如统计一个月销售总额:
SELECT SUM(amount) FROM orders WHERE create_time >= '2026-01-01' AND create_time < '2026-02-01';
行式存储要读取整行所有字段,哪怕只用金额和创建时间两列,列式存储只读amount和create_time两列,无关列直接跳过,加上同列数据类型一致,压缩率明显更高,磁盘I/O进一步下降。
列式引擎常用技术:
- 压缩编码:RLE、字典编码、Delta编码,同类型数据压缩效果好。
-

向量化执行
:SIMD批量处理列数据,一次计算多行。 - 延迟物化:先过滤出符合条件行号,再读取其他列,减少不必要数据物化。
- 分区裁剪与排序键:按时间分区,按用户ID排序,跳过无关数据块。
ClickHouse建表示例:
CREATE TABLE orders ( order_id UInt64, user_id UInt64, amount Decimal(10,2), create_time DateTime ) ENGINE = MergeTree PARTITION BY toYYYYMM(create_time) ORDER BY (user_id, create_time);
这个建表语句指定了分区键和排序键,查询时能快速跳过不相关分区,这就是列式引擎做OLAP查询快的直接原因。
列式数据库价格对比:开源、托管与数据湖怎么算账
选型时成本结构差别很大,不能只看软件授权费。
| 方案 | 软件费用 | 运维成本 | 查询延迟 | 适合规模 |
|---|---|---|---|---|
| 开源ClickHouse自建 | 免费 | 高 | 低 | 中大型团队,有DBA |
| 云托管ClickHouse | 按量或包月 | 低 | 低 | 中小团队快速上线 |
| 数据湖Parquet+Trino | 存储费低 | 中 | 中高 | 海量离线数据 |
| 行式数据库强扛分析 | 已有 | 低 | 高,容易拖垮事务 | 不建议 |
国内云厂商的列式存储服务,比如简米云ClickHouse、酷番云TCHouse,都是按计算节点和存储空间计费,北京、上海等一线地域的云资源价格略高,但网络延迟低,靠近业务系统,如果数据量中等且查询延迟要求高,开源ClickHouse自建或云托管是主流选择,行业共识认为,列式存储在压缩率上通常能达到行式的数倍,这种特性直接降低了分析场景的存储成本。
两类场景混合怎么办:事务与分析同库同存的折中方案
实际企业经常既要事务又要报表,三种路线的代价完全不同。
- 强行走单库:MySQL跑复杂分析,慢查询会占满连接,拖垮线上事务,不推荐。
- ETL分流:MySQL存事务,Binlog或CDC同步到ClickHouse/Doris,分析走列式,这是多数公司落地方式。
- HTAP数据库:TiDB等一体引擎,行存处理TP,列存处理AP,适合不想维护两条链路的团队。

用Flink CDC从MySQL同步到Doris的操作路径:
- 开启MySQL Binlog,格式设为ROW。
- Flink CDC连接器读取Binlog。
- 写入Doris表,Doris自动承接分析查询。
Flink SQL连接MySQL CDC的示例:
CREATE TABLE mysql_orders ( order_id BIGINT, user_id BIGINT, amount DECIMAL(10,2), PRIMARY KEY (order_id) NOT ENFORCED ) WITH ( 'connector' = 'mysql-cdc', 'hostname' = 'localhost', 'port' = '3306', 'username' = 'user', 'password' = 'password', 'database-name' = 'shop', 'table-name' = 'orders' );
事务走MySQL,分析走Doris,两边互不干扰,这套链路在中小型电商和SaaS系统里非常普遍。
事务选行式,分析选列式,这条分界不是人为划分,是磁盘I/O和数据结构决定的,混合负载要么拆链路,要么上HTAP,别用错引擎硬扛。
关系型存储与列式存储常见问题
问:关系型数据库和列式数据库的区别到底有多大?
答:本质区别在数据存放顺序,行式按记录连续放,点查和更新快;列式按字段连续放,扫描和聚合快,两者不是互相替代,是互补关系。
问:OLAP分析场景用什么存储成本最低?
答:如果数据量中等且查询延迟要求高,开源ClickHouse自建或云托管是主流,如果数据海量且可接受分钟级延迟,数据湖Parquet+Trino存储成本更低,成本高低还看团队运维能力和地域带宽费用。
问:事务型数据库选型要不要考虑列式引擎?
答:纯事务负载不建议用列式引擎,单行更新代价高,锁粒度粗,事务机制不成熟,混合负载可考虑HTAP或CDC分流,不要把高频小事务直接压给列式数据库。