SQL 是访问和处理关系数据库的计算机标准语言。无论使用什么编程语言(Java、Python、C++……)编写程序,只要涉及操作关系数据库,都必须通过 SQL 来完成。
对于从事编程或互联网行业的人来说,最具有通用性的语言之一便是 SQL。自从 SQL 加入 TIOBE 编程语言排行榜以来,长期位居榜单前列。
为什么 SQL 如此重要:
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| 术语 | 全称 | 说明 |
|---|---|---|
| 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(Structured Query Language)是结构化查询语言的缩写,用来访问和操作数据库系统。
虽然 SQL 已被 ANSI 组织定义为标准,但各个数据库对标准 SQL 的支持不完全一致:
| 数据库 | 扩展 SQL 名称 | 说明 |
|---|---|---|
| Oracle | PL/SQL | Procedure Language/SQL |
| SQL Server | T-SQL | Transact-SQL |
| MySQL | SQL/PSM | 基于 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 |
大小写规则:
-- 推荐写法
SELECT id, name FROM students WHERE score >= 60;
-- 不推荐写法
select ID, NAME from STUDENTS where SCORE >= 60;在创建数据库之前,需要进行数据库设计。对于 RDBMS,采用 ER 图(Entity Relationship Diagram)进行设计。
| 要素 | 说明 | 表示方式 |
|---|---|---|
| 实体 | 要管理的对象 | 矩形 |
| 属性 | 实体的特征 | 椭圆 |
| 关系 | 对象之间的联系 | 菱形 |
以游戏系统为例:
实体:
关系:
┌─────────┐ ┌─────────┐
│ 用户 │ ────< │ 英雄用户 │ >──── │ 英雄 │
└─────────┘ └─────────┘ └─────────┘-- 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 越复杂越好
误区三:不需要学习数据库原理
关系型数据库是现代软件开发的基石,掌握 SQL 是每个开发者的必备技能: