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

CRUD 入门:数据的增、查、改、删

在前一篇中,我们成功创建了数据库和表,并初步了解了数据类型。接下来,我们将进入数据库操作中最核心、最常用的部分——CRUD。CRUD 是四个基本操作的缩写:Create(增加)、Read(查询)、Update(更新)、Delete(删除)。这四项操作几乎是所有数据库应用的基础,熟练掌握它们,就掌握了与数据库交互的“对话能力”。

本文将以之前创建的users表为载体,带你系统学习:

  • 使用INSERT插入单行、多行数据
  • 使用SELECT查询数据(全列、指定列、表达式、别名、去重)
  • 使用UPDATE修改数据
  • 使用DELETE删除数据
  • 实战:完成用户表的增删改查

1. 插入数据:INSERT INTO

1.1 基本语法

INSERTINTO表名[(1,2,...)]VALUES(1,2,...),(3,4,...),...;
  • 列名列表是可选的,如果省略,则需要按表定义顺序为所有列提供值(自动增长的列可以指定NULLDEFAULT)。
  • 可以一次性插入多行数据,以提高效率。

1.2 插入单行

我们以上一篇创建的users表为例,插入一条完整的记录:

INSERTINTOusers(username,email,password,birthdate,status)VALUES('alice','alice@example.com','hashed_pw_alice','1995-06-15',1);

因为id列是AUTO_INCREMENT,我们无需手动指定,MySQL 会自动生成。mobileavatar_urlsignaturelast_login_at等列有默认值或允许 NULL,未指定则会自动使用默认值(NULL 或指定默认值)。

验证插入结果:

SELECT*FROMusers;

1.3 插入多行

可以一次性插入多条记录,用逗号分隔:

INSERTINTOusers(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(取决于定义)。例如,只插入必填字段:

INSERTINTOusers(username,email,password)VALUES('eve','eve@example.com','hashed_pw_eve');

此时,birthdate会为 NULL,status会使用默认值 1。


2. 查询数据:SELECT

SELECT是 SQL 中使用最频繁的语句,用于从表中检索数据。

2.1 基本查询

查询所有列

SELECT*FROMusers;

使用*很方便,但在生产环境中通常不推荐,因为它可能带来不必要的 I/O 开销,且无法利用覆盖索引优化。明确列出所需列是更好的习惯。

查询指定列

SELECTusername,emailFROMusers;

2.2 表达式与别名

你可以在 SELECT 列表中使用表达式。例如,如果我们想展示一个由usernameemail组合而成的“显示名”:

SELECTusername,CONCAT(username,' <',email,'>')ASdisplay_nameFROMusers;
  • AS用于给列或表达式取别名,方便阅读。别名也可以用在后续的ORDER BYGROUP BY中(但需注意标准 SQL 的执行顺序)。
  • 如果别名包含空格或特殊字符,需要用反引号或双引号包裹,如AS 'display name'

算术运算示例:假设有一张商品表,可以使用price * quantity计算总价。

2.3 去重:DISTINCT

如果想查看用户表中有哪些不同的出生年份(假设我们存储的是 DATE 类型),可以使用DISTINCT

SELECTDISTINCTYEAR(birthdate)ASbirth_yearFROMusersWHEREbirthdateISNOTNULL;

DISTINCT作用在整个选择列表上,即去掉所有选择列都相同的行。

2.4 查询常量与函数

SELECT 也可以查询不来自表的数据,如系统信息:

SELECTVERSION(),NOW(),'Hello'ASgreeting;

这在调试或写存储过程时很有用。


3. 修改数据:UPDATE

UPDATE语句用于修改表中已存在的行。

3.1 基本语法

UPDATE表名SET1=新值1,2=新值2,...[WHERE条件];

⚠️ 强烈建议先写 WHERE 条件再执行,避免误更新整个表!

3.2 示例:更新用户状态和签名

将用户alice的状态改为“冻结”(0),并添加个性签名:

UPDATEusersSETstatus=0,signature='暂时离开,勿念'WHEREusername='alice';

验证更新:

SELECTusername,status,signatureFROMusersWHEREusername='alice';

如果忘记添加 WHERE 条件,所有行的status都会被更新,后果将非常严重。

3.3 使用表达式更新

可以在 SET 中使用当前列的值。比如把所有用户的激活状态反转(0 变 1,1 变 0)—— 虽然这不是常规操作,但演示一下:

UPDATEusersSETstatus=1-status;

这会把status = 0的变为 1,status = 1的变为 0。执行前务必确认 WHERE 条件是否必要。


4. 删除数据:DELETE

4.1 基本语法

DELETEFROM表名[WHERE条件];

同样需要万分小心,没有 WHERE 条件的 DELETE 会清空整个表!如果只是想要清空表,更高效的方式是使用TRUNCATE TABLE 表名,它会重置自增计数器且不记录逐行删除日志。

4.2 删除指定行

删除用户bob

DELETEFROMusersWHEREusername='bob';

如果存在多条username = 'bob',则会全部删除。建议 DELETE 时使用唯一键(如主键)来精确定位。

4.3 删除所有行(慎用)

DELETEFROMusers;

DROP TABLE users;不同,DELETE仅删除数据,保留表结构和索引等。如果要清空表且希望重置自增值,可以使用:

TRUNCATETABLEusers;

TRUNCATE是一个 DDL 操作,无法回滚,速度极快。


5. 实战:完成用户表的增删改查

让我们把前面的知识串起来,模拟一个简单的用户管理场景。假设我们有一个初始为空的users表(可重新创建或清空数据后操作)。

5.1 插入用户

INSERTINTOusers(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 查询所有已激活用户

SELECTid,username,email,birthdateFROMusersWHEREstatus=1;

5.3 更新用户邮箱

lisi更换了邮箱:

UPDATEusersSETemail='lisi_new@example.com'WHEREusername='lisi';

5.4 删除某个用户

zhaoliu注销账号:

DELETEFROMusersWHEREusername='zhaoliu';

5.5 验证最终结果

SELECT*FROMusers;

你应该能看到zhangsanlisiwangwu三个人,其中lisi的邮箱已更新,zhaoliu已消失。

扩展练习

  1. 尝试批量插入 10 条用户记录,其中有几个用户的状态设为 0。
  2. 编写一个 UPDATE 语句,将所有 2000 年后出生的用户签名统一设置为“千禧一代”。
    (提示:WHERE birthdate > ‘2000-01-01’)
  3. 删除所有状态为 0 的用户(使用 DELETE)。

6. 小结

本文我们学习了 MySQL 中最基础的 CRUD 操作:

  • INSERT插入数据,支持单行、多行及指定列;
  • SELECT查询数据,包括指定列、表达式、别名和DISTINCT
  • UPDATE修改数据,必须谨慎加 WHERE 条件;
  • DELETE删除数据,同样需确认条件,清空表时可考虑 TRUNCATE。

这些操作是后续所有复杂查询和数据处理的基础。下一篇我们将深入 SELECT 的过滤与排序,让数据查询更加精准和高效。

思考题

  1. 如果用INSERT INTO users VALUES (NULL, ...)插入,会发生什么?(提示:自增列可以显式给 NULL 吗?)
  2. DELETETRUNCATE的区别是什么?在事务中使用它们,回滚后效果有何不同?
  3. 假设我们误执行了无 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

http://www.jsqmd.com/news/825897/

相关文章:

  • 湖南防火门技术选型指南:国曼消防工艺解析与新国标验收要点
  • Ai小程序入门06-数据绑定(小白入门:从静态到动态,让页面数据显示得活灵活现)
  • AI教材生成秘籍:利用AI写教材,轻松实现低查重与高质量内容!
  • LeRobot SO-ARM101机械臂教程:三、遥感操作
  • 基于CRICKIT与CircuitPython的蛇形机器人避障项目实践
  • 数据不出本机、全程离线运行,这个AI工具让我告别手动办公
  • AI进阶,韧性必修:从传统灾备到数据韧性“变形记”
  • 15种logo检测数据集9626张VOC+YOLO格式
  • 从图论到解析分子结构的应用:Floyd-Warshall 算法
  • 强化学习如何优化大语言模型:TextRL实战指南
  • OpenCV LineMod算法实战:从模板创建到目标检测的完整调用指南
  • LLM提示词编排引擎:构建可维护AI工作流的工程化实践
  • Mali GPU着色器优化与性能分析实战
  • 抖音直播数据抓取实战:6步构建实时WebSocket采集系统
  • 别再手动改标注了!一个Python脚本搞定Labelme、LabelImg、YOLO格式互转(附完整代码)
  • 1688代运营/一个月询盘暴涨325%!1688代运营是怎么做到的?
  • 构建个人代码库:从零到一打造高效开发工具箱
  • C++学习笔记10:auto关键字
  • 为什么92%的团队GitOps落地失败?DeepSeek内部未公开的4层权限治理模型首次披露
  • AI编程助手规则配置指南:提升Cursor代码生成质量与规范一致性
  • Simics在网络转型与SDN迁移中的核心价值与应用
  • Ghost-Cursor:模拟人类鼠标轨迹,提升Web自动化隐蔽性
  • 自建ChatGPT API代理层:解决密钥管理、限流与成本控制难题
  • Perplexity出版社信息查询全攻略:从API调用到元数据溯源的7步精准定位法
  • Cursor编辑器AI规则配置:提升代码生成质量与团队协作效率
  • ARM CHI接口设计原理与多核系统优化实践
  • 别再只看总mAP了!用pycocotools逐类分析你的目标检测模型(附完整代码)
  • Kubernetes多租户管理策略
  • 2026 年 AI 编程工具终极横评:GitHub Copilot vs Cursor vs Claude Code,万字实测告诉你选哪个
  • 【效率提升】macOS下VirtualBox增强功能深度配置:从丝滑体验到无缝数据共享