列存储将同一列数据连续存放,提升分析查询效率与压缩比,但写入性能较差;行存则整行存储,适合事务处理。

SQL数据库里的列存储,核心是把同一列的所有值连续存放在磁盘或内存中,而不是像行存那样把整条记录(比如用户ID、姓名、年龄)捆在一起存。这种“按列组织数据”的方式,直接决定了它在分析类查询中效率高、压缩比大,但在事务写入时更吃力。
列存储是怎么组织数据的
假设一张表有三列:user_id(整型)、action(字符串)、ts(时间戳),共100万行数据:
- 行存会把每行拼成一个单元,比如[1, "click", "2025-01-01"] → [2, "view", "2025-01-01"] → …,顺序写入磁盘块;
- 列存则拆开存放:user_id列单独存为一串整数[1, 2, 3, ..., 1000000],action列存为字符串数组["click", "view", "buy", ...],ts列存为统一格式的时间序列——各列物理上完全分离。
这样做的直接好处是:查“所有action类型分布”,只需读action列那一段;做SUM、AVG、GROUP BY,引擎能顺序扫描同质数据,CPU缓存友好,还能用RLE、字典编码等算法高效压缩。
行存和列存的关键差异在哪
差异不在“好不好”,而在“适合什么场景”:
WOC是基于zend framework1.6框架所开发的一款开源简易网站运营管理系统。它允许进行网站管理、主机管理、域名管理、数据库管理、邮箱管理以及用户管理、角色管理、权限管理等一系列功能,适合中小企业进行网站运营管理。目前版本为V1.2,新版本正在开发中,同时欢迎大家参与到开发中来! WOC升级说明: 1.1在1.0的基础上进行了代码规范并增加了配置数据缓存,以提高访问速度 注意:升级时要重
-
读取逻辑不同:行存一次加载整行,适合点查(如
SELECT * FROM users WHERE id = 123);列存只加载涉及的列,适合宽表扫描(如SELECT COUNT(*), AVG(age) FROM logs WHERE dt = '2026-01-04'); - 写入机制不同:行存插入一行=一次定位+一次写入;列存需分别写入N个列块,磁头寻道/页分裂开销更大,尤其单行更新代价高;
- 压缩能力不同:列内数据类型一致、重复模式多(比如status列大量是"success"),压缩率常达5–10倍;行存混杂不同类型字段,压缩收益有限;
- 索引与优化倾向不同:列存天然具备“每列即索引”的特性(比如对某列建位图索引非常轻量),优化器更倾向向量化执行、谓词下推;行存依赖B+树等传统索引结构,优化重心在连接、事务一致性。
哪些SQL数据库支持列存
不是所有SQL数据库都原生支持列存,但主流系统已有明确分工或混合能力:
- 纯列存SQL引擎:ClickHouse、Apache Doris、StarRocks、Vertica——默认按列组织,专为OLAP设计;
- 支持列存扩展的通用数据库:PostgreSQL(通过citus或columnar插件)、SQL Server(支持聚集列存储索引)、Oracle(In-Memory Column Store选项)、PolarDB(MySQL版提供行列混合模式);
- 典型行存为主,不默认列存:MySQL(InnoDB引擎)、PostgreSQL(默认堆表)、SQLite——它们的底层存储面向事务,列存需额外组件或升级版本实现。
选型时不用纠结“哪个更好”,而要看你主要跑的是UPDATE user SET balance = balance - 100 WHERE id = 888,还是SELECT region, SUM(sales) FROM fact_sales GROUP BY region——前者行存稳,后者列存快。









