一.数据库约束
1.约束类型:
NOT NULL:
并且也是无法通过update进行修改的。
2.unique
3.default
建表是default指定在某个变量之后。
primary key主键:
主键是身份的唯一标识,并且也不能设定多个主键,并且主键包含NOT NULL和UNIQUE的功能。
自增主键需要增加一个auto_increment:
如果手动插入id,则自增主键是从手动插入的id开始自增,字符串也能作业主键,在多个MySQL构成的分布式集群时会使用到:
foreign key:
需要注意的是,使用外键时,所绑定表上的变量必须是主键或者唯一键才能进行绑定(如果不是则会报错第二张图中有):
当存在外键约束是,如果插入的数据父表中不存在,则无法插入,修改也无法进行,因为班级表为父表,学生表为子表,父表会对子表进行约束。
但是在父表中删除数据时,如果父表的数据被子表使用后,则没办法进行删除,必须先删除子表中引用信息的数据,才能再对父表中的数据进行删除。
二.表的设计
1.一对一
一个学生只有一个学生证
如果设计一个表,则这个表就包含这个学生的姓名,身份证,学号,等。
如果设计两个表,则一个表是学生表,这个表包含学号,学生姓名,身份证。
第二个表是学生证的表,这个表包含学生的学号,等其他信息。这样就形成了关联。
2.一对多
一个班级有多个学生。
3.多对多
学生和课程之间都是多对多的关系
三.查询和新增相结合
两张表的变量名可以不相同,主要是按照两张表变量的顺序来进行复制的,在复制过程中,可以在insert into 表名(变量名顺序) select * from 表名 (where条件可以加,也可以不加),也可以在insert into 表名 select (变量名顺序) from 表名 (where条件可以加,也可以不加)来进行控制两张表的变量名顺序后再进行复制。
四.聚合查询
1.聚合函数
count:
计算这个表某个列的行数,还需要注意的是count后面的括号必须紧挨着count不能有空格。
当表的数据的某一行,存在只有一个列的数据不为NULL,则使用count(*)还是会将其计算(行数)数据量中,但是通过count(某个列名),比如通过id列来进行count(id)进行查询则不会加空的数据进算进去。如果某一列的数据存在重复的,则会累加,需要去重需要在前面加入distinct进行去重。:
sum:
对某一列进行求和:
但是数据必须是可计算的数据,而不能是字符串类无法计算的数据,遇到null值也不会参与计算,直接跳过:
avg:
计算平均值,跳过为null的值:
max:
min:
其他的方差等都可以通过这些聚合函数进行查询,可以自行去看MySQL的官方文档。
group by分组查询
取某一组中第一个数据,进行分组,但是一般不这么写,一般都是通过聚合函数一起表示(图二):
对分组查询的数据而言还能进行排序操作:
还可以搭配条件来进行使用,分为两种,第一种为在分组前的条件,简单地说条件先进行,再分组。第二种也就是分组后的条件,简单地说先分组后,再按照条件来进行调整。
分组前的条件使用where
查询不同role的平均薪资之前,除去zhangsan的薪资:
分组后的条件使用having
查询不同role的平均薪资后,排除平均薪资高于15000:
分组前和后的条件:
查询不同role的平均薪资之前,除去zhangsan的薪资,查询后,再排除平均薪资高于15000:
联合查询
简单的来说,多表联合查询,就是通过两张或者多张有关联的表进行排列组合后,在通过一些有共同的特征来进行查询我们所需要的信息。
1.多表的排列组合:
2.添加条件后完善的多表查询
3.多表查询练习
现在有学生,班级,课程,得分四张表,进行多表查询举例:
查询许仙同学的成绩:
先分析四张表会用到那些表,查询某个同学的成绩肯定会使用到学生表和成绩表,如果还需要其他的表后续继续分析,现在对学生表和成绩表进行笛卡尔积(信息过多不再过多截图):
在通过两个表之间存在的联系也就是学生表中存在学生id,成绩表中也有学生id,则可以简化查询表的数据:
此时找到了每个学生对应的成绩,现在还需要精确到某个同学,这里是许仙则继续加上条件查询:
在对需要的列进行精简:
另一种方法通过join进行多表查询:
查询所有同学的总成绩,及个人信息:
学生表和分数表进行笛卡尔积,再进行两个表的联系进行条件查询,和上述一样不重复操作,此时再通过学生的id进行分组:
再通过聚合函数来进行计算总分,最后精简查询信息,也可以使用join on(图二):
查询所有同学的成绩,以及列出同学的名字,课程名字,课程分数
通过join on来写:
4.内连接
上述操作均为内连接操作。
5.外连接
当两张表的信息一一对应时,两个表进行内连接和外连接的结果是一样的(下图为两张表的信息一一对应):
当两张表不是一一对应的关系时,内连接和外连接就不相同了,内连接的结果:
或使用join on来写:
左外连接结果:
右外连接结果:
左右外连接中的左右是用来作为基准进行查询的,假设使用左外连接查询数据,左外连接则以左边的表也就是join左边的表进行标准来查询数据,当右边的表也就是join右边的表中没有左边表的一个数据时,则查询到的数据为NULL,这就是wangwu的score为NULL的原因。此时只按照左边的表进行标准,只会显示左边表中存在的数据,右边表中多余的数据,即使也是score,但是左表中不存在这个用户的id或者其他标识,则不会被查询到,这就是score表中id=4的数据没有显示的原因,右连接也是一个道理。
画图的理解:
6.自连接
查询计算机分数比java分数高的同学有哪些,这就使用到了自连接,简单地说就是一张表和自己本身进行笛卡尔积,这是因为之前的SQL查询是通过列进行比较,这里的话会使用到行进行比较,所以需要通过自连接将行的比较关系变成列的比较关系:
需要注意的是,在自连接的时候需要通过as来取别名才能进行自连接不然会进行报错:
7.子查询
当一个需求需要多个SQL来完成,但是现在强制将多个SQL合并为一个SQL进行查询。这种做法和软件开发的基本原则背道而驰,将简单的东西复杂化了。
子查询的基本写法,单行查询,例如查询不想毕业的同班同学:
这是正常查询的步骤
子查询的单行查询:
多行子查询,例如语文或英语的成绩;
正常查询步骤:
多行子查询:
子查询的本身不推荐使用,exits非常消耗时间,背后会触发大量的硬盘IO操作。
EXISTS:
是一种用于子查询的条件运算符,用于检查子查询是否返回任何行。如果子查询返回至少一行,EXISTS返回 TRUE,否则返回 FALSE
。EXISTS
通常与 WHERE
子句一起使用,用于过滤主查询的结果。
EXISTS语法:
SELECT column1, column2, ...
FROM table1
WHERE EXISTS (SELECT 1 FROM table2 WHERE condition);
实际应用:
注意事项:
-
性能:
EXISTS
通常在子查询找到第一个匹配项后立即返回,因此在某些情况下比IN
或JOIN
更高效。 -
子查询结果:
EXISTS
不关心子查询返回的具体数据,只关心是否有数据返回,因此子查询中的SELECT
通常使用SELECT 1
或SELECT *
。 -
相关性:
EXISTS
子查询通常是相关的,即子查询依赖于外部查询的当前行。
与 IN
的区别
-
EXISTS
通常在子查询找到第一个匹配项后停止,而IN
需要处理整个子查询结果集。 -
EXISTS
用于检查子查询是否返回任何行,而IN
用于检查某个值是否在子查询的结果集中。
select 1:
SELECT 1
是一个简单的 SQL 查询,它的作用是返回一个值为 1
的常量结果集,当你不从任何表中查询数据时,SELECT 1
会返回一个单行单列的结果集,值为 1,
当你从表中查询 SELECT 1
时,它的行为是:为表中的每一行返回一个值为 1
的结果。SELECT 1
通常用于子查询中,尤其是在 EXISTS
或 WHERE
子句中。它的作用是检查子查询是否返回任何行,而不是关心具体返回的数据。
select 1用途:
EXISTS
子查询:用于检查子查询是否返回任何行。
占位符查询:当你不需要实际数据,只需要知道查询是否成功时,可以使用 SELECT 1
性能优化:在子查询中,SELECT 1
比 SELECT *
更高效,因为它不需要读取实际数据,只需要检查是否存在符合条件的行。
五.合并查询
使用union把多个select查询结果合并在一起,而且可以是不同的表进行多个select查询结果合并。
union使用在两张不同的表上进行select查询结果的合并时会进行默认的去重,在union后面加上all就可以取消默认去重。使用union时,要求合并的双方类型,个数,顺序,匹配。列名不做要求,当列名不相同时,以union左边的表的列名作为标准: