在前一篇中,我们成功创建了数据库和表,并初步了解了数据类型。接下来,我们将进入数据库操作中最核心、最常用的部分------CRUD。CRUD 是四个基本操作的缩写:C reate(增加)、R ead(查询)、U pdate(更新)、Delete(删除)。这四项操作几乎是所有数据库应用的基础,熟练掌握它们,就掌握了与数据库交互的"对话能力"。
本文将以之前创建的 users 表为载体,带你系统学习:
- 使用
INSERT插入单行、多行数据 - 使用
SELECT查询数据(全列、指定列、表达式、别名、去重) - 使用
UPDATE修改数据 - 使用
DELETE删除数据 - 实战:完成用户表的增删改查
1. 插入数据:INSERT INTO
1.1 基本语法
sql
INSERT INTO 表名 [(列1, 列2, ...)]
VALUES (值1, 值2, ...),
(值3, 值4, ...),
...;
- 列名列表是可选的,如果省略,则需要按表定义顺序为所有列提供值(自动增长的列可以指定
NULL或DEFAULT)。 - 可以一次性插入多行数据,以提高效率。
1.2 插入单行
我们以上一篇创建的 users 表为例,插入一条完整的记录:
sql
INSERT INTO users (username, email, password, birthdate, status)
VALUES ('alice', 'alice@example.com', 'hashed_pw_alice', '1995-06-15', 1);
因为 id 列是 AUTO_INCREMENT,我们无需手动指定,MySQL 会自动生成。mobile、avatar_url、signature、last_login_at 等列有默认值或允许 NULL,未指定则会自动使用默认值(NULL 或指定默认值)。
验证插入结果:
sql
SELECT * FROM users;
1.3 插入多行
可以一次性插入多条记录,用逗号分隔:
sql
INSERT INTO users (username, email, password, birthdate, status)
VALUES
('bob', 'bob@example.com', 'hashed_pw_bob', '1990-01-20', 1),
('carol', 'carol@example.com', 'hashed_pw_carol', '2000-08-03', 1),
('dave', 'dave@example.com', 'hashed_pw_dave', '1985-12-12', 1);
1.4 插入指定列
如果你的 INSERT 语句只包含了部分列,那么其他未指定的列将使用默认值或 NULL(取决于定义)。例如,只插入必填字段:
sql
INSERT INTO users (username, email, password)
VALUES ('eve', 'eve@example.com', 'hashed_pw_eve');
此时,birthdate 会为 NULL,status 会使用默认值 1。
2. 查询数据:SELECT
SELECT 是 SQL 中使用最频繁的语句,用于从表中检索数据。
2.1 基本查询
查询所有列:
sql
SELECT * FROM users;
使用 * 很方便,但在生产环境中通常不推荐,因为它可能带来不必要的 I/O 开销,且无法利用覆盖索引优化。明确列出所需列是更好的习惯。
查询指定列:
sql
SELECT username, email FROM users;
2.2 表达式与别名
你可以在 SELECT 列表中使用表达式。例如,如果我们想展示一个由 username 和 email 组合而成的"显示名":
sql
SELECT username, CONCAT(username, ' <', email, '>') AS display_name
FROM users;
AS用于给列或表达式取别名,方便阅读。别名也可以用在后续的ORDER BY或GROUP BY中(但需注意标准 SQL 的执行顺序)。- 如果别名包含空格或特殊字符,需要用反引号或双引号包裹,如
AS 'display name'。
算术运算示例:假设有一张商品表,可以使用 price * quantity 计算总价。
2.3 去重:DISTINCT
如果想查看用户表中有哪些不同的出生年份(假设我们存储的是 DATE 类型),可以使用 DISTINCT:
sql
SELECT DISTINCT YEAR(birthdate) AS birth_year FROM users WHERE birthdate IS NOT NULL;
DISTINCT 作用在整个选择列表上,即去掉所有选择列都相同的行。
2.4 查询常量与函数
SELECT 也可以查询不来自表的数据,如系统信息:
sql
SELECT VERSION(), NOW(), 'Hello' AS greeting;
这在调试或写存储过程时很有用。
3. 修改数据:UPDATE
UPDATE 语句用于修改表中已存在的行。
3.1 基本语法
sql
UPDATE 表名
SET 列1 = 新值1, 列2 = 新值2, ...
[WHERE 条件];
⚠️ 强烈建议先写 WHERE 条件再执行,避免误更新整个表!
3.2 示例:更新用户状态和签名
将用户 alice 的状态改为"冻结"(0),并添加个性签名:
sql
UPDATE users
SET status = 0, signature = '暂时离开,勿念'
WHERE username = 'alice';
验证更新:
sql
SELECT username, status, signature FROM users WHERE username = 'alice';
如果忘记添加 WHERE 条件,所有行的 status 都会被更新,后果将非常严重。
3.3 使用表达式更新
可以在 SET 中使用当前列的值。比如把所有用户的激活状态反转(0 变 1,1 变 0)------ 虽然这不是常规操作,但演示一下:
sql
UPDATE users SET status = 1 - status;
这会把 status = 0 的变为 1,status = 1 的变为 0。执行前务必确认 WHERE 条件是否必要。
4. 删除数据:DELETE
4.1 基本语法
sql
DELETE FROM 表名
[WHERE 条件];
同样需要万分小心,没有 WHERE 条件的 DELETE 会清空整个表! 如果只是想要清空表,更高效的方式是使用 TRUNCATE TABLE 表名,它会重置自增计数器且不记录逐行删除日志。
4.2 删除指定行
删除用户 bob:
sql
DELETE FROM users WHERE username = 'bob';
如果存在多条 username = 'bob',则会全部删除。建议 DELETE 时使用唯一键(如主键)来精确定位。
4.3 删除所有行(慎用)
sql
DELETE FROM users;
与 DROP TABLE users; 不同,DELETE 仅删除数据,保留表结构和索引等。如果要清空表且希望重置自增值,可以使用:
sql
TRUNCATE TABLE users;
TRUNCATE 是一个 DDL 操作,无法回滚,速度极快。
5. 实战:完成用户表的增删改查
让我们把前面的知识串起来,模拟一个简单的用户管理场景。假设我们有一个初始为空的 users 表(可重新创建或清空数据后操作)。
5.1 插入用户
sql
INSERT INTO users (username, email, password, birthdate) VALUES
('zhangsan', 'zhangsan@example.com', 'pass_zhangsan', '1998-07-10'),
('lisi', 'lisi@example.com', 'pass_lisi', '2002-11-25'),
('wangwu', 'wangwu@example.com', 'pass_wangwu', '1995-03-08'),
('zhaoliu', 'zhaoliu@example.com', 'pass_zhaoliu', '1990-09-17');
5.2 查询所有已激活用户
sql
SELECT id, username, email, birthdate
FROM users
WHERE status = 1;
5.3 更新用户邮箱
lisi 更换了邮箱:
sql
UPDATE users
SET email = 'lisi_new@example.com'
WHERE username = 'lisi';
5.4 删除某个用户
zhaoliu 注销账号:
sql
DELETE FROM users WHERE username = 'zhaoliu';
5.5 验证最终结果
sql
SELECT * FROM users;
你应该能看到 zhangsan、lisi、wangwu 三个人,其中 lisi 的邮箱已更新,zhaoliu 已消失。
扩展练习
- 尝试批量插入 10 条用户记录,其中有几个用户的状态设为 0。
- 编写一个 UPDATE 语句,将所有 2000 年后出生的用户签名统一设置为"千禧一代"。
(提示:WHERE birthdate > '2000-01-01') - 删除所有状态为 0 的用户(使用 DELETE)。
6. 小结
本文我们学习了 MySQL 中最基础的 CRUD 操作:
INSERT插入数据,支持单行、多行及指定列;SELECT查询数据,包括指定列、表达式、别名和DISTINCT;UPDATE修改数据,必须谨慎加 WHERE 条件;DELETE删除数据,同样需确认条件,清空表时可考虑 TRUNCATE。
这些操作是后续所有复杂查询和数据处理的基础。下一篇我们将深入 SELECT 的过滤与排序,让数据查询更加精准和高效。
思考题:
- 如果用
INSERT INTO users VALUES (NULL, ...)插入,会发生什么?(提示:自增列可以显式给 NULL 吗?) DELETE和TRUNCATE的区别是什么?在事务中使用它们,回滚后效果有何不同?- 假设我们误执行了无 WHERE 的 UPDATE,有没有办法恢复?(提示:需要提前准备什么?)
参考资料
- MySQL 8.0 Reference Manual - INSERT Statement
- MySQL 8.0 Reference Manual - SELECT Statement
- MySQL 8.0 Reference Manual - UPDATE Statement
- MySQL 8.0 Reference Manual - DELETE Statement