【MySQL全面教学】MySQL基础SQL语句Day3(2026年)
欢迎来到MySQL系列教程的第3天!今天我们将学习SQL语句的基础操作,包括DDL(数据定义语言)、DML(数据操作语言)和DQL(数据查询语言)。这些将是日后最常用的SQL命令,务必熟练掌握。
文章目录
- 一、写在前面
- 二、DDL语句:数据库和表的操作
- 2.1 数据库操作
- 2.2 表操作:CREATE TABLE
- 2.3 表操作:ALTER TABLE
- 2.4 删除表
- 三、DML语句:数据的增删改
- 3.1 INSERT语句的多种写法
- 3.2 UPDATE的安全写法
- 3.3 DELETE和TRUNCATE的区别
- 四、DQL基础:SELECT查询
- 4.1 SELECT * 的坑
- 4.2 别名和去重
- 五、实战:创建电商订单系统相关表
- 5.1 完整的电商表结构设计
- 5.2 插入测试数据
- 六、踩坑提醒
- 6.1 UPDATE忘记WHERE的悲剧
- 6.2 DELETE忘记WHERE的悲剧
- 七、面试高频考点
- 考点1:DELETE和TRUNCATE的区别?
- 考点2:DROP和DELETE的区别?
- 考点3:INSERT的几种写法?
- 考点4:如何防止UPDATE/DELETE误操作?
- 八、总结
- 九、下一步预告
- 十、参考资料
- 互动话题
一、写在前面
SQL语句分为以下几类:
| 分类 | 全称 | 主要语句 | 用途 |
|---|---|---|---|
| DDL | Data Definition Language | CREATE, DROP, ALTER | 定义数据库结构 |
| DML | Data Manipulation Language | INSERT, UPDATE, DELETE | 操作数据 |
| DQL | Data Query Language | SELECT | 查询数据 |
| DCL | Data Control Language | GRANT, REVOKE | 权限控制 |
| TCL | Transaction Control Language | COMMIT, ROLLBACK | 事务控制 |
今天我们重点学习DDL、DML和DQL的基础用法。
二、DDL语句:数据库和表的操作
2.1 数据库操作
-- 创建数据库CREATEDATABASEIFNOTEXISTSecommerceDEFAULTCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;-- 使用数据库USEecommerce;-- 查看所有数据库SHOWDATABASES;-- 查看当前数据库SELECTDATABASE();-- 删除数据库(危险操作!)DROPDATABASEIFEXISTSecommerce;-- 修改数据库字符集ALTERDATABASEecommerceCHARACTERSETutf8mb4;经验之谈:创建数据库时务必指定utf8mb4字符集,支持完整的Unicode(包括emoji)。
2.2 表操作:CREATE TABLE
-- 创建用户表CREATETABLEIFNOTEXISTSusers(idINTUNSIGNEDAUTO_INCREMENTPRIMARYKEYCOMMENT'用户ID',usernameVARCHAR(50)NOTNULLUNIQUECOMMENT'用户名',emailVARCHAR(100)NOTNULLUNIQUECOMMENT'邮箱',phoneCHAR(11)COMMENT'手机号',passwordVARCHAR(255)NOTNULLCOMMENT'密码(加密存储)',statusTINYINTUNSIGNEDDEFAULT1COMMENT'状态:0-禁用 1-启用',created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',updated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间',INDEXidx_email(email),INDEXidx_phone(phone))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='用户表';CREATE TABLE要点:
- 每个表建议有
id主键 - 常用查询字段加索引
- 必须设置字符集为utf8mb4
- 添加COMMENT注释,方便维护
2.3 表操作:ALTER TABLE
-- 添加列ALTERTABLEusersADDCOLUMNnicknameVARCHAR(50)COMMENT'昵称'AFTERusername;-- 修改列类型ALTERTABLEusersMODIFYCOLUMNphoneVARCHAR(20)COMMENT'手机号(支持国际号码)';-- 修改列名(MySQL 8.0+)ALTERTABLEusersRENAMECOLUMNnicknameTOdisplay_name;-- 删除列ALTERTABLEusersDROPCOLUMNdisplay_name;-- 添加索引ALTERTABLEusersADDINDEXidx_created_at(created_at);-- 删除索引ALTERTABLEusersDROPINDEXidx_created_at;-- 修改表名ALTERTABLEusersRENAMETOsys_users;RENAMETABLEsys_usersTOusers;2.4 删除表
-- 删除表(会删除数据和结构)DROPTABLEIFEXISTStemp_table;-- 清空表数据(保留结构)TRUNCATETABLEtemp_table;三、DML语句:数据的增删改
3.1 INSERT语句的多种写法
-- 方式1:标准插入(推荐,明确指定列)INSERTINTOusers(username,email,phone,password)VALUES('zhangsan','zhangsan@example.com','13800138000','encrypted_pwd');-- 方式2:插入多行(性能更好)INSERTINTOusers(username,email,password)VALUES('lisi','lisi@example.com','pwd1'),('wangwu','wangwu@example.com','pwd2'),('zhaoliu','zhaoliu@example.com','pwd3');-- 方式3:使用SET语法INSERTINTOusersSETusername='sunqi',email='sunqi@example.com',password='pwd4';-- 方式4:从其他表插入(数据迁移常用)INSERTINTOusers_backup(username,email)SELECTusername,emailFROMusersWHEREstatus=0;-- 方式5:存在则更新,不存在则插入(UPSERT)INSERTINTOusers(id,username,email)VALUES(1,'newname','new@example.com')ONDUPLICATEKEYUPDATEusername=VALUES(username),email=VALUES(email);-- MySQL 8.0.19+ 新语法INSERTINTOusers(id,username,email)VALUES(1,'newname','new@example.com')ASnewONDUPLICATEKEYUPDATEusername=new.username,email=new.email;经验之谈:
- 生产环境务必指定列名,不要依赖列顺序
- 批量插入比单条插入性能高很多
- 使用
INSERT IGNORE忽略重复键错误
3.2 UPDATE的安全写法
-- 危险!忘记WHERE会更新所有行!UPDATEusersSETstatus=0;-- 所有用户都被禁用了!-- 安全的UPDATE写法(先查询确认)-- 步骤1:先SELECT确认要更新的数据SELECT*FROMusersWHEREid=1;-- 步骤2:执行UPDATE(必须带WHERE)UPDATEusersSETstatus=0,updated_at=NOW()WHEREid=1;-- 使用LIMIT限制更新数量(保险措施)UPDATEusersSETstatus=0WHEREstatus=1LIMIT10;-- 多表UPDATEUPDATEusers uJOINorders oONu.id=o.user_idSETu.order_count=u.order_count+1WHEREo.status='completed';3.3 DELETE和TRUNCATE的区别
-- DELETE:删除指定行,可以回滚,记录日志DELETEFROMusersWHEREid=1;-- DELETE忘记WHERE的补救:使用LIMITDELETEFROMusersLIMIT1;-- 只删1条-- TRUNCATE:清空整个表,速度快,不可回滚TRUNCATETABLEtemp_logs;| 特性 | DELETE | TRUNCATE |
|---|---|---|
| 删除范围 | 可指定条件 | 全部数据 |
| 执行速度 | 较慢(逐行删除) | 很快(删除表重建) |
| 事务回滚 | 支持 | 不支持 |
| 触发器 | 会触发 | 不会触发 |
| 自增计数 | 保留 | 重置 |
| 日志记录 | 记录每行 | 最小日志 |
四、DQL基础:SELECT查询
4.1 SELECT * 的坑
-- 不推荐:SELECT * 会返回所有列SELECT*FROMusers;-- 推荐:明确指定需要的列SELECTid,username,email,created_atFROMusers;-- 原因:-- 1. 网络传输更多数据-- 2. 可能包含敏感字段(password)-- 3. 表结构变化会影响应用程序-- 4. 无法利用覆盖索引优化4.2 别名和去重
-- 列别名(AS可省略)SELECTidASuser_id,usernameASname,created_atASregister_timeFROMusers;-- 表别名(多表查询常用)SELECTu.id,u.usernameFROMusers u;-- 去重DISTINCTSELECTDISTINCTstatusFROMusers;-- 查看有哪些状态值-- 多列去重(组合唯一)SELECTDISTINCTstatus,genderFROMusers;五、实战:创建电商订单系统相关表
5.1 完整的电商表结构设计
-- 用户表CREATETABLEusers(idINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,usernameVARCHAR(50)NOTNULLUNIQUE,emailVARCHAR(100)NOTNULLUNIQUE,phoneCHAR(11),passwordVARCHAR(255)NOTNULL,statusTINYINTUNSIGNEDDEFAULT1,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,INDEXidx_phone(phone))ENGINE=InnoDBCOMMENT='用户表';-- 商品表CREATETABLEproducts(idINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(200)NOTNULLCOMMENT'商品名称',descriptionTEXTCOMMENT'商品描述',priceDECIMAL(10,2)NOTNULLCOMMENT'售价',stockINTUNSIGNEDDEFAULT0COMMENT'库存',statusTINYINTUNSIGNEDDEFAULT1COMMENT'0-下架 1-上架',created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,INDEXidx_status_price(status,price))ENGINE=InnoDBCOMMENT='商品表';-- 订单表CREATETABLEorders(idINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,order_noVARCHAR(32)NOTNULLUNIQUECOMMENT'订单编号',user_idINTUNSIGNEDNOTNULLCOMMENT'用户ID',total_amountDECIMAL(10,2)NOTNULLCOMMENT'订单总金额',statusTINYINTUNSIGNEDDEFAULT0COMMENT'0-待支付 1-已支付 2-已发货 3-已完成 4-已取消',created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,INDEXidx_user_id(user_id),INDEXidx_order_no(order_no),INDEXidx_created_at(created_at),FOREIGNKEY(user_id)REFERENCESusers(id))ENGINE=InnoDBCOMMENT='订单表';-- 订单商品表(订单明细)CREATETABLEorder_items(idINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,order_idINTUNSIGNEDNOTNULLCOMMENT'订单ID',product_idINTUNSIGNEDNOTNULLCOMMENT'商品ID',product_nameVARCHAR(200)NOTNULLCOMMENT'商品名称(快照)',priceDECIMAL(10,2)NOTNULLCOMMENT'下单时价格',quantityINTUNSIGNEDNOTNULLCOMMENT'数量',subtotalDECIMAL(10,2)NOTNULLCOMMENT'小计金额',INDEXidx_order_id(order_id),FOREIGNKEY(order_id)REFERENCESorders(id),FOREIGNKEY(product_id)REFERENCESproducts(id))ENGINE=InnoDBCOMMENT='订单商品表';5.2 插入测试数据
-- 插入用户INSERTINTOusers(username,email,phone,password)VALUES('user001','user001@test.com','13800138001','pwd001'),('user002','user002@test.com','13800138002','pwd002'),('user003','user003@test.com','13800138003','pwd003');-- 插入商品INSERTINTOproducts(name,description,price,stock)VALUES('iPhone 15','苹果最新手机',5999.00,100),('MacBook Pro','苹果笔记本电脑',14999.00,50),('AirPods Pro','无线耳机',1999.00,200);-- 插入订单INSERTINTOorders(order_no,user_id,total_amount,status)VALUES('ORDER202401010001',1,5999.00,1),('ORDER202401010002',1,1999.00,0),('ORDER202401010003',2,14999.00,2);-- 插入订单明细INSERTINTOorder_items(order_id,product_id,product_name,price,quantity,subtotal)VALUES(1,1,'iPhone 15',5999.00,1,5999.00),(2,3,'AirPods Pro',1999.00,1,1999.00),(3,2,'MacBook Pro',14999.00,1,14999.00);六、踩坑提醒
6.1 UPDATE忘记WHERE的悲剧
真实案例:某运营人员执行了以下SQL:
-- 本意:只禁用某个违规用户UPDATEusersSETstatus=0;-- 结果:所有用户都被禁用了!网站瘫痪!防范措施:
- 执行UPDATE前先用SELECT确认
- 使用
SET sql_safe_updates = 1;开启安全模式 - UPDATE必须带WHERE条件
-- 开启安全更新模式SETsql_safe_updates=1;-- 此时执行无WHERE的UPDATE会报错UPDATEusersSETstatus=0;-- ERROR 1175 (HY000): You are using safe update mode...6.2 DELETE忘记WHERE的悲剧
-- 本意:删除测试数据DELETEFROMorders;-- 结果:所有订单都没了!防范措施:
- 先用SELECT确认要删除的数据
- 使用事务,删除前可以回滚
- 重要数据先备份
-- 安全的删除流程STARTTRANSACTION;SELECT*FROMordersWHEREstatus=4;-- 确认要删除的已取消订单DELETEFROMordersWHEREstatus=4;-- 确认无误后提交COMMIT;-- 如果有问题回滚-- ROLLBACK;七、面试高频考点
考点1:DELETE和TRUNCATE的区别?
答案:
- DELETE是DML语句,TRUNCATE是DDL语句
- DELETE可以带WHERE条件删除部分数据,TRUNCATE只能清空全部
- DELETE逐行删除,记录日志,可以回滚;TRUNCATE直接删除表重建,速度快,不可回滚
- DELETE会触发表上的触发器,TRUNCATE不会
- DELETE保留自增计数,TRUNCATE重置自增计数
考点2:DROP和DELETE的区别?
答案:
- DROP是DDL语句,删除整个表(结构和数据)
- DELETE是DML语句,只删除数据,保留表结构
- DROP不可回滚,DELETE在事务中可以回滚
考点3:INSERT的几种写法?
答案:
INSERT INTO table (cols) VALUES (...)- 标准插入INSERT INTO table VALUES (...)- 省略列名(不推荐)INSERT INTO table SET col1=val1, col2=val2- SET语法INSERT INTO table SELECT ...- 从其他表插入INSERT ... ON DUPLICATE KEY UPDATE- 存在更新,不存在插入
考点4:如何防止UPDATE/DELETE误操作?
答案:
- 开启sql_safe_updates安全模式
- 执行前先SELECT确认
- 使用事务,先执行后确认再提交
- 重要操作先在测试环境验证
- 定期备份数据
八、总结
今天我们学习了:
- DDL语句:CREATE/DROP/ALTER操作数据库和表结构
- DML语句:INSERT/UPDATE/DELETE操作数据
- DQL语句:SELECT基础查询
- 实战:创建了电商系统的核心表
核心要点:
- 创建表要设置utf8mb4字符集
- UPDATE/DELETE必须带WHERE条件
- SELECT不要直接用*,指定需要的列
- 重要操作前先备份,使用事务保护
九、下一步预告
Day4:MySQL条件查询与排序
我们将学习:
- WHERE子句的各种条件写法
- NULL值的处理
- ORDER BY排序技巧
- LIMIT分页实现
- 电商系统的各种查询场景
十、参考资料
- MySQL 8.0官方文档 - SQL语句
- SQL必知必会(第5版)
- MySQL是怎样运行的:从根儿上理解MySQL
互动话题
- 你在工作中有没有遇到过UPDATE/DELETE忘记WHERE的惊险时刻?后来怎么解决的?
- 你们公司的数据库表设计规范有哪些?欢迎在评论区分享!
- 对于电商系统的表设计,你有什么优化建议?
如果觉得有帮助,请点赞+收藏+关注!我们Day4见!
