初写MySQL四张表:(3/4)

我们已经完成了四张表的创建,学会了创建表和查看表字段信息的语句。

初写MySQL四张表:(1/4)-CSDN博客

初写MySQL四张表:(2/4)-CSDN博客

接下来,我们来学点对数据的操作:增 删 查(一部分)改

先来看这四张表以及相关需求:

四张表

需求一:

这便是向我们创建好的空表里面,插入数据。具体语句我们使用INSERT INTO ,接下来介绍一番:

INSERT INTO:

先来申请英译中:

现在是逻辑课:按照语法来说"插入到"后面得加个地点吧,题上不是说了嘛,"添加到学生表"。根据前面的习惯,表名我们会select一个DATABASE。

(我们可以看到左侧,学生表stu是放在testdb中的)

所以按照猜测语句应该有这样一部分:

sql 复制代码
INSERT INTO testdb.stu

后面按理说就应该是添数据对吧:但是一行数据我们要添加的数据项可能并不是全部字段(属性)------比如在stu表中,我们若添加数据只包含学号 、姓名 、学院编号。但是我们并不添加性别和出生日期这两个字段。

这种添加数据但是不包含所有字段的数据,需要我们自己指明要添加的字段名:

sql 复制代码
#假如,指定添加该学生的学号,姓名和学院编号
INSERT INTO testdb.stu(stuid,stuname,deptid)
...
#字段之间用逗号隔开

如果你要添加的数据,包含全部的字段,这时候就不需要指明添加的字段名,默认你要添加所有字段。比如这里的需求:

但是,我们添加的核心,始终是数据。

我们会添加一个关键字VALUES:而数据就放在VALUES();的括号中。这里就应该这样表示:

sql 复制代码
INSERT INTO testdb.stu
VALUES('2022121001','张三','男','2006-5-1','1');
#这是一行记录,一行记录的数据值之间也需要使用逗号隔开。其中字符型数据需要使用单引号。

发现没有,所有数据值的顺序对应我们字段的顺序。

补充:

我们前面在创建表的时候,不是有个字段NOT NULL约束吗?NOT NULL到底什么时候约束呢?就是添加记录的时候。

INTO子句中没有出现的字段,新添加的记录在这些字段上将被赋NULL值。但是表定义时有NOT NULL约束的字段不能取NULL值,添加记录时必须给其赋值。

我们运行一下:

sql 复制代码
#Error Code: 1452. 
/*Cannot add or update a child row: 
a foreign key constraint fails (`testdb`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`deptid`) REFERENCES `dept` (`deptid`))*/

报错了,很好。具体错误是:无法添加或更新一个子行(row,在MySQL里,行也称作一条记录)。

外键约束无效:

原因是什么呢?是因为我们的外键约束失败了。外键为什么不行,还记得外键怎么来的吗?外键是另一张表的主键的引用,保证数据的完整性。不仅如此,从表中的外键列只能包含主表中已存在的主键值,避免了出现悬挂指针(指向不存在的数据)或数据不一致的情况。

外键能约束说明它心中已经有杆秤了,外键本质上是另一张表的主键。而有杆秤,说明该主表的主键列已经有值了------怎么至少也得有>=1个值吧,外键就依据这些现有的值来判断你添加的值是否有效了。------这就是外键约束。

解决方案:先在dept表里添加主键值,那就要我们再写一个INSERT INTO 呗,但是,你觉得这种写法可行吗?

sql 复制代码
INSERT INTO testdb.dept(deptid)
VALUES('1');

看见没,前面的补充你只要明白了,这里你就知道为什么我们不能单单添加deptid了。NOT NULL约束对不对?

sql 复制代码
INSERT INTO testdb.dept
VALUES('1','计算机学院');

运行一下,添加记录。

此时再添加这条学生信息,想必就不会外键失效了。

sql 复制代码
INSERT INTO testdb.stu
VALUES('2022121001','张三','男','2006-5-1','1');

也成功了,但是文字的显示始终没有图形来得震撼。

我们前面说,DESC + 表名是查看表的字段信息,但是我们添加了数据,该怎么去看有数据的表呢?

SELECT * FROM

sql 复制代码
SELECT * FROM 表名;
#表名包括了数据库

SELECT 表示筛选,*是通配符,表示"所有",FROM 表,连起来就是从某个表里的所有字段列中筛选数据------作用是:查询该表中的全部内容。

sql 复制代码
SELECT * FROM testdb.dept;
#刚刚添加了一条数据,我们来显示一下

是吧,添加成功了。

这里浅浅说说,方便我们检验操作,因为我们后面不远处,还会说到select 。

需求一的参考代码:

sql 复制代码
INSERT INTO testdb.dept
VALUES('1','计算机学院');
INSERT INTO testdb.stu
VALUES('2022121001','张三','男','2006-5-1','1');

需求二:

在学生表中删除学号为'2022121001'的学生信息。

分析需求:核心是删除一条记录,删的记录是哪里的? stu这张表里的。它直接报出了学号,咱们就得按照学号来检索删除。

按理说,这个"检索删除"有两步,但是学习的魅力就在于此:我们若只着眼于解决当下问题,就可以直接站在巨人的肩膀上,一步到位;但是我们若要追根溯源,探寻如何实现,也有前人给我们源码研究。

现在就允许我们先跪在巨人的肩膀上吧,学个DELETE from

DELETE FROM

DELETE FROM按照之前的设计后面也接个表名,你是这么猜,它也真的这么设计。这里就是:

sql 复制代码
DELETE FROM testdb.stu
#我没打分号就表示这不是一句完整的语句,提醒一句

WHERE

WHERE关键字,WHERE 是 SQL 语言中的一个关键字,它用于指定 DELETEUPDATESELECT 等语句中的条件,以限制哪些行(记录)会被影响或返回。

此处,DELETE FROM ... WHERE ...其结果是:指定删除。

怎么用呢? 比如:学生表中,你要指定删除一个叫"王五"的学生。用DELETE FROM ...WHERE就是:

sql 复制代码
DELETE FROM testdb.stu WHERE stuname = '王五';
#指定删除学生表中学生姓名叫王五的学生的信息记录

运行当然运行不了,因为我们根本没添加过这条数据,我这里只是打个比方。

那实现这里的需求,也就照猫画虎了:

在学生表中删除学号为'2022121001'的学生信息。

sql 复制代码
DELETE FROM testdb.stu WHERE stuid = '2022121001';

运行之前,先看一下表里的数据:

再运行一下我们的删除语句:

显示删除成功了。(有时发现不知不觉就熬了夜☕哈哈哈)

ok,我们通过select * 检查一下,是否真的删除了。

记录没了,确实删除了,直观吧

需求二的参考代码:

sql 复制代码
DELETE FROM testdb.stu WHERE stuid = '2022121001';

需求三:

把课程表中课程编号为"CS003A"的课程的学分改为3。

分析:本质是什么,修改某条记录某个字段的值。关键词:修改表中的数据。

UPDATE ... SET ...

UPDATE 后面接表名,表示你要修改哪张表。SET 英译过来:"设置",这里和修改同义。

SET 设置的是前面确定表名的某个或多个字段 的值。

**扩展:**还记得前面说过的,WHERE加在不同的地方有指定的xx功能。和delete搭在一起,有指定删除的功能,那和set搭在一起,就有指定修改的功能。哟,这不巧了嘛。

我们的需求就是:指定修改课程表里课程编号为'CS003A'的课程记录的学分字段的值。(话有点长,但意思我写得清楚🤞)

比如:我们要把学生表里面的姓名叫"张三"的学生记录中的出生日期改成"2006-5-2"。

sql 复制代码
UPDATE testdb.stu
SET birthday = '2006-5-2'
WHERE stuname = '张三';
#照样是举个例子

那么,这个需求,实现也近在眼前了:

把课程表中课程编号为"CS003A"的课程的学分改为3。

sql 复制代码
UPDATE testdb.course
SET credit = 3
WHERE cid = 'CS003A';
#字符型数据才会加单引号,这里的学分不是字符型数据

但是,我们自己会发现这个修改数据是建立在有数据的基础上,若没有CSA003A这条课程的记录,甚至谈不上指定数据 。所以,我们还得手动添加一条数据记录。

sql 复制代码
INSERT INTO testdb.course
VALUES('CS003A','数据库',2,'1');
#添加该课程编号整一条记录

那么我们先运行添加,查看:

再来修改学分为3:

好了,完成了需求三------修改数据。

需求三的参考代码:

sql 复制代码
UPDATE testdb.course
SET credit = 3
WHERE cid = 'CS003A';

需求四:

查询学号为"2022121001"的学生所有信息。

分析:指定查询。

查询我们用关键字:SELECT,刚刚后面接*表示所有字段记录,若只有SELECT * FROM 表名,就表示查询该表中的全部内容。

现在我们要指定查询,就要在后面加个WHERE,起到我们期望的"指定"的效果。

WHERE 后面一般接字段名 = 某个值。

比如这里的:指定的是"学号为"2022121001"的学生"

sql 复制代码
WHERE stuid = '2022121001'

我们要实现的是"查询...所有信息",前面再加上SELECT * FROM 表名

sql 复制代码
SELECT * FROM testdb.stu
WHERE stuid = '2022121001';

我们运行一下,看看查询最后的效果是怎样。

所以得到需求四的实现代码:

sql 复制代码
SELECT * FROM testdb.stu
WHERE stuid = '2022121001';

需求五:

查询学院名称为"计算机学院"的学生名单,显示学号、姓名、学院。

分析:也是指定查询,SELECT ... FROM...WHERE...是跑不了了。但是特殊的需求是,并非如上个需求显示所有字段的数据,而是只显示部分字段数据。别忘了,学生表中只有学院编号,要让我们显示的不是学院编号,而是学院表里面才有的学院名称。

这次查询,不是单纯的在一张表上查询,而是两张表。

首先改变的,只有 "*" 变成对应的字段名。

sql 复制代码
#学号、姓名------ 这些字段来自stu表,后面FROM已经说明了是从学生表找。但是学院名称是在dept表中,则需要指明表
SELECT stuid,stuname,dept.deptname
FROM testdb.stu,testdb.dept
WHERE 

我们的查询条件应该接在WHERE后,条件是deptname = '计算机学院',而这里值得注意的是,怎么样把两张表连起来。这两张表有主从关系,主从关系从何而来,学生表的外键是学院表主键的有效引用。

没错就是,主键外键 ------ 学生表的外键是学院表主键的有效引用。则同时满足stu.deptid = dept.deptid

sql 复制代码
SELECT stuid,stuname,dept.deptname
FROM testdb.stu,testdb.dept
WHERE stu.deptid = dept.deptid AND deptname = '计算机学院';

AND

在SQL中用于表示关系的逻辑操作符和关键字,AND表示"前后两个表达式为真,记录就会被包含在查询结果中。",意思即"并且"。------ 呼应我们这里的学院名称为计算机学院 同时满足 两张表学员编号对应的要求。

运行效果:

查询学院名称为"计算机学院"的学生名单,显示学号、姓名、学院。

是不是挨个展示了 学号、姓名和学院名称。

这里,我们再介绍一种写法:

JOIN关键字

你需要通过两个表来进行联合查询(JOIN),join关键字后接上另一张表名。当将JOIN关键词放于FROM子句中,应有关键词ON与之对应,以表明连接的条件。

以前我们使用WHERE后面接查询条件和连接条件,现在我们使用ON。

查询学院名称为"计算机学院"的学生名单,显示学号、姓名、学院。

代码应该是这样:

sql 复制代码
SELECT stuid,stuname,dept.deptname
FROM testdb.stu
JOIN testdb.dept
ON stu.deptid = dept.deptid AND deptname = '计算机学院';
#JOIN 后接另一张表,ON和JOIN连用,ON后接连接条件和查询条件

是不是一样的效果?

需求五的参考代码:

sql 复制代码
#第一种:WHERE
SELECT stuid,stuname,dept.deptname
FROM testdb.stu,testdb.dept
WHERE stu.deptid = dept.deptid AND deptname = '计算机学院';
#第二种:JOIN ON
SELECT stuid,stuname,dept.deptname
FROM testdb.stu
JOIN testdb.dept
ON stu.deptid = dept.deptid AND deptname = '计算机学院';
#记得 SELECT ... FROM... 和 JOIN ... ON ...常见搭配

今天写得倒是很扎实,哈哈哈(意满离)

相关推荐
Karoku06626 分钟前
【企业级分布式系统】ELK优化
运维·服务器·数据库·elk·elasticsearch
小技与小术2 小时前
数据库表设计范式
数据库·mysql
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作
运维·服务器·数据库·sql·mysql
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验九 触发器
数据库·sql·mysql·oracle·实验报告
Loganer2 小时前
MongoDB分片集群搭建
数据库·mongodb
LKID体2 小时前
Python操作neo4j库py2neo使用之创建和查询(二)
数据库·python·neo4j
刘大浪2 小时前
后端数据增删改查基于Springboot+mybatis mysql 时间根据当时时间自动填充,数据库连接查询不一致,mysql数据库连接不好用
数据库·spring boot·mybatis
一只爱撸猫的程序猿2 小时前
简单实现一个系统升级过程中的数据平滑迁移的场景实例
数据库·spring boot·程序员
无敌岩雀2 小时前
MySQL中的索引
数据库·mysql
a_安徒生3 小时前
linux安装TDengine
linux·数据库·tdengine