保证某列的每行必须有唯一的值。
数据库如何判定,当前这一条记录是重复的?先查找,再插入。但是加上约束之后,数据库的执行过程可能就变了。因此执行时间或者效率会受到很大影响。
约束是可以组合在一起使用的。一列中可以同时加上多个约束。如:
主键约束,就是not null + unique
主键也同样是在插入记录的时候,需要先查询,再进行真正的插入。
正因为主键和unique都有先查询的过程,MySQL就会默认给primary key和unique 这样的列,自动添加索引,来提高查询速度。
注意:
针对两个表之间,产生的约束。
外键约束的含义,就是要求student里的classId 务必要在class表的id列中存在。
学生表中的数据要依赖班级表的数据。班级表的数据要对学生表产生约束力。此处起到约束作用的班级,就叫做“父表”(parent),被约束的这个表,就叫做子表(child)。
外键约束,是父表对 子表做了约束,但与此同时。子表也在反过来约束了父表。
id为1,被子表引用了,因此被约束,无法删除id为1的数据。
id为2,没有被引用,可以删除。
这是为什么呢?每次给子表插入数据,势必要在父表中查询一下这个id是否存在。默认情况下查询是需要遍历表的。在表非常大的时候,遍历效率非常低,所以要使用索引。
要想创建外键,就要求父表的对应的列,得有primary key 或者unique约束。
表的设计/数据库的设计,要做的工作,就是明确一个程序里,需要使用几个数据库,几个表,表里有哪些列~
设计表/数据库基本思路:
在教务系统中,有一个实体,学生,还有一个实体,账号。
一个学生,只能拥有一个账号(一个学生不能有多个账号)
一个账号,只能被一个同学使用(一个账号不能给多个同学共享)
针对这种关系:
student.studentId与account.studentId相互关联~
一个学生,只能存在于一个班级中。
一个班级,可以包含多个学生。
针对这种关系:
学生与课程之间:
一个学生可以选修多门课程
一门课程,也可以被多个学生来选择
针对这种关系:
student(studentId,name);
course(courseId,name);
student_course(studentId,courseId);
本质上是在针对行和行之间进行计算。
进行聚合,需要搭配聚合函数(SQL中内置的一组函数)
常见的聚合函数有:
这些操作都是针对某个列的所有行来进行运算的。
注意:count和()之间不能有空格,必须紧挨着!!!
sum求和:
要求这个列必须得是数字。
NULL和任何数据运算,结果都是NULL,sum会尽可能的避免这种情况。
使用group by 对表中的行进行分组
不用group by分组的时候,相当于只有一组。引入group by就可以针对不同的组来分别进行聚合。
如果不带聚合函数的普通查询,一般不能group by。mysql中如果没有order by,这里的顺序是不可预期的。
分组查询,也是可以指定条件的。有两种情况:
实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积:
笛卡尔积是通过排列组合来的。
笛卡尔积得到一个更大的表。列数就是两个表列数只和。行数就是两个表行数之积。
但是仔细观察,笛卡尔积里的很多结果,是无效数据。只有一部分是有意义的。
需要用到成员访问运算符.
加上以上条件之后,结果就只剩下合法数据了。我们吧这个用来筛选有效数据的条件称为连接条件。
任务1:查询许仙同学的成绩
要想完成上述查询,就需要吧学生表和分数表进行联合查询。
那么如何进行联合查询呢?
任务2:查询所有同学的总成绩,以及同学的个人信息
分析:要列出每个同学的姓名(student表)和总分(分数表),由于此处是按照行的维度来进行组织的,就需要使用聚合查询来完成。
任务3:查询所有同学的成绩以及同学的个人信息
分析:期望查询结果中,有个人信息(student表),有课程名字(class表),有分数(分数表)
内连接语法:
select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;
外连接语法:
-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;
内连接和外连接大多数情况下没什么区别。但是如果表不是一一对应,内连接和外连接就有区别了。
左外连接:会把左表的结果尽量列出来,哪怕在右表中没有对应的记录,就使用NULL填充。
同理,右表连接,会把右表的结果尽量列出来,哪怕左表中没有对应的李璐,就使用NULL来填充。
子查询本质上就是套娃。把多个SQL组合成一个。实际开发中,子查询要慎用!
单行子查询:返回一行记录的子查询
任务:查询与“不想毕业”同学的同班同学
分析:先去查询不想毕业同学的班级id,再按照班级id来查询那些同学和他一个班。
子查询就是把两个操作合并~
返回多行记录的子查询
任务:查询“语文”或者“英语课程的成绩信息”
分析:1.现根据名字查课程id
2.根据课程id查询课程分数
在这里插入图片描述
本质上是吧两个查询的结果集,合并成一个。(要求这两结果集的列相同,才能合并)
任务:查询id小于3,或者名字为“英文”的课程。
union all和union差不多,union是会进行去重的。union all则是可以保留多份,不去重。
知识扩展:
高内聚和低耦合
耦合:描述了模块之间的关联关系是不是比较强。认为关联关系越强,越复杂,即耦合度越高,越不好。
高内聚:把所有有关联关系的代码写到一起。