DML(Data Manipulation Language,数据操作语言)是 SQL 中用于操作数据库表中具体数据的核心部分。如果说 DDL 是建造大楼的框架,那么 DML 就是在大楼里搬运家具、装修房间和清理垃圾的过程。
增 (Insert):向表中添加新的数据行。
改 (Update):修改表中已存在的数据行。
删 (Delete):从表中移除特定的数据行。
查 (Select):虽然 SELECT 常被单独归类为 DQL,但在广义的数据操作中,它也是获取数据的关键步骤。
事务性:DML 操作通常包含在事务中。这意味着你可以执行一系列插入、更新或删除操作,然后选择提交 (COMMIT) 使更改永久生效,或者回滚 (ROLLBACK) 撤销所有更改。
安全性:尤其是 UPDATE 和 DELETE 操作,如果忘记加 WHERE 子句,可能会导致全表数据被修改或清空,这是生产环境中极其严重的事故。
INSERT 语句用于向数据库表中添加新记录。
-- 指定列名插入(推荐方式)
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);最佳实践:始终显式列出列名。
原因:如果表结构发生变化(如增加了新列),不写列名的语句可能会报错或插入错误的数据。显式列名让代码更具可读性和健壮性。
为了提高性能,可以在一条语句中插入多行数据,减少网络交互和解析开销。
INSERT INTO table_name (column1, column2, column3, ...)
VALUES
(value1_a, value2_a, value3_a),
(value1_b, value2_b, value3_b),
(value1_c, value2_c, value3_c);假设我们有一个 employees 表:
-- 插入单条记录
INSERT INTO employees (employee_id, first_name, last_name, salary)
VALUES (101, 'John', 'Doe', 50000);
-- 插入多条记录(高效写法)
INSERT INTO employees (employee_id, first_name, last_name, salary)
VALUES
(102, 'Jane', 'Smith', 60000),
(103, 'Bob', 'Johnson', 55000),
(104, 'Alice', 'Williams', 58000);自增主键:如果主键是 AUTO_INCREMENT,插入时可以忽略该列,数据库会自动生成。
INSERT INTO users (username, email) VALUES ('tom', 'tom@example.com');默认值:如果某列定义了 DEFAULT 值且插入时未指定,将自动填入默认值。
部分列插入:只插入非空且有值的列,其他列设为 NULL 或默认值。
UPDATE 语句用于修改表中已存在的记录。务必谨慎使用!
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;SET 子句:指定要修改的列和新值。可以修改单列,也可以同时修改多列(用逗号分隔)。
WHERE 子句:至关重要。它指定哪些行需要被更新。
有 WHERE:只更新符合条件的行。
无 WHERE:更新表中的所有行!这通常是灾难性的。
-- 场景 1:修改单个字段
-- 将产品 ID 为 101 的价格调整为 25.99
UPDATE products
SET price = 25.99
WHERE product_id = 101;
-- 场景 2:基于现有值计算更新
-- 给销售部门 (Sales) 的所有员工加薪 10%
UPDATE employees
SET salary = salary * 1.1
WHERE department = 'Sales';
-- 场景 3:同时修改多个字段
-- 更新用户信息并记录最后修改时间
UPDATE users
SET email = 'new_email@example.com', last_login = NOW()
WHERE user_id = 5;安全提示:在执行
UPDATE之前,建议先执行对应的SELECT语句,确认WHERE条件选中的行正是你想要修改的行。-- 先检查 SELECT * FROM employees WHERE department = 'Sales'; -- 确认无误后再执行 UPDATE
DELETE 语句用于从表中移除记录。
DELETE FROM table_name
WHERE condition;WHERE 子句:同样至关重要。
有 WHERE:删除符合条件的行。
无 WHERE:清空整张表的所有数据(但表结构保留)。
虽然 DELETE FROM table_name (不带 WHERE) 和 TRUNCATE TABLE table_name 都能清空表,但它们有本质区别:
-- 场景 1:删除特定记录
-- 删除员工 ID 为 103 的记录
DELETE FROM employees
WHERE employee_id = 103;
-- 场景 2:批量删除
-- 删除所有已离职 (status='left') 的员工
DELETE FROM employees
WHERE status = 'left';警告:生产环境中严禁随意执行不带
WHERE的DELETE语句。如果需要清空表且不需要保留自增 ID,优先使用TRUNCATE。
基于之前创建的 users 表,完成以下数据操作流程。
假设 users 表结构如下:
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
registration_date DATETIME DEFAULT CURRENT_TIMESTAMP
);需求:插入两个新用户。
用户 1:john_doe, 密码 password123, 邮箱 john@example.com。
用户 2:jane_doe, 密码 pass456, 邮箱 jane@example.com。
注册日期使用默认当前时间。
INSERT INTO users (username, password, email)
VALUES
('john_doe', 'password123', 'john@example.com'),
('jane_doe', 'pass456', 'jane@example.com');注:registration_date 未指定,将自动填入当前时间。
需求:发现 john_doe 的密码泄露,需要将其更新为 new_password789。
UPDATE users
SET password = 'new_password789'
WHERE username = 'john_doe';安全检查:先 SELECT * FROM users WHERE username = 'john_doe'; 确认只有一行受影响。
需求:用户 jane_doe 申请注销账号,需要从数据库中移除。
DELETE FROM users
WHERE username = 'jane_doe';执行查询以确认操作结果:
SELECT * FROM users;预期结果:
表中只剩下 john_doe 的记录。
john_doe 的密码已变为 new_password789。
jane_doe 的记录已消失。