目录
前言:
1.数据库的约束
1.1约束类型
1.1.1 not null
1.1.2 unique 唯一约束
1.1.3 default 默认值约束
1.1.4 primary key 主键约束
1.1.5 foreign key 外键约束
2.表的关系
2.1 一对一
2.2 一对多
2.3 多对一
3.新增
4.聚合查询
4.1聚合函数
4.1.1 count
4.1.2 sum
4.1.3 AVG
4.1.4 max
4.1.5 min
4.2 group by子句
4.2.1 分组前删选条件用where。
4.2.2 分组后删选条件用having语句。
4.2.3 where + having
5.联合查询
5.1内连接
5.2外连接
5.3自连接
6.子查询
7.合并查询
结束语:
前言:
在上一节中小编主要介绍了数据库中的CRUD操作,也在MySQL的客户端中给大家演示了具体的操作,那么有关于数据库的约束又是什么情况呢?这节中小编将与大家分享数据库约束和表的关系两大部分,大家来随小编的步伐一起来往下走吧!
1.数据库的约束
1.1约束类型
- not null :指示某一行不能存储null的值。
- unique:保证某列的每行必须有唯一的值。
- default:规定没有给列赋值时的默认值。
- primary key:相当于是not null和unique的结合,确保某列(或两个列多个列结合)有唯一标识,有助于更容易更快地找到表中的一个特定的记录。
- foreign key:保证一个表中的数据匹配到另一个表中的值参照完整性。
- check:保证列中的值符合指定的条件,对于MYSQL数据库,对check子句进行分析,但是忽略check子句。这个在MySQL5版本中是不支持的,但是写了不会报错,也没有什么实际的意义和效果,这里我们对check操作就不做过多的讨论了。
1.1.1 not null
现在我们重新来设置一个学生表结构。
现在我们来查看一下表的结构。
你会发现id这一行的第三列上面的那个null是NO。也就是说我们以后在插入值的时候我们是不可以给ID插入一个null值的。
1.1.2 unique 唯一约束
指定某一列是唯一的,不重复的。在插入/修改数据的时候,会先查询,先看看数据是否已经存在,如果不存在就能够插入/修改 成功,如果存在,则插入/修改失败。
在没加唯一约束的时候,我们可以进行多次插入。
如果我们给id加上unique约束,如下所示:
我们会发现如果我们两次插入相同的id时就会发生错误,显示我们无法插入。他说是我们有重复的条目。
1.1.3 default 默认值约束
默认值是insert指定插入的时候,其他未被指定的列就是按照默认值来进行填充。
我们可以在创建表的时候给指定默认值。
1.1.4 primary key 主键约束
主键我们可以理解为一条记录的身份标识,就像我们人一样,每一个人都有唯一的一串身份证号,这是我们每个人都不一样的标记。
它要求唯一且不能为空。所以主键就类似于unique + not null。但是也不完全就是。
在MYSQL中要求一个表中只能有一个主键,在创建主键的时候我们可以使用一个列来作为主键,也可以使用多个列来作为主键(复合主键),但是这里我们对复合主键不做过多的讨论。
当你多次进行插入相同的id值的时候,就会报错。
一个重要的问题:如何给这个记录安排一个主键呢?
MySQL自身只是能够检查是否重复,设置的时候还得是靠程序员来进行设置,此处MySQL中提供了一种简单粗暴的办法,那就是使用自增主键,auto_increment具体操作我们来看下面的客户端操作。
你会发现我们在插入数据的时候更本没有管id这一行的数据,但是系统帮我们就自动分配了。
注意:如果你是指定一个id值之后那么之后你如果不指定id值的话系统就会随着你的id值进行继续分配。
1.1.5 foreign key 外键约束
外键用于关联其他表的主键或唯一键。
语法:
foreign key (字段名)reference 主表(列)
我们创建两张表,并把它们的classId进行关联。
此时我们就要求在student表中的每一条classID记录都要在class中能够找到,如果没有就会报错。
这里我就将class表叫做student的父表。
当你想要删除父表中的classID为1的信息的时候你会发现是删除不了的,当父表在约束子表的同时,子表也在约束着父表。
2.表的关系
设计表的时候我们分两步走。
- 梳理清楚需求中的“实体”。
- 梳理清楚实体之间的关系。
2.1 一对一
例如:
一个学生,只能有一个账号。
一个账号,只能提供一个学生所有。
方法一:
我们可以搞一张大表,同时包含学生信息和账号信息。(这里小编就简写了)
account-student (accountId,username,password, studentName);
方法二:
搞两个表,互相进行关联。
account(accountId,username, password, studentId);
student(studentId, name...);
方法三:
搞两个表。
account(accountId,username, password);
student(studentId, studentName, accountId);
2.2 一对多
例如:
一个班级可以包含多个学生。
一个学生只能对应一个班级。
方法一:
student(studentId, name);
class(classId,className,studentIdList);
注意:
相当于是在class表中搞了一个学生id的列表,但是MySQL中没有数组类型,不能这样搞,有些数据库是由这种类型的如Redis,在Redis中就可以考虑这样设计。
方法二:
class(classId,className);
student(studentId, name,classId);
2.3 多对一
例如:
一个学生可以选择多个课程。
一个课程也可以提供给多个学生。
student(studentId, name);
course(courseId, name);
student_course(studentId,courseId);//联合表,将上面的两张表进行关联起来。
3.新增
我们这里的新增是在上一节的基础上进行了一定的升级。
我们是将一个查询结果作为新增的内容放入到了insert语句中,如下所示:
这里我们要注意的是我们的列名可以不一样,但是数据类型一定要匹配。
4.聚合查询
4.1聚合函数
函数 | 说明 |
count() | 返回查询到的数据的数量 |
sum() | 返回查询到的数据的总和,不是数字没有意义 |
AVG() | 返回查询到的数据的平均值,不是数字没有意义 |
max() | 返回查询到的数据的最大值,不是数字没有意义 |
min() | 返回查询到的数据的最小值,不是数字没有意义 |
我们先来创建一张学生表。
4.1.1 count
我们计算一下学生表中一共有多少个学生。
4.1.2 sum
我们来计算一下这个班所有学生的各科的总成绩。
4.1.3 AVG
我们来计算一下这个班学生每一科的平均分是多少。
计算一下三门科目总成绩的平均分。
4.1.4 max
我们来求一下每一科目的最高分是多少。
4.1.5 min
我们来求一下每个科目的最低分是多少。
4.2 group by子句
select中使用group by子句可以对指定列进行分组查询,需要满足:使用group by进行分组查询时,select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中。
语法:
select 列名,聚合函数(),.... from 表名 group by 列名;
案例演示:
我们先来创建出一个emp表来。
现在我们来求出每个岗位的平均薪资。
4.2.1 分组前删选条件用where。
求每个岗位的平均薪资但是要除去孙悟空同学。
4.2.2 分组后删选条件用having语句。
求每个岗位的平均薪资,但是除去老板的。
4.2.3 where + having
也可以同时在分组前和分组后进行筛选。
5.联合查询
5.1内连接
我们上面和之前所学习的都是在一个表中进行操作的,那么如何在两个表甚至是多个表中进行查询呢?这里我们就涉及到了联合查询。将多个表联合在一起进行查询。
我们在实际开发中往往数据是来自不同的表中的,所以需要多表联合查询,多表联合查询是对多张表的数据取笛卡尔积。
什么是笛卡尔积呢?下面我们通过几张表来进行演示一下。
但是我们会发现在笛卡尔积表中会有很多无效的数据,我们划掉之后就变成下面的这张表了。
笛卡尔积是得到了一张更大的表,列数是两个表列数之和,行数是两个表行数之积。
案例演示:
首先我们先来创爱出三张表:
下面我们来查询一下“许仙”同学的成绩。
首先我们先来确定一下我们要找的关键字是学生名字和成绩,它两一个是在学生表中一个是在成绩表中。所以我们需要先将两张表进行笛卡尔积,将所需要的信息聚集在一张表中。
注意:这里的查询结果小编只是截取了一点。
我们要删除掉一些无用信息。我们可以通过学生表中的id和成绩表中的student_id来进行关联。
这里我们也可以通过 表名.列名 的方式来指定列,一般推荐大家使用这个方法,以防万一两张表中的关键字是一样的,便于区分。
此时我们就只剩最后一步,在加上一个条件既可以查询到许仙同学的成绩了。
我们还可以对列进行简化。
这里我们来总结一下多表查询的一般步骤:
- 分析清楚需求中,涉及到的信息都在哪些表中。
- 针对这多个表进行笛卡尔积。
- 筛选出其中的有效数据。
- 结合需求中的条件,进一步的加强条件。
- 针对列进行精简。
上述中我们在进行笛卡尔积的时候使用的是 ,进行笛卡尔积的,同样我们也可以使用 join 这个关键字来进行笛卡尔积,此时如果后续还要继续加强条件的时候我们使用的就不是where了而是on这个关键字。如下所示:
案例二:
查询所有同学的总成绩。
具体的实施步骤如下所示:
注意:
我们这里所讲的联合查询其实就是是内连接!!!其实内连接和外连接都是进行笛卡尔积。但是细节上是有所区别的。
5.2外连接
我先来创建出两张表,如下所示:
如果两个表中的数据不在是一一对应了,此时进行内连接,结果就只是两个表中都有体现的数据。
相当于我们之前学过的取两个集合的交集,如下所示:
左外连接,就是以左侧为准,将左侧表中的所有数据都体现出来。
如下示意图所示:
右外连接,就是以右侧的表为准将右侧表中的所有数据都体现出来。
如下示意图所示:
5.3自连接
自连接就是自己和自己进行连接,自己与自己做笛卡尔积。
6.子查询
子查询是指嵌套在其他SQL语句中的select语句,也叫嵌套查询。
案例演示:
查询与“不想毕业”同学的同班同学。
查询语文或者英语课程的成绩信息。
注意:
子查询在实际开发的时候要慎重使用,因为一旦子查询嵌套太多层对于代码的可读性将会是毁灭性的打击!!!
7.合并查询
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符union,union all,使用union和union all时,前后查询的结果集中,字段需要一致。
案例演示:
查询id小于3,或者名字为英文的课程。
通过上述情况我们可以看出来or只能针对一个表,而union可以把多个表的查询结果进行合并。
这里还有一个关键字是union all 它与union的区别就是union会自动去重而union all是不会自动去重的。
结束语:
好了小编今天就与大家分享到这里啦,这节中小编主要与大家分享了数据库中的一些约束、联合查询、怎么进行内连接、怎么进行外连接、自连接和合并查询,不知道大家对这块知识有没有掌握,大家记得下去之后多加练习哦!大家继续跟紧小编的步伐,一起往前冲!!!希望这节对大家认识数据库有一定的帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)