
文档教程【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址https://gitcode.com/GitHub_Trending/py/Python-100-Days点击查看免费下载本篇文章基于 Python-100-Days 项目Python - 100天从新手到大师中《SQL详解之DML》一课以学校选课系统school数据库为实战载体系统讲解数据操作语言DML中三大核心语句insert插入数据、delete删除数据和update更新数据的完整用法、语法细节与潜在风险。读完本文你将掌握在 MySQL 中安全、高效地执行增删改操作的全部要领并理解为什么带where的delete/update是业务系统的基本素养以及如何通过truncate、批处理插入、low_priority等手段在不同场景下做出正确的取舍。课前准备切换到 school 数据库DML 操作必须建立在已存在的数据库和表结构之上。本课沿用上一课《SQL详解之DDL》Day36-45/37.SQL详解之DDL.md中创建的学校选课系统数据库。该数据库包含五张表学院表tb_college、学生表tb_student、教师表tb_teacher、课程表tb_course和选课记录表tb_record其中tb_record是维持学生与课程多对多关系的中间表。在执行任何 DML 语句之前先通过use命令切换到school数据库上下文USE school;仓库中提供了完整的建库建表与初始化数据脚本 Day36-45/code/SRS_create_and_init.sql可直接执行该脚本完成全部环境准备。这里以学院表为例回顾关键表结构完整建表语句见 Day36-45/37.SQL详解之DDL.mdCREATE TABLE tb_college ( col_id int unsigned AUTO_INCREMENT COMMENT 编号, col_name varchar(50) NOT NULL COMMENT 名称, col_intro varchar(500) NOT NULL DEFAULT COMMENT 介绍, PRIMARY KEY (col_id) );可以看到col_id是自增主键AUTO_INCREMENTcol_intro设置了默认值约束这两点直接影响下面insert语句的写法。insert 操作向二维表插入数据insert用于向二维表中插入行按插入方式可以划分为四种典型场景插入完整的行、插入行的一部分、插入多行批处理、插入查询的结果。插入完整的行直接为目标表提供所有列的完整取值不需要列出列名。由于学院表的主键col_id是自增字段该列可以交给数据库自动生成此时使用关键字default表示采用该列的默认值自增序列的下一个值INSERT INTO tb_college VALUES (DEFAULT, 计算机学院, 学习计算机科学与技术的地方);插入行的一部分指定列赋值同样的效果也可以明确写出要赋值的列名让自增主键隐式生成INSERT INTO tb_college (col_name, col_intro) VALUES (计算机学院, 学习计算机科学与技术的地方);推荐使用这种指定列赋值的写法原因有二可以不按照建表时设定的字段顺序赋值而按照values前面元组中给定的字段顺序为字段赋值代码可读性更好表结构演进如新增列时显式列名的写法受影响的概率更小。注意使用这种写法时除了允许为null和有默认值的字段外其他字段都必须一一列出并在values后面的元组中为其赋值。例如tb_college的col_name是非空字段必须给出取值而col_intro有默认值可以省略。如果省略了既不允许为空、又没有默认值的列insert操作将产生错误。批量插入多行如果希望一次性插入多条记录可以在values后面跟上多个元组来实现批量插入。MySQL 会在一条 SQL 中完成多行数据的写入相比逐条insert效率更高INSERT INTO tb_college (col_name, col_intro) VALUES (外国语学院, 学习歪果仁的语言的学院), (经济管理学院, 经世济民治理国家管理科学兴国之道), (体育学院, 发展体育运动增强人民体质);提示本课末尾完整的数据一节中的插入脚本正是采用了这种批处理方式来插入五张表的所有数据其注释也明确提醒——批处理方式插入数据的效率比较高。插入查询的结果如果已经有一张表例如含a、b两列的tb_temp表保存了学院名称和学院介绍也可以通过查询获得数据并直接插入学院表。这里的select属于 DQL数据查询语言会在下一课《SQL详解之DQL》Day36-45/39.SQL详解之DQL.md中详细讲解INSERT INTO tb_college (col_name, col_intro) SELECT a, b FROM tb_temp;这种insert ... select写法常用于数据迁移、表之间数据复制、报表数据预聚合等场景。插入数据的两个关键风险点主键唯一性主键是不能重复的如果插入的数据与表中已有记录的主键相同insert操作将产生 Duplicated Entry 的报错信息。例如在tb_college中插入两条col_id1的记录就会触发该错误。省略列的限制如果insert操作省略了某些列那么这些列要么有默认值要么允许为null否则也将产生错误。降低 insert 的优先级low_priority在业务系统中为了让insert操作不影响其他操作主要是后面要讲的select查询操作的性能可以在insert和into之间加一个low_priority关键字降低该写入操作的优先级INSERT LOW_PRIORITY INTO tb_college (col_name, col_intro) VALUES (体育学院, 发展体育运动增强人民体质);同样的做法也适用于下面要讲的delete和update操作。该机制让写入操作在资源紧张时让位于查询操作适合高并发读写场景下的负载调节。delete 操作从表中删除数据如果需要从表中删除数据可以使用delete操作它可以删除指定行也可以删除所有行。删除指定的行删除编号为1的学院DELETE FROM tb_college WHERE col_id1;这里的where子句用来指定删除条件只有满足条件的行会被删除。where是delete语句的保护伞实际业务中几乎总是需要它。删除所有行危险操作如果遗漏了where子句下面的 SQL 将删除学院表中的所有记录这是相当危险的在实际工作中通常也不会这么做DELETE FROM tb_college;delete 与 truncate 的本质区别需要特别说明的是即便删除了所有的数据delete操作不会删除表本身也不会让 AUTO_INCREMENT 字段的值回到初始值如果需要删除所有的数据而且让 AUTO_INCREMENT 字段回到初始值可以使用truncate table执行截断表操作TRUNCATE TABLE tb_college;truncate的本质是删除原来的表并重新创建一个表因此它的速度其实更快——不需要逐行删除数据。但请务必记住用truncate table删除数据是非常危险的它会删除所有的数据而且由于原来的表已经被删除了要想恢复误删除的数据会变得极为困难。因此生产环境中对truncate的使用要慎之又慎通常需要配合备份、权限控制等手段。update 操作修改表中的数据如果要修改表中的数据可以使用update操作它可以更新指定的行配合where也可以更新所有的行不加where实际工作中几乎不会用到。更新指定行例如将学生表中杨过的姓名修改为杨逍这里假设杨过的学号为1001UPDATE tb_student SET stu_name杨逍 WHERE stu_id1001;为什么使用学号stu_id而不是姓名stu_name作为筛选条件因为学生表中可能存在多个名为杨过的学生如果使用stu_name作为筛选条件update操作有可能一次更新多条数据这显然不是我们想要看到的。以唯一标识主键作为筛选条件才能精确锁定目标记录。另一个容易踩坑的地方是set关键字SQL 中的并不表示赋值而是判断相等的运算符只有出现在set关键字后面的才具备赋值的能力。例如WHERE stu_id1001中的是等值判断而SET stu_name杨逍中的才是赋值。同时更新多列如果要同时修改学生的姓名和生日可以在set关键字后使用逗号分隔多个赋值表达式UPDATE tb_student SET stu_name杨逍 , stu_birth1975-12-29 WHERE stu_id1001;使用查询结果更新数据update语句中也可以使用查询的方式获得数据并以此来更新指定的表数据如UPDATE ... SET col(SELECT ...)或 MySQL 的UPDATE ... JOIN语法有兴趣的读者可以自行研究。书写 update 的黄金法则书写update语句时通常都会有where子句因为实际工作中几乎不太会用到更新全表的操作这一点一定要时刻注意。一条缺少where的update会静默地修改整张表的数据且难以回退是生产事故的高发源头。完整的数据school 数据库五张表初始化脚本下面给出完整的向school数据库五张表插入数据的 SQL可整体复制到 MySQL 命令行或客户端中执行验证前面所学的全部知识点USE school; -- 插入学院数据 INSERT INTO tb_college (col_name, col_intro) VALUES (计算机学院, 计算机学院1958年设立计算机专业1981年建立计算机科学系1998年设立计算机学院2005年5月为了进一步整合教学和科研资源学校决定计算机学院和软件学院行政班子合并统一运作、实行教学和学生管理独立运行的模式。 学院下设三个系计算机科学与技术系、物联网工程系、计算金融系两个研究所图象图形研究所、网络空间安全研究院2015年成立三个教学实验中心计算机基础教学实验中心、IBM技术中心和计算机专业实验中心。), (外国语学院, 外国语学院设有7个教学单位6个文理兼收的本科专业拥有1个一级学科博士授予点3个二级学科博士授予点5个一级学科硕士学位授权点5个二级学科硕士学位授权点5个硕士专业授权领域同时还有2个硕士专业学位MTI专业有教职员工210余人其中教授、副教授80余人教师中获得中国国内外名校博士学位和正在职攻读博士学位的教师比例占专任教师的60%以上。), (经济管理学院, 经济学院前身是创办于1905年的经济科已故经济学家彭迪先、张与九、蒋学模、胡寄窗、陶大镛、胡代光以及当代学者刘诗白等曾先后在此任教或学习。); -- 插入学生数据 INSERT INTO tb_student (stu_id, stu_name, stu_sex, stu_birth, stu_addr, col_id) VALUES (1001, 杨过, 1, 1990-3-4, 湖南长沙, 1), (1002, 任我行, 1, 1992-2-2, 湖南长沙, 1), (1033, 王语嫣, 0, 1989-12-3, 四川成都, 1), (1572, 岳不群, 1, 1993-7-19, 陕西咸阳, 1), (1378, 纪嫣然, 0, 1995-8-12, 四川绵阳, 1), (1954, 林平之, 1, 1994-9-20, 福建莆田, 1), (2035, 东方不败, 1, 1988-6-30, NULL, 2), (3011, 林震南, 1, 1985-12-12, 福建莆田, 3), (3755, 项少龙, 1, 1993-1-25, 四川成都, 3), (3923, 杨不悔, 0, 1985-4-17, 四川成都, 3); -- 插入老师数据 INSERT INTO tb_teacher (tea_id, tea_name, tea_title, col_id) VALUES (1122, 张三丰, 教授, 1), (1133, 宋远桥, 副教授, 1), (1144, 杨逍, 副教授, 1), (2255, 范遥, 副教授, 2), (3366, 韦一笑, DEFAULT, 3); -- 插入课程数据 INSERT INTO tb_course (cou_id, cou_name, cou_credit, tea_id) VALUES (1111, Python程序设计, 3, 1122), (2222, Web前端开发, 2, 1122), (3333, 操作系统, 4, 1122), (4444, 计算机网络, 2, 1133), (5555, 编译原理, 4, 1144), (6666, 算法和数据结构, 3, 1144), (7777, 经贸法语, 3, 2255), (8888, 成本会计, 2, 3366), (9999, 审计学, 3, 3366); -- 插入选课数据 INSERT INTO tb_record (stu_id, cou_id, sel_date, score) VALUES (1001, 1111, 2017-09-01, 95), (1001, 2222, 2017-09-01, 87.5), (1001, 3333, 2017-09-01, 100), (1001, 4444, 2018-09-03, NULL), (1001, 6666, 2017-09-02, 100), (1002, 1111, 2017-09-03, 65), (1002, 5555, 2017-09-01, 42), (1033, 1111, 2017-09-03, 92.5), (1033, 4444, 2017-09-01, 78), (1033, 5555, 2017-09-01, 82.5), (1572, 1111, 2017-09-02, 78), (1378, 1111, 2017-09-05, 82), (1378, 7777, 2017-09-02, 65.5), (2035, 7777, 2018-09-03, 88), (2035, 9999, 2019-09-02, NULL), (3755, 1111, 2019-09-02, NULL), (3755, 8888, 2019-09-02, NULL), (3755, 9999, 2017-09-01, 92);注意上面的insert语句使用了批处理的方式来插入数据这种做法插入数据的效率比较高。同一份初始化数据也收录在仓库脚本 Day36-45/code/SRS_create_and_init.sql 中二者数据一致。上述脚本中有几个值得留意的细节DEFAULT的应用tb_teacher的tea_title字段建表时指定了DEFAULT 助教因此插入韦一笑时可以直接写DEFAULT让其使用默认职称这正是有默认值的字段可以省略赋值规则的体现。NULL的应用tb_student.stu_addr允许为空部分学生可以插入NULLtb_record.score允许为空decimal(4,1)未加NOT NULL未参加考试或未出成绩的选课记录成绩即为NULL。外键约束的体现学生、教师、课程、选课记录中的外键列如col_id、tea_id、stu_id、cou_id必须引用主表中已存在的值否则插入会失败。例如tb_student的col_id只能取1/2/3学院表中的值。纵深扩展从源码脚本看 DML 在项目中的落地形态与 DDL 的衔接约束如何影响 DML 行为从 Day36-45/37.SQL详解之DDL.md 的建表语句可以看到tb_student的col_id列带有外键约束fk_student_col_idtb_record带有联合唯一约束uk_record_stu_cou。这些约束直接决定了 DML 语句的边界外键约束维持两张表的参照完整性——向子表插入不存在的父表主键值会被拒绝删除被引用的父表行也会被拒绝除非在 DDL 中配置了ON DELETE CASCADE等策略联合唯一约束保证了同一个学生不能重复选同一门课程重复插入会触发 Duplicated Entry 错误非空约束NOT NULL与默认值约束决定了insert省略列时的合法性这正是本课反复强调省略的列必须有默认值或允许为 NULL的根源。在 Python 应用中的 DMLpymysql 的对应实现DML 语句最终服务于应用程序的数据持久化。在《Python接入MySQL数据库》Day36-45/44.Python接入MySQL数据库.md一课中insert、delete、update三种操作都有对应的pymysql实现范式其核心流程为创建连接 → 获取游标 →execute发出 SQL → 提交或回滚事务 → 关闭连接。例如插入数据时使用参数化查询避免 SQL 注入import pymysql no int(input(部门编号: )) name input(部门名称: ) location input(部门所在地: ) conn pymysql.connect(host127.0.0.1, port3306, userguest, passwordGuest.618, databasehrs, charsetutf8mb4) try: with conn.cursor() as cursor: affected_rows cursor.execute( insert into tb_dept values (%s, %s, %s), (no, name, location) ) if affected_rows 1: print(新增部门成功!!!) conn.commit() except pymysql.MySQLError as err: conn.rollback() print(type(err), err) finally: conn.close()这里有几个与本课知识点直接呼应的实践要点affected_rows返回值execute返回受影响的行数可以用来判断 DML 是否真正命中目标行——例如delete/update因where条件没匹配到任何记录时返回 0这有助于排查SQL 写对了但没生效的问题事务提交与回滚创建连接时默认开启了事务环境insert、delete、update执行后必须commit()才会真正生效异常时通过rollback()撤销本次操作也可以给connect传入autocommitTrue让每条 SQL 自动提交批量插入的对应写法SQL 层面用多值元组批量插入Python 层面则对应游标对象的executemany方法——第一个参数是 SQL 语句第二个参数是包含多组数据的列表或元组一条insert后面跟上多组数据完成批处理参数占位符%s占位符配合元组传参杜绝字符串拼接带来的 SQL 注入风险是业务系统使用 DML 的正确姿势。与 DQL 的衔接insert ... select已经展示了 DML 与 DQL 的结合。在本课完整数据脚本执行成功后即可进入下一课《SQL详解之DQL》Day36-45/39.SQL详解之DQL.md用select查询验证这些数据构成建表DDL→ 写数据DML→ 查数据DQL的完整闭环。总结DML 安全操作自查清单最后把本课的全部要点浓缩成一张自查清单供日常开发时对照操作核心语法关键注意事项insertINSERT INTO 表 (列...) VALUES (值...), (值...), ...省略的列必须有默认值或允许NULL主键不可重复批处理多值元组效率更高insert ... select可迁移数据deleteDELETE FROM 表 WHERE 条件永远先确认where条件不带where会删除全表truncate删除全表且无法恢复、自增归零updateUPDATE 表 SET 列值, 列值 WHERE 条件优先用主键/唯一键做筛选条件set后的是赋值where后的是等值判断几乎不会用到更新全表三条最核心的工程经验where是delete和update的生命线——写这两类语句时先问自己条件是否足够精确宁可先select验证条件再执行增删改优先使用显式列名的insert写法并善用DEFAULT、批处理与insert ... select区分delete与truncate的语义差异危险操作务必确认表、数据库、权限三重边界必要时依赖事务在事务内执行 DML 并rollback为误操作留出退路。本课内容与仓库中 Day36-45/code/SRS_create_and_init.sql、Day36-45/37.SQL详解之DDL.md、Day36-45/44.Python接入MySQL数据库.md 等资源互为印证建议按顺序完成建表、插数、查询、接入 Python 的全链路练习即可完整掌握关系型数据库 DML 的核心能力。赞分享文档教程【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址https://gitcode.com/GitHub_Trending/py/Python-100-Days点击查看免费下载相关推荐StarRocks Iceberg Catalog DML 操作完全指南INSERT / DELETE / UPDATE / MERGE INTO / TRUNCATE 实战与原理StarRocks Iceberg Catalog DML 操作完全指南INSERT / DELETE / UPDATE / MERGE INTO / TRU数据库OLAP数据仓库大数据湖仓一体数据分析Apache DataFusion 数据操纵语言DML完全指南COPY、INSERT、DELETE 与 UPDATEApache DataFusion 数据操纵语言DML完全指南COPY、INSERT、DELETE 与 UPDATE 本指南系统讲解 Apache Dat大数据数据分析后端Squirrel数据操作INSERT、UPDATE、DELETE详解Squirrel数据操作INSERT、UPDATE、DELETE详解 本文详细介绍了Squirrel框架中InsertBuilder的多值插入与批量操作、Up后端数据库上一篇Java泛型反射toBeBetterJavaer WildcardType下一篇FlicFlac7大音频格式一键转换的终极免费解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考