这个是数据库选型的核心。为了清晰理解,我们分两层拆解:第一层是数据模型(关系型 vs 非关系型) ,第二层是存储引擎(行存储 vs 列存储)。这两层是正交的,可以交叉组合。
第一层:数据模型(关系型 vs 非关系型)
这决定的是数据如何组织 和用什么语言操作。
-
关系型数据库(SQL)
-
核心 :数据存成二维表格 ,表与表之间通过外键 关联。必须有固定的Schema(表结构),像Excel模板,每行每列固定。
-
操作语言 :SQL(结构化查询语言),支持复杂的多表联合查询(JOIN)和事务(ACID)。
-
典型产品:MySQL、PostgreSQL、Oracle。
-
适用场景 :强一致性要求的场景,如银行转账、订单系统、ERP(企业资源计划系统)。数据完整性比性能更重要。
-
-
非关系型数据库(NoSQL)
-
核心 :Schema-less(无固定模式),存储结构灵活。细分为四大家族:
-
键值型(Redis):像超大字典,通过Key找Value,极快。
-
文档型(MongoDB):存JSON文档,嵌套结构,适合灵活迭代的业务。
-
列族型(HBase/Cassandra):注意!这里的"列族"是数据模型,不是底层的列存储,后面会区分。
-
图型(Neo4j):存节点和关系,专攻社交网络、知识图谱。
-
-
操作语言:各家用各自的API或类SQL语法,通常不支持多表JOIN。
-
适用场景 :高并发、海量数据、快速迭代,如缓存、日志、物联网实时数据。
-
第二层:存储格式(行存储 vs 列存储)
这决定的是数据在磁盘上如何物理排列 。这是数据库性能差异的关键,尤其影响查询速度。
用一个例子对比,假设有张用户表:
| ID(主键) | 姓名 | 年龄 | 城市 |
|---|---|---|---|
| 1 | 张三 | 28 | 北京 |
| 2 | 李四 | 32 | 上海 |
| 3 | 王五 | 24 | 深圳 |
-
行存储(Row-Oriented)
-
物理排列 :磁盘上按行 连续存放。像这样:
1,张三,28,北京 | 2,李四,32,上海 | 3,王五,24,深圳。 -
特点 :写操作极快 (一次IO写一整行),查询整行极快 (
SELECT *)。 -
痛点 :如果只查年龄总和 (
SELECT SUM(年龄)),数据库仍需把整行数据(含姓名、城市)全部读入内存,再过滤出年龄,IO浪费严重。 -
典型产品:MySQL InnoDB、PostgreSQL。
-
-
列存储(Column-Oriented)
-
物理排列 :磁盘上按列 连续存放。像这样:
1,2,3 | 张三,李四,王五 | 28,32,24 | 北京,上海,深圳(每列单独存储)。 -
特点 :查询特定列极快 (只读取需要的列数据块),压缩率极高(同一列数据类型相同,比如年龄列全是数字,压缩比可达10:1)。
-
痛点 :写入慢 (插入一行要分散写入多个列文件),查整行慢(需要从多个列文件拼凑数据)。
-
典型产品:ClickHouse、Apache Parquet(大数据文件格式)、HBase底层(LSM树,但这里先不展开)。
-
第三层:实战组合(打破认知)
很多人误以为"关系型=行存,非关系型=列存",这是错误 的。真实世界是混合体:
| 组合方式 | 典型产品 | 适用场景 |
|---|---|---|
| 关系型 + 行存 | MySQL、PostgreSQL | OLTP(在线交易) 。银行扣款、下单支付。需要频繁增删改,且每次查一行或少量行。 |
| 关系型 + 列存 | Greenplum、ClickHouse(兼容SQL) | OLAP(在线分析) 。BI报表、销售大盘。数据只追加不修改,海量数据按年汇总,只查几列。 |
| 非关系型 + 行存 | MongoDB、Redis | 业务缓存 、文档存储。通常按ID取整个JSON对象,极少做全表统计。 |
| 非关系型 + 列存 | HBase、Cassandra(宽表) | 海量Key-Value查询。比如查某个用户的手机号、地址,按主键取回整行数据的所有列,但底层按列族存储以节省空间。 |
终极选择指南(决策树)
当你做技术选型时,可以按这个逻辑问自己:
-
数据需要强一致性和多表关联吗?
-
是 → 选关系型(MySQL/PostgreSQL)。
-
否 → 选非关系型(MongoDB/Redis)。
-
-
(在关系型内部)你的查询主要是单条点查,还是全表聚合?
-
点查/频繁更新 (如订单ID查详情)→ 行存储(MySQL)。
-
海量数据统计 (如计算过去10年总销售额)→ 列存储(ClickHouse)。
-
-
(在非关系型内部)你的数据是复杂对象,还是单纯的大Key?
-
复杂嵌套 (如商品评论、用户画像)→ 文档型(MongoDB),默认行存。
-
单纯的海量KV (如用户状态)→ 列族型(HBase),底层优化列存。
-
最后,一个极简口诀 :
行存管交易(OLTP),列存做分析(OLAP);关系型管关联,非关系型管海量。