mysql数据库的增删改查(CRUD)

MySQL 增删改查(CRUD)完全指南

本文档专门讲 对表里数据的增、删、改、查,即 CRUD:Create(增)、Read(查)、Update(改)、Delete(删)。每一步都配有详细说明和大量示例,适合零基础新手跟着做。


目录

  1. 什么是 CRUD
  2. 操作前准备:库和表
  3. 增(Create)——INSERT
  4. 查(Read)——SELECT
  5. 改(Update)——UPDATE
  6. 删(Delete)——DELETE
  7. 增删改查综合示例
  8. 必须牢记的注意点
  9. 常见错误与解决
  10. 命令速查表

1. 什么是 CRUD

CRUD 是四个英文单词的首字母:

字母 英文 含义 对应 SQL
C Create 增加数据 INSERT
R Read 查询数据 SELECT
U Update 修改数据 UPDATE
D Delete 删除数据 DELETE

也就是说:

  • = 往表里插入新的一行或多行 → 用 INSERT
  • = 从表里读出满足条件的行 → 用 SELECT
  • = 把表里某些行的列更新成新值 → 用 UPDATE
  • = 把表里某些行删掉 → 用 DELETE

下面会按 增 → 查 → 改 → 删 的顺序,逐个讲语法和示例。


2. 操作前准备:库和表

增删改查都是针对某张表的,表又在某个数据库里,所以要先选库、确保表存在。

2.1 选择数据库

USE school;

2.2 准备一张示例表

后面所有示例都用下面这张表,你可以先建好,跟着一起练:

CREATE TABLE IF NOT EXISTS students (
    id          INT PRIMARY KEY AUTO_INCREMENT,
    name        VARCHAR(50) NOT NULL,
    gender      CHAR(1) DEFAULT '男',
    age         INT,
    class_name  VARCHAR(20),
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP
);
  • id:主键,自增,插入时可以省略。
  • name:必填(NOT NULL)。
  • gender:有默认值 '男',不写就填 '男'
  • ageclass_name:可空。
  • created_at:不写则自动填当前时间。

3. 增(Create)——INSERT

INSERT 用来往表里插入新行

3.1 基本语法(指定列名,推荐)

INSERT INTO 表名 (列1, 列2, 列3, ...) VALUES (值1, 值2, 值3, ...);
  • 列名 要一一对应:列1 对应 值1,列2 对应 值2……
  • 字符串、日期用单引号,数字不用。
  • 没有写出来的列:若没有默认值且允许 NULL,会是 NULL;若有默认值或是自增,按默认/自增处理。

示例:插入一条学生记录

INSERT INTO students (name, gender, age, class_name)
VALUES ('张三', '男', 18, '高一1班');

这里没写 idcreated_at

  • id 自增,会自动变成 1;
  • created_at 有默认值,会自动填当前时间。

再插几条:

INSERT INTO students (name, gender, age, class_name) VALUES ('李四', '女', 17, '高一2班');
INSERT INTO students (name, gender, age, class_name) VALUES ('王五', '男', 18, '高一1班');
INSERT INTO students (name, gender, age, class_name) VALUES ('赵六', '女', 17, '高一2班');
INSERT INTO students (name, gender, age, class_name) VALUES ('钱七', '男', 19, '高一1班');

3.2 一次插入多行(推荐,效率更高)

用一条 INSERT 写多组 VALUES,用逗号隔开:

INSERT INTO students (name, gender, age, class_name) VALUES
('张三', '男', 18, '高一1班'),
('李四', '女', 17, '高一2班'),
('王五', '男', 18, '高一1班'),
('赵六', '女', 17, '高一2班'),
('钱七', '男', 19, '高一1班');

效果和上面分 5 条插入一样,但只执行一次,速度更快。

3.3 插入时写全所有列(不推荐)

如果按表定义的顺序把每一列都写上,可以省略列名,直接 VALUES

INSERT INTO students VALUES (NULL, '孙八', '男', 18, '高一1班', NOW());
  • idNULL 时,自增列会自动生成新 id。
  • 缺点:列顺序一变或表结构一改就容易错,可读性差,建议始终写上列名

3.4 利用默认值:少写几列

有默认值的列可以不写,数据库会自动填默认值:

-- gender 有默认值 '男',不写就是 '男'
INSERT INTO students (name, age, class_name) VALUES ('周九', 18, '高一1班');

-- created_at 有 DEFAULT CURRENT_TIMESTAMP,不写就是当前时间
-- 上面所有示例都没写 created_at,都是自动填的

3.5 主动插入 NULL(可空列)

若列允许 NULL,可以显式插入 NULL:

INSERT INTO students (name, gender, age, class_name) VALUES ('吴十', '女', NULL, NULL);

表示“年龄、班级未知”。

3.6 INSERT IGNORE(主键/唯一冲突时跳过)

若表里有主键或唯一索引,插入时若和已有行冲突会报错。
INSERT IGNORE 时,遇到冲突就跳过该行,不报错:

INSERT IGNORE INTO students (id, name, gender, age, class_name) VALUES
(1, '重复id', '男', 18, '高一1班');
-- 若 id=1 已存在,这条会被忽略,不会报错

3.7 REPLACE INTO(主键/唯一冲突时替换,了解即可)

REPLACE INTO 的写法与 INSERT 类似,但若主键或唯一键冲突,会先删掉旧行,再插入新行(相当于“替换”):

REPLACE INTO students (id, name, gender, age, class_name) VALUES
(1, '新张三', '男', 19, '高一2班');

一般用 INSERTINSERT … ON DUPLICATE KEY UPDATE 更常见,REPLACE 了解即可。

3.8 增(INSERT)小结

  • 推荐写法:INSERT INTO 表名 (列1, 列2, …) VALUES (值1, 值2, …);
  • 多行:多组 VALUES 用逗号隔开。
  • 字符串、日期用单引号;数字不用;可空列可写 NULL
  • 有默认值或自增的列可以不写。

4. 查(Read)——SELECT

SELECT 用来从表里读出数据,是使用频率最高的语句。

4.1 基本语法

SELECT 列1, 列2, ... FROM 表名 [WHERE 条件] [ORDER BY 排序列] [LIMIT 条数];
  • SELECT 列:要查哪些列;FROM 表名:从哪张表查。
  • WHERE:筛选行(可选)。
  • ORDER BY:排序(可选)。
  • LIMIT:只取前几条(可选)。

下面先讲最基础的“查哪些列”“查哪些行”,WHERE/ORDER BY/LIMIT 的详细用法可以配合你已有的「条件与排序」文档一起看。

4.2 查询所有列:SELECT *

*星号 ``** 表示“所有列”:

SELECT * FROM students;

会返回表里所有行、所有列。适合调试,正式代码里建议尽量写具体列名,方便维护。

示例输出(示意):

+----+------+--------+------+------------+---------------------+
| id | name | gender | age  | class_name | created_at          |
+----+------+--------+------+------------+---------------------+
|  1 | 张三 | 男     |   18 | 高一1班    | 2025-02-26 10:00:00 |
|  2 | 李四 | 女     |   17 | 高一2班    | 2025-02-26 10:00:00 |
...
+----+------+--------+------+------------+---------------------+

4.3 查询指定列

只查需要的列,列名用逗号隔开:

SELECT name, age, class_name FROM students;

示例:只查姓名和班级

SELECT name, class_name FROM students;

4.4 给列起别名(AS)

AS 可以把列在结果里显示成另一个名字(不影响表结构):

SELECT name AS 姓名, age AS 年龄, class_name AS 班级 FROM students;

AS 可以省略,用空格隔开“列”和“别名”也行(不推荐,可读性差):

SELECT name 姓名, age 年龄 FROM students;

4.5 去重:DISTINCT

若多行在“选中列”上完全相同,只保留一行,用 DISTINCT

SELECT DISTINCT class_name FROM students;

结果里每个班级只出现一次。

4.6 带条件查询:WHERE(重要)

WHERE 用来筛选行,只返回满足条件的记录。

示例:查高一1班的学生

SELECT * FROM students WHERE class_name = '高一1班';

示例:查年龄大于等于 18 的

SELECT * FROM students WHERE age >= 18;

示例:查年龄 18 且在高一1班

SELECT * FROM students WHERE age = 18 AND class_name = '高一1班';

示例:查姓名为张三或李四

SELECT * FROM students WHERE name = '张三' OR name = '李四';

示例:查年龄在 17 到 18 之间(含 17 和 18)

SELECT * FROM students WHERE age BETWEEN 17 AND 18;

示例:查学号在 1、2、3 里的

SELECT * FROM students WHERE id IN (1, 2, 3);

示例:查姓名包含“三”的(模糊匹配)

SELECT * FROM students WHERE name LIKE '%三%';
  • % 表示任意多个字符;_ 表示一个字符。
  • '%三%':中间有“三”即可;'张%':以“张”开头。

示例:查年龄为 NULL 的(空值判断)

SELECT * FROM students WHERE age IS NULL;

注意:不能用 age = NULL,必须用 IS NULLIS NOT NULL

4.7 排序:ORDER BY

ORDER BY 指定按哪一列(或几列)排序,ASC 升序,DESC 降序,不写默认 ASC。

示例:按年龄升序

SELECT * FROM students ORDER BY age ASC;

示例:按年龄降序,年龄相同按 id 升序

SELECT * FROM students ORDER BY age DESC, id ASC;

4.8 限制条数:LIMIT

只取前几条,用 LIMIT

SELECT * FROM students ORDER BY id LIMIT 3;

分页常用:跳过前 N 条,再取 M 条,用 LIMIT N, M(注意:第一个数是“跳过”,第二个是“取几条”):

-- 跳过前 2 条,取接下来 3 条(即第 3、4、5 条)
SELECT * FROM students ORDER BY id LIMIT 2, 3;

4.9 查(SELECT)小结

  • 查所有列:*SELECT FROM 表名;查指定列:SELECT 列1, 列2 FROM 表名**。
  • 别名:SELECT 列 AS 别名
  • 去重:SELECT DISTINCT 列 FROM 表名
  • 条件:WHERE 条件;排序:ORDER BY 列 ASC/DESC;条数:LIMIT nLIMIT 跳过, 条数

5. 改(Update)——UPDATE

UPDATE 用来修改表里已有行的列值。

5.1 基本语法

UPDATE 表名 SET 列1=新值1, 列2=新值2, ... [WHERE 条件];
  • SET:要改的列和对应的新值,多列用逗号隔开。
  • WHERE:只对满足条件的行更新;不写 WHERE 会更新整张表,非常危险!

5.2 修改某一行的某一列

示例:把 id 为 1 的学生的年龄改成 19

UPDATE students SET age = 19 WHERE id = 1;

示例:把姓名为“李四”的学生的班级改成“高一1班”

UPDATE students SET class_name = '高一1班' WHERE name = '李四';

5.3 修改多列

示例:把 id 为 2 的学生的年龄改为 18,班级改为“高一1班”

UPDATE students SET age = 18, class_name = '高一1班' WHERE id = 2;

5.4 按条件修改多行

示例:把所有“高一2班”的学生的年龄都改成 17

UPDATE students SET age = 17 WHERE class_name = '高一2班';

示例:把所有年龄为 NULL 的填成 18

UPDATE students SET age = 18 WHERE age IS NULL;

5.5 用表达式更新(了解)

SET 右边可以是表达式,例如“年龄加 1”:

UPDATE students SET age = age + 1 WHERE id = 1;

5.6 危险写法:不加 WHERE(务必避免)

UPDATE students SET age = 18;

这会把表中所有行age 都改成 18!
改(UPDATE)前一定要确认 WHERE 条件是否正确,最好先 SELECT 查一遍再 UPDATE。

5.7 改(UPDATE)小结

  • 语法:UPDATE 表名 SET 列=值 [, 列2=值2 …] WHERE 条件
  • 必须养成习惯:先想清楚要改哪几行,写上 WHERE,必要时先用 SELECT 验证。

6. 删(Delete)——DELETE

DELETE 用来删除表里的行(记录),不删表结构。

6.1 基本语法

DELETE FROM 表名 [WHERE 条件];
  • WHERE:只删除满足条件的行;不写 WHERE 会删除表中所有数据,极其危险!

6.2 删除指定的一行

示例:删除 id 为 5 的学生

DELETE FROM students WHERE id = 5;

6.3 按条件删除多行

示例:删除所有高一2班的学生

DELETE FROM students WHERE class_name = '高一2班';

示例:删除年龄小于 18 的

DELETE FROM students WHERE age < 18;

6.4 危险写法:不加 WHERE(务必避免)

DELETE FROM students;

会删除 students 表里的所有行,表还在,但数据全没了,且无法恢复
删(DELETE)前必须确认 WHERE,建议先用 SELECT … WHERE 同一条件看一遍再删。

6.5 清空整张表:TRUNCATE(了解)

若确定要清空整张表,可以用 TRUNCATE

TRUNCATE TABLE students;
  • 效果:表里数据全部清空,自增 id 会从 1 重新开始。
  • DELETE FROM students; 的区别:TRUNCATE 不能加 WHERE,且通常更快;DELETE 可以带 WHERE 只删部分行。
  • 新手阶段用 DELETE + WHERE 即可,清空全表时再考虑 TRUNCATE。

6.6 删(DELETE)小结

  • 语法:DELETE FROM 表名 WHERE 条件
  • 绝不建议在没写 WHERE 的情况下执行 DELETE。

7. 增删改查综合示例

下面用同一张表,按顺序做一遍增、查、改、删,方便你整段练习。

USE school;

-- 确保表存在
CREATE TABLE IF NOT EXISTS students (
    id          INT PRIMARY KEY AUTO_INCREMENT,
    name        VARCHAR(50) NOT NULL,
    gender      CHAR(1) DEFAULT '男',
    age         INT,
    class_name  VARCHAR(20),
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- ========== 增 ==========
INSERT INTO students (name, gender, age, class_name) VALUES
('张三', '男', 18, '高一1班'),
('李四', '女', 17, '高一2班'),
('王五', '男', 18, '高一1班');

-- ========== 查 ==========
SELECT * FROM students;
SELECT name, age FROM students WHERE class_name = '高一1班';
SELECT * FROM students ORDER BY age DESC LIMIT 2;

-- ========== 改 ==========
UPDATE students SET age = 19 WHERE name = '张三';
SELECT * FROM students WHERE name = '张三';   -- 确认改对了

UPDATE students SET class_name = '高一1班' WHERE name = '李四';

-- ========== 删 ==========
-- 先查再删,避免删错
SELECT * FROM students WHERE name = '王五';
DELETE FROM students WHERE name = '王五';
SELECT * FROM students;

8. 必须牢记的注意点

8.1 UPDATE 和 DELETE 一定要带 WHERE

  • UPDATE 表 SET … 不加 WHERE → 更新全表。
  • DELETE FROM 表 不加 WHERE → 删除全表数据。
  • 习惯:先 SELECT … WHERE 条件 看会影响哪些行,再写 UPDATE/DELETE … WHERE 同一条件

8.2 字符串和日期用单引号

  • 正确:'张三''高一1班''2025-02-26'
  • 错误:张三(会被当成列名等)、数字不需要引号。

8.3 NULL 的判断

  • 判断是否为空:WHERE 列 IS NULLWHERE 列 IS NOT NULL
  • 不能写 列 = NULL(结果永远为假)。

8.4 主键、唯一列插入时不要冲突

  • 主键或唯一列重复插入会报错,可用 INSERT IGNOREON DUPLICATE KEY UPDATE 处理(见前文)。

9. 常见错误与解决

9.1 报错:Column count doesn’t match value count

原因:INSERT 时列的数量和值的数量不一致。
解决:检查 INSERT INTO 表 (列1, 列2, …) VALUES (值1, 值2, …),列和值个数、顺序一致。

9.2 报错:Data too long for column ‘xxx’

原因:插入的字符串超过该列定义的长度(如 VARCHAR(10) 却插了 20 个字符)。
解决:缩短内容,或用 ALTER TABLE 把该列长度改大。

9.3 报错:Incorrect date value

原因:日期格式不对或超出范围。
解决:日期写成 ‘YYYY-MM-DD’,如 '2025-02-26';日期时间写成 ‘YYYY-MM-DD HH:MM:SS’

9.4 把整张表都更新/删除了

原因:UPDATE 或 DELETE 忘了写 WHERE,或 WHERE 条件写错(如永远为真)。
解决:只能从备份恢复;以后务必先 SELECT … WHERE 条件 确认再执行 UPDATE/DELETE。


10. 命令速查表

操作 基本语法
增(单行) INSERT INTO 表 (列1,列2) VALUES (值1,值2);
增(多行) INSERT INTO 表 (列1,列2) VALUES (v1,v2),(v1,v2);
查(全部) SELECT * FROM 表;
查(指定列) SELECT 列1,列2 FROM 表;
查(带条件) SELECT * FROM 表 WHERE 条件;
查(排序) SELECT * FROM 表 ORDER BY 列 ASC/DESC;
查(条数) SELECT * FROM 表 LIMIT n;LIMIT 跳过,n
UPDATE 表 SET 列=值 [,列2=值2] WHERE 条件;
DELETE FROM 表 WHERE 条件;

提醒:UPDATE 和 DELETE 务必写对 WHERE,必要时先用 SELECT 验证条件。


按本文把增、查、改、删各练几遍,再结合「条件与排序」文档把 WHERE、ORDER BY、LIMIT 用熟,就能覆盖日常大部分对单表的 CRUD 操作了。建议在本地建好 students 表,把第 7 节整段跑一遍,再自己设计几条 INSERT/SELECT/UPDATE/DELETE 练手。

发表评论