当前位置: 首页 > news >正文

深入理解 DML 和 DQL:SQL 数据操作与查询全解析

深入理解 DML 和 DQL:SQL 数据操作与查询全解析

在数据库管理中,SQL(结构化查询语言)是操作和查询数据的核心工具。其中,DML(Data Manipulation Language,数据操作语言)DQL(Data Query Language,数据查询语言) 是最常用的子集。DML 负责数据的插入、更新和删除,而 DQL 专注于数据查询。本文将详细讲解 DML 和 DQL 的核心操作,包括 UPDATEDELETETRUNCATESELECT,以及相关函数和子句,结合示例帮助你快速上手。


一、DML:数据操作语言

DML 用于操作数据库中的数据,主要包括以下操作:

  • 插入(INSERT):向表中添加新记录。
  • 更新(UPDATE):修改表中已有记录。
  • 删除(DELETE):移除表中记录。

以下重点讲解 UPDATEDELETE,并深入分析 TRUNCATEDELETE 的区别。

1. UPDATE:修改数据

UPDATE 用于修改表中符合条件的记录,语法如下:

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
  • 作用:更新指定列的值。
  • 注意WHERE 子句指定更新的范围,未指定会导致全表更新。
示例

假设有一个 student 表:

idnameage
1Alice20
2Bob22
3Charlie20

需求:将年龄为 20 的学生年龄改为 21。

UPDATE student
SET age = 21
WHERE age = 20;

结果

idnameage
1Alice21
2Bob22
3Charlie21

注意

  • 没有 WHERE 子句时,UPDATE student SET age = 21; 会将所有记录的 age 改为 21。
  • 建议先用 SELECT 查询确认受影响的记录。

2. DELETE:删除数据

DELETE 用于删除表中符合条件的记录,语法如下:

DELETE FROM table_name
WHERE condition;
  • 作用:移除满足条件的记录。
  • 注意:不带 WHERE 会删除表中所有记录。
示例

需求:删除年龄小于 22 的学生。

DELETE FROM student
WHERE age < 22;

结果

idnameage
2Bob22

注意

  • 删除后,表结构和索引保留,数据可通过事务回滚(如果在事务中)。
  • 自增列计数器行为因存储引擎不同而异(详见下文)。

3. TRUNCATE:清空表

TRUNCATE 用于完全清空表中的数据,语法如下:

TRUNCATE TABLE table_name;
  • 作用:删除表中所有记录,重置表到初始状态。
  • 注意:无法指定条件,总是清空整个表。
示例

需求:清空 student 表。

TRUNCATE TABLE student;

结果

  • 表变为空,结构保留。
  • 自增列计数器重置为 1。

二、TRUNCATE 与 DELETE 的区别

TRUNCATEDELETE 都可以删除数据,但有显著差异。以下是详细对比:

特性DELETETRUNCATE
删除范围可通过 WHERE 删除部分记录删除整个表,无条件
速度较慢,逐行删除,记录日志更快,直接重建表结构
事务支持支持事务,可回滚不影响事务,无法回滚
自增列计数器不重置,保留上次值重置为 1
触发器触发 DELETE 触发器不触发触发器
外键约束支持(受外键限制)不支持(表有外键时无法使用)
日志记录记录每行操作,占用日志空间仅记录表结构变更,日志少

TRUNCATE 的优势

  1. 速度快TRUNCATE 直接重建表结构,效率高于逐行删除的 DELETE
  2. 重置自增列:适合需要重置主键计数器的场景(如测试环境清空数据)。
  3. 不影响事务:执行后不记录逐行日志,节省日志空间。
  4. 低资源占用:适合快速清空大表。

DELETE 删除后的行为(重启数据库)

DELETE 删除数据后,自增列计数器的行为因存储引擎不同而异:

  • InnoDB

    • 自增计数器存储在内存中。

    • 重启数据库后,计数器从 1 重新开始。

    • 示例:

      CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY);
      INSERT INTO test VALUES (1), (2), (3);
      DELETE FROM test;
      INSERT INTO test VALUES (NULL); -- id = 1(重启后)
      
  • MyISAM

    • 自增计数器存储在文件中,持久化。

    • 重启数据库后,从上一个最大值继续。

    • 示例:

      DELETE FROM test;
      INSERT INTO test VALUES (NULL); -- id = 4(继续上一个值)
      
示例:DELETE vs TRUNCATE
-- 创建表
CREATE TABLE student (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),age INT
);
INSERT INTO student (name, age) VALUES ('Alice', 20), ('Bob', 22);-- DELETE
DELETE FROM student;
INSERT INTO student (name, age) VALUES ('Charlie', 21);
-- InnoDB 重启后:id = 1;MyISAM:id = 3-- TRUNCATE
TRUNCATE TABLE student;
INSERT INTO student (name, age) VALUES ('Charlie', 21);
-- 无论引擎:id = 1

三、DQL:数据查询语言

DQL 用于从数据库中检索数据,主要通过 SELECT 语句实现。以下讲解 SELECT 的核心用法,包括简单查询、特定字段查询、别名、去重和条件查询。

1. 简单单表查询

查询整个表
SELECT * FROM student;
  • 作用:返回 student 表的所有列和记录。

  • 示例输出

    (假设表如上):

    id | name    | age
    1  | Alice   | 20
    2  | Bob     | 22
    

注意* 适合快速查看,但生产环境中建议明确指定列以提高性能。

查询特定字段
SELECT name, age FROM student;
  • 作用:只返回 nameage 列。

  • 示例输出

    name    | age
    Alice   | 20
    Bob     | 22
    
给结果起别名

使用 AS 关键字为列或表达式指定别名:

SELECT name AS student_name, age AS student_age FROM student;
  • 输出

    student_name | student_age
    Alice        | 20
    Bob          | 22
    

别名提高可读性,常用在复杂查询或报表生成中。

2. 函数:CONCAT

CONCAT 函数用于拼接字符串,语法如下:

SELECT CONCAT(column1, ' ', column2) AS result FROM table_name;
示例

需求:将学生的姓名和年龄拼接为一个字符串。

SELECT CONCAT(name, ' is ', age, ' years old') AS info FROM student;

输出

info
Alice is 20 years old
Bob is 22 years old

注意

  • 不同数据库对 CONCAT 的支持略有差异(如 MySQL 支持多参数,SQL Server 使用 +)。
  • 可结合其他函数(如 CAST)处理非字符串类型。

3. 去重:DISTINCT

DISTINCT 用于去除查询结果中的重复行,语法如下:

SELECT DISTINCT column1, column2 FROM table_name;
示例

需求:查询所有不同的年龄。

SELECT DISTINCT age FROM student;

假设数据

idnameage
1Alice20
2Bob22
3Charlie20

输出

age
20
22

注意

  • DISTINCT 作用于整行(多列时考虑组合)。
  • 对性能有一定影响,尽量在必要时使用。

4. WHERE 条件子句

WHERE 用于过滤满足条件的记录,语法如下:

SELECT column1, column2
FROM table_name
WHERE condition;
示例

需求:查询年龄大于 20 的学生。

SELECT name, age
FROM student
WHERE age > 20;

输出

name | age
Bob  | 22

常见条件

  • 比较:=, >, <, >=, <=, !=
  • 逻辑:AND, OR, NOT
  • 范围:BETWEEN ... AND ...
  • 集合:IN (value1, value2)
  • 模糊匹配:LIKE '%pattern%'
综合示例

需求:查询年龄为 20 或 22 的学生,拼接姓名和年龄,去重后显示。

SELECT DISTINCT CONCAT(name, ' is ', age) AS info
FROM student
WHERE age IN (20, 22);

输出

info
Alice is 20
Bob is 22
Charlie is 20

四、实际应用场景

  1. 数据清理
    • 使用 DELETE 移除无效记录(如 WHERE created_date < '2020-01-01')。
    • 使用 TRUNCATE 重置测试环境数据。
  2. 数据更新
    • UPDATE 批量修改用户信息(如 SET status = 'active' WHERE last_login > '2023-01-01')。
  3. 报表生成
    • SELECT 结合 CONCATDISTINCT 生成用户统计报表。
    • 使用 WHERE 过滤特定条件的数据。

五、注意事项与优化技巧

  1. DML 操作
    • 事务管理DELETEUPDATE 应在事务中执行,确保可回滚。
    • 日志监控DELETE 操作可能导致日志文件过大,定期清理。
    • 备份:执行 TRUNCATE 前备份数据,因无法回滚。
  2. DQL 查询
    • 索引优化:为 WHERE 条件中的列建立索引,提高查询效率。
    • 避免 SELECT \*:明确指定列,减少不必要的数据传输。
    • 去重性能DISTINCT 可能影响性能,优先考虑业务逻辑去重。
  3. 存储引擎选择
    • InnoDB:适合事务密集场景,自增列需注意重启行为。
    • MyISAM:适合读多写少场景,自增列更稳定。

六、总结

DML 和 DQL 是数据库操作的核心组成部分:

  • DMLUPDATE, DELETE, TRUNCATE)用于修改和删除数据,TRUNCATE 适合快速清空表,DELETE 提供更灵活的条件删除。
  • DQLSELECT)通过 WHEREDISTINCTCONCAT 等功能实现精确查询,满足多样化需求。

通过本文的讲解和示例,你应该能熟练掌握这些操作,并在实际项目中灵活运用。如果有更多疑问或高级用法需求,欢迎在评论区交流!

相关文章:

  • Spring Boot 集成 Redis 实战总结
  • 智能对讲机:通信技术的革新与“危急特”场景的守护者
  • 【KWDB创作者计划】_针对KWDB时序数据库(多副本集群环境)进行压力测试
  • C++如何处理多线程环境下的异常?如何确保资源在异常情况下也能正确释放
  • 【scikit-learn基础】--『监督学习』之 均值聚类
  • Android 15强制edge-to-edge全面屏体验
  • docker部署ruoyi-vue-pro前后端详细笔记
  • Linux:权限相关问题
  • 一款支持多线程的批量任务均衡器
  • AI日报 - 2024年04月22日
  • 实验四-用户和权限管理
  • Uniapp:view容器(容器布局)
  • 微硕WSP4407A MOS管在智能晾衣架中的应用与市场分析
  • 时序逻辑入门指南:LTL、CTL与PTL的概念介绍与应用场景
  • Flowable7.x学习笔记(十)分页查询已部署 BPMN XML 流程
  • 【Python】Python如何在字符串中添加变量
  • leetcode 647. Palindromic Substrings
  • 6N60-ASEMI机器人功率器件专用6N60
  • 《P3029 [USACO11NOV] Cow Lineup S》
  • 使用Mybaitis-plus提供的各种的免写SQL的Wrapper的使用方式
  • 国务院国资委:推动央企强化资金统筹,确保及时付款
  • 经济大省中川、豫、浙一季报已发:GDP增速均高于全国
  • 甘肃古浪县发生3.0级地震,未接到人员伤亡和财产损失报告
  • 85岁眼科专家、武汉大学人民医院原眼科主任喻长泰逝世
  • 马上评|机器人马拉松,也是具身智能产业的加速跑
  • 美接连派轰炸机、无人机前往日本,驻日美军正升级空中力量