第一章:SQL 语言基础 —— 数据库交互的核心艺术
本文系统解析了SQL语言的五大分类体系及其底层逻辑:1)DDL(数据定义语言)负责数据库对象结构的创建与修改,具有隐式提交特性;2)DML(数据操作语言)处理数据记录的增删改,支持事务控制;3)DQL(数据查询语言)专注于数据检索,遵循特定的执行顺序;4)DCL(数据控制语言)管理访问权限;5)TCL(事务控制语言)处理事务提交与回滚。文章通过Mermaid图表、代码示例和操作流程详细说明了各类S
摘要:本章将深入剖析结构化查询语言(SQL)的底层逻辑与分类体系。我们将不仅仅停留在“怎么写”的层面,更要探讨“为什么要这样写”以及数据库内核是如何理解这些指令的。通过本章的学习,你将建立起对 SQL 语言全貌的宏观认知,掌握 DDL、DML、DQL、DCL 及 TCL 的本质区别与协作机制,并养成符合工业界标准的 SQL 编码规范。
1.1 SQL 语言分类:构建数据库世界的五大支柱
SQL (Structured Query Language) 并非仅仅是一门单一的查询语言,而是一套功能完备的数据库管理指令集。根据功能的不同,SQL 被严格划分为五大类。理解这种分类不仅有助于记忆命令,更能帮助你理解数据库系统内部的权限隔离与执行模块划分。
1.1.1 宏观架构图:SQL 指令集的层次结构
1.1.2 DDL (Data Definition Language) —— 数据库的建筑师
DDL 负责定义数据库的“骨架”。它不涉及具体的数据行,而是操作数据库对象(如数据库、表、索引、视图、存储过程等)的结构。
-
核心特征:
- 隐式提交:大多数 DDL 语句在执行后会强制触发一次事务提交(Commit),这意味着 DDL 操作通常是不可回滚的(在 MySQL 中)。
- 元数据操作:DDL 修改的是数据字典(Data Dictionary)或元数据(Metadata)。
-
核心指令:
CREATE:从无到有创建对象。ALTER:修改现有对象的结构(如加字段、改类型)。DROP:彻底销毁对象及其包含的所有数据。TRUNCATE:清空表内数据并重置自增计数器(虽然它清除数据,但因其操作的是物理页且不可回滚,通常被归类为 DDL)。
-
执行流程示意:
1.1.3 DML (Data Manipulation Language) —— 数据的搬运工
DML 是我们在业务开发中使用最高频的语言类别(除了查询)。它负责对表中的**记录(Rows)**进行增、删、改。
-
核心特征:
- 事务性:DML 操作可以被包含在事务中,支持回滚(Rollback)。
- 锁机制:DML 操作通常会触发行锁(Row Lock)或表锁,以保证并发一致性。
-
核心指令:
INSERT:插入新行。UPDATE:修改现有行的内容。DELETE:删除特定的行。
-
代码示例与深度解析:
为了演示 DML 操作,我们需要先创建一个测试表
users(关于CREATE TABLE的细节将在第二章详述,此处仅为演示 DML 准备环境):-- 准备环境:如果表已存在则删除,并创建一个新表 DROP TABLE IF EXISTS users; CREATE TABLE users ( id INT PRIMARY KEY, username VARCHAR(50), status VARCHAR(20), created_at DATETIME, updated_at DATETIME );

接下来是核心的 DML 操作演示:
-- 开启一个显式事务(为了演示 DML 的可回滚性)
START TRANSACTION;
-- 1. INSERT: 插入操作
-- 意图:向 users 表中新增一条用户记录
INSERT INTO users (
id, -- 用户ID,主键
username, -- 用户名
status, -- 状态
created_at -- 创建时间
) VALUES (
101, -- ID 值
'Alice_Wonderland', -- 用户名值
'ACTIVE', -- 状态值
NOW() -- 当前系统时间函数
);
-- 此时数据仅在内存缓冲区和事务日志中,其他事务可能不可见(取决于隔离级别)
-- 2. UPDATE: 更新操作
-- 意图:将刚刚插入的用户的状态修改为 'VIP'
UPDATE users
SET
status = 'VIP', -- 修改的目标列和值
updated_at = NOW() -- 同时更新修改时间
WHERE
id = 101; -- [重要] 务必带上 WHERE 条件,否则会更新全表!
-- 3. DELETE: 删除操作
-- 意图:删除 ID 为 101 的用户
DELETE FROM users
WHERE
id = 101; -- [重要] 同样需要 WHERE 条件
-- 提交事务,将上述所有操作永久写入磁盘
COMMIT;



添加成功
修改测试

删除示例
没了
1.1.4 DQL (Data Query Language) —— 数据的洞察者
DQL 专注于数据的检索,不会修改数据本身。它是 SQL 中最复杂、最灵活的部分。
-
核心特征:
- 只读性:DQL 不会对数据库产生副作用(不修改数据)。
- 执行顺序:DQL 的书写顺序与数据库引擎的执行顺序截然不同。
-
核心指令:
SELECT:唯一的入口。
-
DQL 执行流详解(面试必问):
我们在写 SQL 时是这样的顺序:SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...
但数据库引擎执行的顺序是这样的:
- 示例:
-- 这是一个典型的 DQL 语句 SELECT department_id, -- 4. 选择显示的列 COUNT(*) as emp_count -- 4. 计算聚合值 FROM employees -- 1. 确定数据来源 WHERE status = 'ACTIVE' -- 2. 初步过滤:只看在职员工 GROUP BY department_id -- 3. 按部门分组 HAVING emp_count > 10 -- 5. 二次过滤:只保留人数大于10的部门 ORDER BY emp_count DESC; -- 6. 结果排序
1.1.5 DCL (Data Control Language) —— 数据的安保员
DCL 用于定义数据库的访问权限和安全级别。它决定了“谁”可以对“什么对象”进行“什么操作”。
-
核心指令:
GRANT:授予权限。REVOKE:回收权限。
-
场景示例:
-- 创建一个只读用户 report_user CREATE USER 'report_user'@'%' IDENTIFIED BY 'StrongPass123!'; -- GRANT: 授权 -- 允许该用户对 mydb 数据库下的所有表进行 SELECT 查询 GRANT SELECT ON mydb.* TO 'report_user'@'%'; -- 刷新权限表使配置立即生效 FLUSH PRIVILEGES; -- REVOKE: 撤销权限 -- 如果发现该用户不再需要查询权限 REVOKE SELECT ON mydb.* FROM 'report_user'@'%';
1.1.6 TCL (Transaction Control Language) —— 数据的时空穿梭机
TCL 用于维护数据的一致性,它允许我们将一组 SQL 操作视为一个原子单元(Atomic Unit)。
-
核心指令:
COMMIT:提交事务,将更改永久保存。ROLLBACK:回滚事务,撤销未提交的更改。SAVEPOINT:设置保存点,允许回滚到事务的特定位置。
-
事务生命周期图:
1.2 SQL 语法规范:像专家一样写代码
编写能运行的 SQL 很简单,但编写可维护、高性能、跨平台的 SQL 需要遵循严格的规范。
1.2.1 大小写规则 (Case Sensitivity)
这是 SQL 初学者最容易困惑的地方,因为其行为取决于操作系统和配置。
-
关键字(Keywords):
- 规则:SQL 关键字(如
SELECT,FROM,WHERE)通常不区分大小写。 - 最佳实践:为了提高代码可读性,所有 SQL 关键字建议全大写。
- Bad:
select * from users; - Good:
SELECT * FROM users;
- 规则:SQL 关键字(如
-
表名与数据库名(Identifier):
- Windows:默认不区分大小写。
- Linux/Unix:默认区分大小写(取决于文件系统)。
- MySQL 配置:
lower_case_table_names参数控制此行为。 - 最佳实践:表名和字段名统一使用小写,并用下划线分隔 (snake_case)。这能最大程度保证跨平台兼容性。
- Bad:
SELECT * FROM UserInfo;(在 Linux 上可能报错 Table ‘UserInfo’ doesn’t exist) - Good:
SELECT * FROM user_info;
1.2.2 命名规范
好的命名是文档的一半。
- 表名:
- 使用复数名词(如
users,orders)或单数名词(如user,order),但在整个项目中必须保持一致。推荐使用复数,因为表是记录的集合。 - 加上业务前缀可避免冲突(如
sys_config,biz_orders)。
- 使用复数名词(如
- 字段名:
- 避免使用 SQL 保留字(如
order,desc,key)。如果非要用,必须用反引号`包裹,但极其不推荐。 - 表达清晰,如
user_id优于uid,create_time优于ct。
- 避免使用 SQL 保留字(如
- 索引名:
- 主键:
pk_表名 - 唯一索引:
uk_字段名 - 普通索引:
idx_字段名
- 主键:
1.2.3 注释的使用 (Comments)
代码是写给人看的,顺便给机器执行。
-
单行注释:
- 使用
--(注意双横线后必须有一个空格,这是 SQL 标准)。 - 使用
#(这是 MySQL 特有的扩展,不推荐在跨数据库场景使用)。
- 使用
-
多行注释:
- 使用
/* 注释内容 */。
- 使用
-
MySQL 特有的“可执行注释”:
- 格式:
/*! MySQL版本号 SQL语句 */ - 用途:这是一种非常巧妙的兼容性设计。如果数据库版本高于指定版本,则执行其中的语句;否则当作普通注释忽略。这在数据库迁移和备份(mysqldump)中非常常见。
-- 示例:仅在 MySQL 5.7.0 及以上版本执行该语句 /*!50700 ALTER TABLE users ADD COLUMN json_data JSON */; - 格式:
1.2.4 语句结束符
-
标准结束符:分号
;。 -
命令行中的特殊情况:
- 在
mysql命令行工具中,如果你正在编写存储过程或触发器,分号会被识别为语句结束并立即执行,这会导致代码截断报错。 - 解决方案:使用
DELIMITER命令临时修改结束符。
-- 1. 将结束符修改为 // DELIMITER // -- 2. 编写包含分号的复杂逻辑 CREATE PROCEDURE get_user_count() BEGIN SELECT COUNT(*) FROM users; -- 这里的 ; 不会触发执行 END // -- 遇到 // 才认为是结束 -- 3. 恢复结束符为 ; DELIMITER ; - 在
1.2.5 字符串引用
- 值引用:字符串值必须使用单引号
'value'。虽然 MySQL 允许双引号"value",但这不符合 ANSI SQL 标准(在标准 SQL 中,双引号用于引用标识符)。- 推荐:
SELECT * FROM users WHERE name = 'Alice';
- 推荐:
- 标识符引用:如果表名或字段名包含特殊字符、空格或与关键字冲突,使用反引号
`包裹(MySQL 特有)或双引号"包裹(ANSI 模式)。- 示例:
SELECT `select`, `from` FROM `where`;(虽然合法,但请千万不要这样命名!)
- 示例:
1.3 本章小结
本章我们构建了 SQL 语言的宏观地图。请记住以下关键点:
- DDL 定义结构,通常不可回滚。
- DML 操作数据,支持事务。
- DQL 逻辑执行顺序与书写顺序不同(FROM 先于 SELECT)。
- 规范:关键字大写,表名小写(snake_case),字符串用单引号,结束符用分号。
在下一章中,我们将深入 DDL 的世界,亲手创建我们的第一个数据库和数据表,并探讨数据类型的奥秘。
更多推荐



所有评论(0)