关系型数据库概述
SQL 是访问和处理关系数据库的计算机标准语言。无论使用什么编程语言(Java、Python、C++……)编写程序,只要涉及操作关系数据库,都必须通过 SQL 来完成。
对于从事编程或互联网行业的人来说,最具有中台能力的语言便是 SQL。自从 SQL 加入 TIOBE 编程语言排行榜以来,一直保持在 Top 10。
为什么 SQL 如此重要:
- SQL 语言无处不在:它对于不同职位的人都有价值。SQL 已不仅仅是技术人员需要掌握的技能,产品经理、运营人员同样需要掌握
- SQL 语言稳定:从诞生到现在,SQL 很少变化。这意味着一旦掌握,可以一劳永逸
- SQL 入门不难:基础语法简单直观,学习曲线平缓
NoSQL 的演变
NoSQL 的分类很多,包括键值型、文档型、搜索引擎、列式存储和图形数据库等。很多人鼓吹现代 Web 程序已经无需关系数据库,只需要使用 NoSQL 即可。但事实上 SQL 数据库从始至终从未被取代过。
NoSQL 的发展历程:
| 年代 | 含义 | 说明 |
|---|---|---|
| 1970 | NoSQL = We have no SQL | 早期没有 SQL |
| 1980 | NoSQL = Know SQL | 开始了解 SQL |
| 2000 | NoSQL = No SQL! | NoSQL 运动兴起 |
| 2005 | NoSQL = Not only SQL | 不仅仅是 SQL |
| 2013 | NoSQL = No, SQL! | SQL 依然重要 |
结论:SQL 数据库仍然承担各种应用程序的核心数据存储,而 NoSQL 数据库作为 SQL 数据库的补充。两者不再是二选一的问题,而是主从关系。无论是 Web 开发、游戏开发还是移动开发,掌握 SQL 是所有软件开发人员的必备技能。
数据模型
数据库按照数据结构来组织、存储和管理数据。数据库一共有三种模型:
层次模型
层次模型以"上下级"的层次关系来组织数据,数据结构看起来像一棵树。
学校
/ \
学院1 学院2
/ \ / \
专业1 专业2 专业3 专业4特点:
- 结构简单,易于理解
- 查询效率高(路径明确)
- 缺点:无法表示多对多关系,缺乏独立性
网状模型
网状模型把每个数据节点和其他很多节点连接起来,数据结构看起来像城市之间的路网。
A ---- B
/ \ /|\
C---D--E-F
\ / \|/
G ---- H特点:
- 可以表示复杂的多对多关系
- 存取效率较高
- 缺点:结构复杂,编程困难
关系模型
关系模型把数据看作一个二维表格,任何数据都可以通过行号+列号唯一确定,数据模型看起来就是一个 Excel 表。
特点:
- 理解和使用最简单
- 建立在严格的数学理论基础上
- 最终获得了绝对市场份额
为什么关系模型胜出:相比层次模型和网状模型,关系模型理解和使用起来最简单。虽然其数学理论(域、笛卡尔积、关系代数)较为复杂,但基于日常生活的理解却十分直观。
关系模型示例
以学校班级为例,一个班级的学生可以用一个表格存储:
学生表 students:
| ID | 姓名 | 班级ID | 性别 | 年龄 |
|---|---|---|---|---|
| 1 | 小明 | 201 | M | 9 |
| 2 | 小红 | 202 | F | 8 |
| 3 | 小军 | 202 | M | 8 |
| 4 | 小白 | 201 | F | 9 |
班级表 classes:
| ID | 名称 | 班主任 |
|---|---|---|
| 201 | 二年级一班 | 王老师 |
| 202 | 二年级二班 | 李老师 |
通过给定一个班级名称,可以查到一条班级记录,根据班级 ID,又可以查到多条学生记录。这样,二维表之间就通过 ID 映射建立了"一对多"关系。
数据类型
对于关系表,除了定义每一列的名称外,还需要定义每一列的数据类型。关系数据库支持的标准数据类型包括:
数值类型
| 名称 | 类型 | 说明 | 存储空间 |
|---|---|---|---|
| TINYINT | 小整型 | -128 到 127 | 1 字节 |
| SMALLINT | 短整型 | -32768 到 32767 | 2 字节 |
| INT | 整型 | 约 +/-21亿 | 4 字节 |
| BIGINT | 长整型 | 约 +/-922亿亿 | 8 字节 |
| REAL | 浮点型 | 约 +/-10^38 | 4 字节 |
| DOUBLE | 双精度浮点型 | 约 +/-10^308 | 8 字节 |
| DECIMAL(M,N) | 高精度小数 | 用户指定精度 | 可变 |
字符串类型
| 名称 | 类型 | 说明 |
|---|---|---|
| CHAR(N) | 定长字符串 | 总是存储 N 个字符,不足补空格 |
| VARCHAR(N) | 变长字符串 | 存储 0~N 个字符 |
| TEXT | 长文本 | 存储大段文本 |
| BLOB | 二进制大对象 | 存储二进制数据 |
时间日期类型
| 名称 | 类型 | 说明 | 示例 |
|---|---|---|---|
| DATE | 日期类型 | 存储日期 | 2024-06-22 |
| TIME | 时间类型 | 存储时间 | 12:20:59 |
| DATETIME | 日期时间 | 存储日期+时间 | 2024-06-22 12:20:59 |
| TIMESTAMP | 时间戳 | Unix 时间戳 | 自动更新 |
其他类型
| 名称 | 类型 | 说明 |
|---|---|---|
| BOOLEAN | 布尔类型 | 存储 TRUE 或 FALSE |
| JSON | JSON 类型 | 存储 JSON 数据(MySQL 5.7+) |
数据类型选择建议
-- 整数选择:通常 BIGINT 能满足整数存储需求
id BIGINT NOT NULL AUTO_INCREMENT
-- 字符串选择:VARCHAR(N) 能满足大部分字符串存储需求
name VARCHAR(100) NOT NULL
-- 金额计算:使用 DECIMAL 避免精度丢失
price DECIMAL(10, 2) NOT NULL最佳实践:
- 整数优先选择
BIGINT,避免溢出风险 - 字符串优先选择
VARCHAR,节省存储空间 - 金额计算必须使用
DECIMAL,避免浮点精度问题 - 时间存储优先使用
DATETIME或TIMESTAMP
DB、DBS 和 DBMS 的区别
| 术语 | 全称 | 说明 |
|---|---|---|
| DBMS | DataBase Management System | 数据库管理系统,可以对多个数据库进行管理 |
| DB | DataBase | 数据库,存储数据的集合,包含多个数据表 |
| DBS | DataBase System | 数据库系统,包括数据库、DBMS 和数据库管理员 DBA |
关系图:
数据库系统 (DBS)
├── 数据库管理系统 (DBMS)
│ ├── 管理程序
│ └── 数据库 (DB)
│ ├── 数据表1
│ ├── 数据表2
│ └── ...
└── 数据库管理员 (DBA)注意:虽然常把 Oracle、MySQL 等称为数据库,但确切地说应该是数据库管理系统(DBMS)。
主流数据库
关系型数据库是 DBMS 的主流,使用最多的 DBMS 分别是 Oracle、MySQL 和 SQL Server。
数据库分类
| 类型 | 代表产品 | 适用场景 |
|---|---|---|
| 商用数据库 | Oracle、SQL Server、DB2 | 大型企业应用 |
| 开源数据库 | MySQL、PostgreSQL | 互联网应用、中小型企业 |
| 桌面数据库 | Access | 桌面应用程序 |
| 嵌入式数据库 | SQLite | 手机应用、桌面程序 |
主流数据库对比
| 数据库 | 开源 | 特点 | 适用场景 |
|---|---|---|---|
| Oracle | 否 | 功能强大、稳定性高、收费昂贵 | 金融、电信等大型企业 |
| MySQL | 是 | 轻量级、高性能、社区活跃 | 互联网应用、中小型项目 |
| SQL Server | 否 | 与 Windows 深度集成 | 企业级 Windows 应用 |
| PostgreSQL | 是 | 功能丰富、扩展性强 | 复杂查询、地理信息 |
| SQLite | 是 | 零配置、单文件存储 | 移动应用、嵌入式设备 |

SQL 语言详解
SQL(Structured Query Language)是结构化查询语言的缩写,用来访问和操作数据库系统。
SQL 的特点
- 统一标准:不同的数据库都支持 SQL,学习一种语言可以操作多种数据库
- 声明式语言:只需要告诉数据库"做什么",不需要知道"怎么做"
- 非过程化:不需要一步步指定操作步骤
SQL 方言
虽然 SQL 已被 ANSI 组织定义为标准,但各个数据库对标准 SQL 的支持不完全一致:
| 数据库 | 扩展 SQL 名称 | 说明 |
|---|---|---|
| Oracle | PL/SQL | Procedure Language/SQL |
| SQL Server | T-SQL | Transact-SQL |
| MySQL | SQL/PSM | 基于 SQL 标准的存储模块 |
最佳实践:如果只使用标准 SQL 的核心功能,所有数据库通常都可以执行。尽量避免使用特定数据库的方言,以提高代码的可移植性。
SQL 语言分类
| 分类 | 全称 | 说明 | 常用语句 |
|---|---|---|---|
| DDL | Data Definition Language | 数据定义语言 | CREATE、ALTER、DROP |
| DML | Data Manipulation Language | 数据操作语言 | INSERT、UPDATE、DELETE |
| DQL | Data Query Language | 数据查询语言 | SELECT |
| DCL | Data Control Language | 数据控制语言 | GRANT、REVOKE |
SQL 语法规范
大小写规则:
- SQL 关键字不区分大小写(SELECT = select)
- 表名和列名在不同数据库中规则不同
- 建议:关键字大写,表名和列名小写
-- 推荐写法
SELECT id, name FROM students WHERE score >= 60;
-- 不推荐写法
select ID, NAME from STUDENTS where SCORE >= 60;ER 图(实体关系图)
在创建数据库之前,需要进行数据库设计。对于 RDBMS,采用 ER 图(Entity Relationship Diagram)进行设计。
ER 图三要素
| 要素 | 说明 | 表示方式 |
|---|---|---|
| 实体 | 要管理的对象 | 矩形 |
| 属性 | 实体的特征 | 椭圆 |
| 关系 | 对象之间的联系 | 菱形 |
ER 图示例
以游戏系统为例:
实体:
- 英雄:姓名、职业、最大生命值、攻击范围等
- 用户:用户ID、登录名、密码、性别、头像等
关系:
- 英雄和用户:多对多关系(一个英雄可以从属多个用户,一个用户也可以拥有多个英雄)
┌─────────┐ ┌─────────┐
│ 用户 │ ────< │ 英雄用户 │ >──── │ 英雄 │
└─────────┘ └─────────┘ └─────────┘ER 图工具
- Navicat:在左侧面板选择数据库,导航条选择"查看"→"ER 图表"
- PowerDesigner:专业的数据库设计工具
- MySQL Workbench:MySQL 官方工具
- draw.io:在线绘图工具
实践建议
学习路径
- 基础阶段:掌握 SQL 基本语法(SELECT、INSERT、UPDATE、DELETE)
- 进阶阶段:学习多表查询、子查询、索引优化
- 高级阶段:掌握存储过程、事务处理、性能调优
开发规范
-- 1. 使用有意义的表名和字段名
CREATE TABLE students (
id BIGINT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
class_id BIGINT NOT NULL
);
-- 2. 添加适当的注释
CREATE TABLE students (
id BIGINT PRIMARY KEY COMMENT '学生ID',
name VARCHAR(50) NOT NULL COMMENT '学生姓名',
class_id BIGINT NOT NULL COMMENT '班级ID'
) COMMENT '学生信息表';
-- 3. 遵循命名规范
-- 表名:小写,下划线分隔,如 user_info
-- 字段名:小写,下划线分隔,如 create_time
-- 主键:id 或 表名_id
-- 外键:关联表名_id,如 user_id常见误区
-
误区一:NoSQL 会完全取代关系数据库
- 事实:SQL 和 NoSQL 是互补关系,各有适用场景
-
误区二:SQL 越复杂越好
- 事实:简单清晰的 SQL 更易维护,性能更好
-
误区三:不需要学习数据库原理
- 事实:理解底层原理有助于写出高效的 SQL
总结
关系型数据库是现代软件开发的基石,掌握 SQL 是每个开发者的必备技能:
- 关系模型:通过二维表存储数据,简单直观
- SQL 语言:统一的数据库操作语言,跨数据库通用
- 数据类型:合理选择数据类型,保证数据完整性
- ER 图设计:开发前进行数据库设计,避免后期返工