关系型和非关系型数据库到底是什么意思呢,关系型和非关系型怎么理解,知道MySQL是关系型,HBASE是非关系型
理解了"关系"这两个字,你就真正懂了数据库设计的核心思想。
一、"关系"到底是什么意思?
1.1 一句话理解
关系 = 表与表之间的连接线(外键关联)
sql
sql
-- 用户表
CREATE TABLE user (
user_id INT PRIMARY KEY,
name VARCHAR(50)
);
-- 订单表(通过user_id关联用户)
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT, -- 外键,指向user表
amount DECIMAL(10,2),
FOREIGN KEY (user_id) REFERENCES user(user_id)
);
这就是"关系" :订单表的 user_id 关联到用户表的 user_id。
二、用你的课堂笔记理解(关键!)
你之前的HBase笔记里有个图:
text
rowkey info address
1001 {name:zhangsan, age:14} {province:guangdong, city:guangzhou}
1002 {name:lisi, sex:male} {area:binjiang, street:juyelu}
这个图完美解释了区别:
| 维度 | 关系型(MySQL) | 非关系型(HBase) |
|---|---|---|
| 数据组织 | 拆成多个表,用ID关联 | 全部塞进一行,不关联 |
| 用户和地址 | 分两张表,用user_id关联 | 写在同一行,直接嵌套 |
| 查询方式 | JOIN两张表 | 一次GET就拿到所有 |
三、具体例子对比
场景:存储用户和订单
关系型(MySQL)做法:
sql
sql
-- 用户表
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(50)
);
-- 订单表(关联用户)
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT, -- 外键,建立关系
price DECIMAL(10,2)
);
-- 查询:需要两张表关联
SELECT user.name, orders.price
FROM user
JOIN orders ON user.id = orders.user_id;
非关系型(HBase)做法:
bash
bash
# 一行存完,不用关联
rowkey = 用户ID
列簇 = info:
- name: 张三
列簇 = orders:
- 20250529_001: 99.00
- 20250529_002: 128.00
- 20250530_003: 59.00
# 查询:一次GET全拿到
get 'user_orders', '用户ID'
四、为什么叫"关系"型?
4.1 历史来源
1970年,IBM研究员埃德加·科德 发表论文《大型共享数据库的关系模型》,提出用**数学中的"关系"(Relation)**来组织数据。
数学中的关系 :就是表格
bash
关系 = 一张二维表
例如:
用户关系(表):
┌─────┬──────┐
│ id │ name │
├─────┼──────┤
│ 1 │ 张三 │
│ 2 │ 李四 │
└─────┴──────┘
订单关系(表):
┌─────┬─────────┬────────┐
│ id │ user_id │ amount │
├─────┼─────────┼────────┤
│ 101 │ 1 │ 99.00 │
│ 102 │ 1 │ 128.00 │
└─────┴─────────┴────────┘
这两个"关系"通过 user_id 建立"联系" → 关系型数据库
4.2 通俗理解
| 说法 | 解释 |
|---|---|
| 学术说法 | 基于关系模型的数据库 |
| 通俗说法 | 表之间可以用外键"牵线搭桥"的数据库 |
| 你的理解 | 数据可以拆开存,需要用的时候再拼起来 |
五、关系型 vs 非关系型 核心区别
| 维度 | 关系型(MySQL) | 非关系型(HBase/Redis/MongoDB) |
|---|---|---|
| 数据组织 | 多个表,用外键关联 | 单张表,或者用嵌套/聚合 |
| 表结构 | 列固定,改结构麻烦 | 列动态,随时可加 |
| 查询方式 | SQL,支持JOIN | API,主要按Key查 |
| 事务支持 | 支持ACID事务 | 有限支持(HBase只有行级) |
| 扩展方式 | 垂直扩展(加硬件) | 水平扩展(加机器) |
| 数据量 | GB~TB级别 | TB~PB级别 |
| 典型代表 | MySQL、Oracle、PostgreSQL | HBase、Redis、MongoDB |
六、什么场景用哪种?(判断标准)
用关系型(MySQL)的场景 ✅
# 1. 数据之间有复杂关系
例如:学生-课程-成绩-老师,需要多表关联查询
# 2. 需要事务保证
例如:银行转账(A扣钱,B加钱,必须一起成功)
# 3. 数据结构稳定
例如:用户表,字段基本不变
# 4. 数据量中等
例如:公司ERP系统,百万级数据
用非关系型(HBase)的场景 ✅
# 1. 数据量巨大
例如:用户行为日志,每天几十亿条
# 2. 查询简单(主要按主键)
例如:查某个用户的近期行为
# 3. 列经常变化
例如:用户画像标签,今天加一个"喜欢运动",明天加一个"高消费"
# 4. 不需要复杂JOIN
例如:物联网设备数据、日志存储
七、一句话总结
关系型 = 数据拆开存,用ID牵线(省空间,但查询麻烦)
非关系型 = 数据堆一起存,按Key查(占空间,但查询快)
类比搬家:
关系型 = 打包拆开(床板、螺丝分开装,省地方但组装费劲)
非关系型 = 整体搬(直接抬走,费地方但省事)
没有谁更好,看你要"省空间"还是"省时间"
八、常见混淆点澄清
| 错误认知 | 正确理解 |
|---|---|
| "关系型就是有SQL" | 对,但不是本质 |
| "非关系型就是没SQL" | HBase确实没SQL,但有类似工具(Phoenix) |
| "关系型不能存大数据" | MySQL也能存亿级,但HBase更适合百亿级 |
| "非关系型不需要设计" | 恰恰相反,HBase的rowkey设计是关键 |
HBase确实没SQL是什么意思
这句话需要澄清一下,因为容易产生误解。
一、"HBase确实没SQL" 是什么意思?
准确理解:
-
HBase 本身不支持 SQL 语法
-
你不能像 MySQL 那样写
SELECT * FROM user WHERE age > 18 -
HBase 有自己的 API 和 Shell 命令
二、具体对比
MySQL 有SQL(你熟悉的写法)
sql
-- 这些都是SQL
SELECT * FROM user;
SELECT * FROM user WHERE age > 18;
INSERT INTO user VALUES (1, '张三', 28);
UPDATE user SET age = 29 WHERE id = 1;
DELETE FROM user WHERE id = 1;
HBase 没SQL(实际写法)
bash
# 这不是SQL,是HBase Shell命令
scan 'user'
scan 'user', {FILTER => "ValueFilter(=,'binary:18')"} # 没有简单的 WHERE
put 'user', '1', 'info:name', '张三'
put 'user', '1', 'info:age', '28'
delete 'user', '1', 'info:age'
三、但是!HBase 可以有 SQL(通过中间层)
这就是容易混淆的地方:
方式1:Apache Phoenix(最常用)
sql
-- 用Phoenix,可以在HBase上写SQL
CREATE TABLE user (
id INTEGER PRIMARY KEY,
name VARCHAR,
age INTEGER
);
SELECT * FROM user WHERE age > 18; -- 这就是SQL!
INSERT INTO user VALUES (1, '张三', 28);
Phoenix 怎么做到的?
-
把 SQL 翻译成 HBase 的 API 调用
-
你的 SQL 变成底层的
get、scan、put
方式2:Hive 映射
sql
-- 在Hive中创建映射表,用Hive SQL查HBase
CREATE EXTERNAL TABLE user_hbase (
id STRING,
name STRING,
age STRING
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler';
SELECT * FROM user_hbase WHERE age > 18; -- Hive SQL
四、所以正确的理解是
| 说法 | 是否正确 | 说明 |
|---|---|---|
| "HBase 原生不支持 SQL" | ✅ 正确 | 原生 Shell 和 API 都没有 SQL |
| "HBase 不能用 SQL" | ❌ 错误 | 可以通过 Phoenix 等工具用 SQL |
| "HBase 没 SQL" | 🟡 容易误解 | 应该说 "原生不支持 SQL" |
五、为什么 HBase 原生不提供 SQL?
| 原因 | 说明 |
|---|---|
| 设计哲学不同 | HBase 追求简单、高效的单行操作 |
| SQL 开销大 | 解析 SQL、优化查询计划、执行引擎都需要资源 |
| 适用场景不同 | HBase 主要做 KV 查询,不需要复杂 SQL |
| 保持轻量 | 去掉 SQL 层,让 HBase 更专注存储 |
六、面试怎么回答?
面试官:HBase 支持 SQL 吗?
HBase 原生不支持 SQL,它有自己的一套 Shell 命令和 Java API。
但是,如果想用 SQL 查 HBase,可以搭配 Apache Phoenix 使用,Phoenix 会把 SQL 翻译成 HBase 的底层操作。
不过生产环境中,如果业务需要复杂 SQL 查询,通常会选择用 Hive 或者 Spark SQL 来查 HBase。
七、一句话总结
text
HBase 原生没SQL,但可以"穿上外衣"支持SQL(Phoenix/Hive)
就像:
- 中国人不会说英语(HBase没SQL)
- 但可以配个翻译(Phoenix)跟老外交流(用SQL查HBase)