作为一名数据库开发工程师,我经常遇到新手对DML语句的困惑。DML(Data Manipulation Language)是MySQL中最核心的操作语言,掌握好DML语句的使用,才能真正驾驭数据库中的数据操作。本文将带你深入理解DML语句的方方面面,从基础概念到高级用法,再到实际开发中的注意事项。
DML全称Data Manipulation Language(数据操作语言),它与DDL(数据定义语言)的核心区别在于:DDL操作的是数据库对象的结构(如表、索引等),而DML操作的是表中的数据内容。
提示:虽然严格来说SELECT属于DQL(数据查询语言),但在实际开发中我们通常将其归入DML范畴,因为查询是最常用的数据操作。
| 操作类型 | SQL语句 | 说明 |
|---|---|---|
| 插入数据 | INSERT | 向表中新增记录 |
| 更新数据 | UPDATE | 修改已有记录 |
| 删除数据 | DELETE | 删除记录 |
| 查询数据 | SELECT | 检索记录(严格属DQL) |
最规范的INSERT语法应明确指定列名和对应值:
sql复制INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2);
示例:向学生表插入数据
sql复制-- 创建学生表
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT,
major VARCHAR(100)
);
-- 插入单条数据
INSERT INTO student (name, age, major)
VALUES ('张三', 20, '计算机科学');
批量插入可显著提高效率:
sql复制INSERT INTO student (name, age, major) VALUES
('李四', 21, '软件工程'),
('王五', 19, '人工智能'),
('赵六', 22, '网络工程');
注意:批量插入时,建议每次不超过1000条,避免事务过大导致性能问题。
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 插入失败 | 列与值不匹配 | 检查列顺序和数据类型 |
| 主键冲突 | 重复主键值 | 使用AUTO_INCREMENT或检查业务逻辑 |
| 数据截断 | 值超过列长度 | 验证数据长度是否符合列定义 |
sql复制UPDATE student
SET age = 22, major = '大数据'
WHERE name = '张三';
sql复制UPDATE student
SET major = '人工智能'
WHERE age > 20 AND major = '计算机科学';
sql复制DELETE FROM student WHERE id = 3;
| 特性 | DELETE | TRUNCATE |
|---|---|---|
| 执行速度 | 较慢 | 极快 |
| 可回滚 | 是 | 否 |
| 重置自增 | 否 | 是 |
| 日志记录 | 详细 | 最小化 |
建议:需要条件删除用DELETE,快速清空表用TRUNCATE
sql复制SELECT 列1, 列2 FROM 表名
WHERE 条件
ORDER BY 排序列
LIMIT 条数;
sql复制-- 年龄大于20且专业为AI的学生
SELECT * FROM student
WHERE age > 20 AND major = '人工智能';
-- 模糊查询姓名含"张"的学生
SELECT * FROM student
WHERE name LIKE '%张%';
sql复制SELECT
COUNT(*) AS 总人数,
AVG(age) AS 平均年龄,
MAX(age) AS 最大年龄
FROM student;
sql复制SELECT major, COUNT(*) AS 人数
FROM student
GROUP BY major
HAVING COUNT(*) > 2;
sql复制-- 第一页(1-10条)
SELECT * FROM student LIMIT 0, 10;
-- 第二页(11-20条)
SELECT * FROM student LIMIT 10, 10;
sql复制START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 或ROLLBACK回滚
java复制@Transactional
public void transfer(int fromId, int toId, int amount) {
accountMapper.decreaseBalance(fromId, amount);
accountMapper.increaseBalance(toId, amount);
}
提示:Spring的@Transactional注解会自动处理事务提交和回滚
理解SQL的实际执行顺序对编写高效查询至关重要:
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| 更新影响行数过多 | 缺少WHERE条件 | 添加精确条件 |
| 插入失败 | 违反约束 | 检查主键、外键、非空约束 |
| 死锁 | 事务交叉 | 调整事务顺序或隔离级别 |
| 性能下降 | 缺少索引 | 分析执行计划添加索引 |
掌握DML语句是MySQL开发的基础,建议通过实际项目不断练习。我在最初学习时,曾因忘记WHERE条件导致全表更新,这个教训让我深刻理解了DML操作的重要性。记住:生产环境的DML操作一定要谨慎再谨慎!