SQL详解之DML(数据操作语言)
本节课将结合上一课创建的「学校选课系统数据库(school)」,详细讲解DML(Data Manipulation Language,数据操作语言)的使用。DML的核心作用是对二维表中的数据进行交互操作,主要包含三类核心指令:插入数据(INSERT)、删除数据(DELETE)、更新数据(UPDATE)。
温馨提示:执行所有DML操作前,请先通过以下命令切换到school数据库,避免操作错误数据库导致数据异常。
USE `school`;
insert操作(插入数据)
INSERT用于向二维表中插入一条或多条记录(行),核心语法灵活,可根据需求选择不同插入方式,以下结合school数据库的「学院表(tb_college)」演示所有常用场景。
INSERT INTO `tb_college` VALUES (DEFAULT, '计算机学院', '学习计算机科学与技术的地方');
说明:tb_college的主键(col_id)是自增字段,无法手动赋值,因此用DEFAULT表示使用该字段的默认值(自增序列)。
易错提示:此方式必须严格按照建表时的字段顺序赋值,若字段顺序调整,会导致插入失败或数据错乱,日常开发不推荐。
INSERT INTO `tb_college` (`col_name`, `col_intro`) VALUES ('计算机学院', '学习计算机科学与技术的地方');
核心规则(必记):
除「允许为NULL」和「有默认值」的字段外,其他字段必须一一列出,并在VALUES后赋值;
字段名与VALUES后的赋值顺序、数据类型必须完全对应,否则会报类型不匹配错误;
主键若为自增/默认值字段,可省略不写(自动触发默认规则)。
如果希望一次性插入多条记录,我们可以在values后面跟上多个元组来实现批量插入,代码如下所示。
INSERT INTO `tb_college` (`col_name`, `col_intro`) VALUES ('外国语学院', '学习歪果仁的语言的学院'), ('经济管理学院', '经世济民,治理国家;管理科学,兴国之道'), ('体育学院', '发展体育运动,增强人民体质');
在插入数据时,要注意主键是不能重复的,如果插入的数据与表中已有记录主键相同,那么insert操作将会产生 Duplicated Entry 的报错信息。再次提醒大家,如果insert操作省略了某些列,那么这些列要么有默认值,要么允许为null,否则也将产生错误。在业务系统中,为了让insert操作不影响其他操作(主要是后面要讲的select操作)的性能,可以在insert和into之间加一个low_priority来降低insert操作的优先级,这个做法也适用于下面要讲的delete和update操作。
假如有一张名为tb_temp的表中有a和b两个列,分别保存了学院的名称和学院的介绍,我们也可以通过查询操作获得tb_temp表的数据并插入到学院表中,如下所示,其中的select就是我们之前提到的 DQL,在下一课中会详细讲解。
INSERT INTO `tb_college` (`col_name`, `col_intro`)SELECT `a`, `b` FROM `tb_temp`;
说明:SELECT语句属于DQL(数据查询语言),具体用法将在下一课详细讲解,此处仅了解该插入场景即可。
INSERT操作核心注意事项
主键唯一:插入的数据若与表中已有记录的主键重复,会报「Duplicated Entry」错误;
字段约束:省略的字段必须满足「允许为NULL」或「有默认值」,否则插入失败;
性能优化:业务系统中,若需插入大量数据,可在INSERT和INTO之间加「LOW_PRIORITY」,降低插入操作优先级,避免影响SELECT等高频操作(DELETE、UPDATE也适用)。
delete 操作
DELETE用于删除表中的指定记录(行),核心是通过WHERE子句筛选删除条件,若省略WHERE子句,会删除表中所有记录,风险极高,需重点注意。以下结合tb_college表演示。
DELETEFROM `tb_college`WHERE col_id=1;
提示:优先通过主键(如col_id、stu_id)筛选删除,主键唯一可确保只删除目标记录,避免因其他字段重复(如学院名相同)误删多条数据。
DELETEFROM `tb_college`;
关键说明:
update 操作
UPDATE用于修改表中已有的指定记录(行),核心是通过WHERE子句筛选目标记录,通过SET子句指定修改的字段和新值,同样需避免省略WHERE子句导致全表更新。以下结合school数据库的「学生表(tb_student)」演示。
UPDATE `tb_student`SET `stu_name`='杨逍'WHERE `stu_id`=1001;
关键注意点:
如果要同时修改学生的姓名和生日,我们可以对上面的update语句稍作修改,如下所示。
UPDATE `tb_student`SET `stu_name`='杨逍' , `stu_birth`='1975-12-29'WHERE `stu_id`=1001;
update语句中也可以使用查询的方式获得数据并以此来更新指定的表数据,有兴趣的读者可以自行研究。在书写update语句时,通常都会有where子句,因为实际工作中几乎不太会用到更新全表的操作,这一点大家一定要注意。
UPDATE操作核心注意事项
严禁省略WHERE:省略后会更新表中所有记录(如UPDATE `tb_student` SET `stu_sex`=1; 会修改所有学生性别),生产环境需严格规避;
数据类型匹配:SET子句中赋值的数据类型,必须与字段定义的类型一致(如日期字段不能赋值字符串);
性能优化:更新大量数据时,可加LOW_PRIORITY降低优先级,避免影响其他操作。
完整的数据
下面我们给出完整的向 school 数据库的五张表中插入数据的 SQL。
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语句使用了批处理的方式来插入数据,这种做法插入数据的效率比较高。