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