news 2026/6/16 10:19:02

MySQL 系列:第4篇 增删改有章法(DML)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL 系列:第4篇 增删改有章法(DML)

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


前面的文章我们学会了建库、建表、选类型,相当于盖好了房子、规划了房间。今天终于要往里面“放家具”和“挪家具”了——这就是 DML(Data Manipulation Language),包含INSERTUPDATEDELETE三大操作。别小看这三板斧,用不好轻则数据错乱,重则误删全表。我们将用 Python 逐一拆解,并给出生产环境下的安全准则与性能优化技巧。

1. INSERT:把数据塞进去

1.1 单行插入,最基础的姿势

importmysql.connector conn=mysql.connector.connect(host="127.0.0.1",port=3306,user="root",password="MyNewPass123!",database="shop")cursor=conn.cursor()# 先准备好一张产品表(复用第3篇的结构)cursor.execute(""" CREATE TABLE IF NOT EXISTS products(idINT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200)NOT NULL UNIQUE, price DECIMAL(10,2)NOT NULL, stock INT DEFAULT0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)ENGINE=InnoDB""")# 单行插入sql="INSERT INTO products (title, price, stock) VALUES (%s, %s, %s)"cursor.execute(sql,("Python 入门书",59.90,100))conn.commit()print(f"✅ 插入成功,新 ID = {cursor.lastrowid}")

预期输出

要点:

  • 参数化查询%s是占位符,不要用字符串拼接,防止 SQL 注入。

  • 必须 commitmysql-connector-python默认自动提交关闭,忘记 commit 会导致数据丢失。

1.2 批量插入:效率提升百倍

如果要插入 1000 条数据,单条循环插入会产生 1000 次网络往返。用executemany一次性提交:

books=[("Python 高级编程",79.00,50),("MySQL 实战",69.00,80),("Redis 深度历险",49.00,120),("Linux 私房菜",89.00,30),]sql="INSERT INTO products (title, price, stock) VALUES (%s, %s, %s)"cursor.executemany(sql, books)conn.commit()print(f"✅ 批量插入 {cursor.rowcount} 条记录")

预期输出

性能对比实验(不妨动手试试):

time模块计时,插入 10000 条数据,单条循环 vsexecutemany的耗时可能相差几十倍。这就是批量操作的威力。

1.3 存在即更新:ON DUPLICATE KEY UPDATE

当唯一键冲突时,我们不想报错,而是希望更新某些字段。例如同一本书再次入库时,累加库存:

sql=""" INSERT INTO products(title, price, stock)VALUES(%s, %s, %s)ON DUPLICATE KEY UPDATE stock=stock + VALUES(stock)""" cursor.execute(sql,("Python 入门书",59.90,50))conn.commit()print(f"✅ 库存已累加,受影响行数: {cursor.rowcount}")

预期输出

注意:如果冲突发生且执行了更新,rowcount返回 2;如果是全新插入返回 1。可据此判断操作类型。

1.4 INSERT IGNORE:冲突时静默跳过

INSERT IGNORE INTO ...遇到主键或唯一键冲突时直接忽略,不报错也不更新。

cursor.execute("INSERT IGNORE INTO products (title, price, stock) VALUES (%s, %s, %s)",("Python 入门书",59.90,10))conn.commit()print(f"受影响行数: {cursor.rowcount}")# 0,因为已存在

2. UPDATE:修改已有数据

2.1 基础语法与 Python 示例

UPDATE 表名 SET 列1=值1, 列2=值2 WHERE 条件;

无 WHERE 的 UPDATE 会修改全表!这是生产事故的高发区。来看一个安全示例:

# 将 id=1 的商品价格上调 10%cursor.execute("UPDATE products SET price = price * 1.1 WHERE id = %s",(1,))conn.commit()print(f"✅ 更新了 {cursor.rowcount} 行")

2.2 安全准则:先查后改

在大批量更新前,最好先用相同 WHERE 条件执行 SELECT,确认受影响的行数:

# 安全三步走:查看 → 确认 → 更新cursor.execute("SELECT COUNT(*) FROM products WHERE stock < 10")count=cursor.fetchone()[0]print(f"⚠️ 即将清空 {count} 件低库存商品的库存,是否继续?")# 实际生产中这里应该有确认逻辑ifcount<100: cursor.execute("UPDATE products SET stock = 0 WHERE stock < 10")conn.commit()print(f"✅ 已将 {cursor.rowcount} 件商品库存置 0")

2.3 利用 LIMIT 防止误更新大量数据

UPDATE products SET stock=0WHERE stock<10LIMIT10;

分批更新,每次只影响少量行,降低事故爆炸半径。

3. DELETE:删数据是件严肃的事

3.1 DELETE 基础

同样,无 WHERE 会清空整个表。建议开启 MySQL 的--safe-updates模式(或设置sql_safe_updates=1),在没带 WHERE 或 LIMIT 时拒绝执行。

# 删除 id=5 的记录cursor.execute("DELETE FROM products WHERE id = %s",(5,))conn.commit()print(f"✅ 删除了 {cursor.rowcount} 行")

3.2 软删除 vs 硬删除

生产环境很少物理删除数据,通常采用软删除:增加is_deleted字段,标记为 1。

ALTER TABLE products ADD COLUMN is_deleted TINYINT DEFAULT0;

删除操作变为:

cursor.execute("UPDATE products SET is_deleted = 1 WHERE id = %s",(3,))conn.commit()

所有查询后面追加WHERE is_deleted = 0,数据可恢复,符合审计要求。

3.3 TRUNCATE:快速清空表

TRUNCATE TABLE products相当于DROP + CREATE,速度极快,不记日志(因此无法回滚),且重置自增 ID。适合清空测试数据,生产慎用。

4. 批量数据导入导出思路

实际工作中经常需要将 CSV 或外部数据导入 MySQL,或者导出备份。这里给出 Python 实现方案。

4.1 从 CSV 文件导入

假设有products.csv文件:

title,price,stock 机器学习,79.00,40 深度学习,89.00,30
importcsv with open("products.csv","r",encoding="utf-8")as f: reader=csv.DictReader(f)data=[(row['title'], row['price'], row['stock'])forrowinreader]sql="INSERT INTO products (title, price, stock) VALUES (%s, %s, %s)"cursor.executemany(sql, data)conn.commit()print(f"✅ 从 CSV 导入了 {cursor.rowcount} 行")

4.2 导出到 CSV

cursor.execute("SELECT title, price, stock FROM products WHERE is_deleted = 0")rows=cursor.fetchall()with open("export_products.csv","w",newline='',encoding="utf-8")as f: writer=csv.writer(f)writer.writerow(["title","price","stock"])writer.writerows(rows)print("✅ 导出完成")

更高效的方式是使用 MySQL 自带的SELECT INTO OUTFILE,但需服务器文件权限。Python 方案更灵活。

5. 事务在 DML 中的角色

DML 操作通常在事务中执行,保证原子性:要么全成功,要么全回滚。Python 默认需要在 DML 后显式commit(),否则关闭连接时自动回滚。

try: cursor.execute("UPDATE products SET stock = stock - 10 WHERE id = 1")cursor.execute("UPDATE products SET stock = stock + 10 WHERE id = 2")conn.commit()except Exception as e: conn.rollback()print(f"❌ 事务回滚: {e}")

这是实现转账、库存扣减等业务的基础。后续文章会深入讲解事务隔离级别与锁。

6. 动手试试:搭建一个小型进货系统

模拟一个图书进货流程:

  1. 插入新书,如果已存在则累加库存。

  2. 更新库存时,如果更新后库存为负则回滚(使用 Python 检查)。

  3. 将所有价格低于 60 元的书打 9 折。

  4. 导出当前全部库存到 CSV。

你可以基于前面的products表练习,参考代码框架如下:

# 进货book=("Python 入门书",59.90,20)cursor.execute(""" INSERT INTO products(title, price, stock)VALUES(%s,%s,%s)ON DUPLICATE KEY UPDATE stock=stock + VALUES(stock)""", book)# 安全扣减库存cursor.execute("SELECT stock FROM products WHERE id = 1")stock=cursor.fetchone()[0]ifstock>=5: cursor.execute("UPDATE products SET stock = stock - 5 WHERE id = 1")conn.commit()else: print("库存不足")# 打折cursor.execute("UPDATE products SET price = price * 0.9 WHERE price < 60")conn.commit()# 导出(代码见前)

7. 总结

DML 看似简单,却是日常工作中最容易出事故的地方。记住三条铁律:

  • :使用参数化,批量用executemany,冲突用ON DUPLICATE KEY

  • :永远先 SELECT 确认范围,大量更新加 LIMIT 分批。

  • :优先软删除,硬删除前务必三思,开启safe-updates保平安。

下一篇我们将进入SELECT 查询的艺术,学习如何从海量数据中精准、高效地取出想要的内容。下次见!

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/16 10:19:00

MYD1小鼠模型在免疫与肿瘤研究中的应用进展

MYD1基因修饰小鼠模型的构建策略MYD1基因修饰小鼠模型的建立主要采用三种分子遗传学技术&#xff1a;传统基因敲除&#xff08;KO&#xff09;、条件性敲除&#xff08;cKO&#xff09;和点突变&#xff08;KI&#xff09;模型。全基因敲除模型通过同源重组替换MYD1基因的第2-4…

作者头像 李华
网站建设 2026/6/16 10:14:56

中国大气二氧化碳月浓度高精度估算(2015-2022)

该数据集采用森林模型估算了2015-2022年中国每月大气二氧化碳浓度&#xff0c;结合了轨道碳观测站2号卫星观测和各种辅助变量&#xff0c;空间分辨率为0.05。 该数据集主要以csv的格式存储&#xff0c;收录了2015-2022年间的中国大气二氧化碳月浓度高精度估算数据&#xff0c;其…

作者头像 李华
网站建设 2026/6/16 10:05:52

桌游卡牌批量生成解决方案:CardEditor开源工具完全指南

桌游卡牌批量生成解决方案&#xff1a;CardEditor开源工具完全指南 【免费下载链接】CardEditor 一款专为桌游设计师开发的批处理数值填入卡牌生成器/A card batch generator specially developed for board game designers 项目地址: https://gitcode.com/gh_mirrors/ca/Car…

作者头像 李华
网站建设 2026/6/16 10:02:45

目录穿越漏洞深度解析:从路径拼接原理到Web安全实战防御

1. 项目概述&#xff1a;从“../”到系统沦陷的隐秘通道在Web安全的世界里&#xff0c;有些漏洞听起来平平无奇&#xff0c;但其破坏力却足以让一个系统从内部被彻底瓦解。目录穿越漏洞&#xff0c;就是这样一个典型。你可能在渗透测试报告里见过它&#xff0c;也可能在开发日志…

作者头像 李华
网站建设 2026/6/16 10:02:43

Mac本地部署Gemma4+Hermes Agent全链路指南

1. 为什么在 Mac 上硬刚 Hermes Agent Gemma4 是个“反直觉但值得”的选择你点开这篇教程&#xff0c;大概率已经经历过至少一次这样的挫败&#xff1a;在 Terminal 里敲下ollama run gemma4:12b&#xff0c;结果卡在pulling manifest十分钟不动&#xff1b;或者好不容易拉下来…

作者头像 李华