数据库3.0
今天的内容是增删改查的进阶的一部分~
目录
一、数据库的约束
1.0 约束的定义
2.0 Mysql中提供了以下约束
3.0 示例
二、 表的设计
三、查询操作的进阶:
1.0 查询搭配插入使用
2.0 聚合查询
(1)聚合函数
(2)分组聚合查询
(3)练习题
3.0 联合查询(重难点)
(1)笛卡尔积
(2)示例
四、外连接、内连接、自连接
1.0 内连接
2.0 外连接
3.0 自连接
一、数据库的约束
1.0 约束的定义
数据库自动对数据的合法性进行校验检查的一系列机制~~
目的就是为了保护数据库中能避免被插入或修改一些非法的数据
2.0 Mysql中提供了以下约束
not null :指示某列不能存储NUll值
unique: 保证某列的每行必须有唯一的值
default:规定没有给列赋值时的默认值
primary key:not null 和 unique的结合,确保某列有唯一的值
foreign key :保证一个表中的数据匹配另一个表中的值的完整性
check:保证列中的值符合指定的条件
3.0 示例
not null:
unique(唯一的):
会让后续的查询/修改操作的时候,先触发一次查询操作
数据库引入约束之后,执行效率就会受到影响,就可能会降低很多
default:规定没有给列赋值的默认值
注意:desc 表名; desc-----> describe 描述
order by 列名 ; desc -------> descend 降序
写代码 补药随便搞缩写,缩写了之后,代码的含义就可能变得难以理解了
还有一个注意点: mysql是大小写不敏感的
所以你创建的表格 student Student 和STudent其实是一个表格
primary key (主键) :
这个是最重要的约束~~ 一行记录的身份标识
如何保证主键的唯一性:
mysql提供了一种‘自增主键’的机制 ~~
主键经常会使用int的形式 这样由数据库服务器自己给你分配一个主键 不必手动指定主键 值~
会从1开始,依次递增的分配主键的值
这里写作null 其实是让数据库服务器自行分配的 结果显示分配上了 id为1
foreign key (外键):
描述了两个表之间的关联关系
例:加我联系方式的时候 备注好你的班级和姓名 这个时候就和班级表和姓名表产生了关系
references JavaSE 引用
此处表示了当前这个表的这一列中的数据,应该出自于另一个表的哪一列
示例:
两个表建立连接之后 员工表的公司号只能是公司表里面的1 2 3 号中的一个
注意:
外键准确来说,是两个表的 列 产生关联关系,其他的列是不受影响的~~~
如果我尝试直接删除company表 删除不了表格
因为company 表没了 子表comployee表添加新的元素,就没的参考了~
正确的删除方式是:先删除子表 然后再删除父表
指定外键约束的时候,要求父表中被关联的这一列,得是主键或者是unique
意思是 父表被关联的这一列,company中的id列必须是主键 才能让employee表外键关联
二、 表的设计
如何设计一个表格?
根据实际的场景需求,明确当前要创建几个表,每个表啥样子,这些表之间是否存在一定联系
两个步骤: 梳理清楚 需求中的实体 再确定好实体之间的关系
实体: 就是咱们说的对象 一般来说,每个实体,都需要安排一个表,表的列就对应到实体的各个属性
实体之间的关系:一对一 一对多 多对多 没关系
一对一:一个学生只能有一个账号 一对多:一个班级能有多个学生 多对一
一个学生可以选多门课程 多门课程也可以包含多个学生
三、查询操作的进阶:
1.0 查询搭配插入使用
把查询的结果做为插入的数值~
insert into student2 select * from student ; 不写values了
限制:查询出来的结果集合, 列数和类型要和 插入的这个表匹配
意思是需要两个表的结构一样 这样才能实现查询结果插入
2.0 聚合查询
是相当于是在 行和行之间进行运算
(1)聚合函数
sql提供了一些聚合函数 来提供上述的运算
注释: sql中通过--空格 或者#开头 作为注释
如果当前列里面有null 两种方式计算的count就不同了
count:
count(*) null也会算进去 distinct 指定具体列,是可以去重的~
注意: count 后面直接就是() 不能有空格
在很多语言中,函数名和后面的()中间的空格是不做要求的
sum:
把这个一列的若干行 给进行求和 (算术运算) 只能针对数字类型使用
如果是针对字符产进行求和会怎么样 结果是0 同时有警告(有问题但不严重)
因为mysql会尝试进行类型转换为double 但是字符产007也会转换为double
sum还可以进行总成绩 select sum(Chinese+english + math) from exam_result;
avg 和 max 和min 类似上面两个 就不再赘述了
这说明,sql也可以进行一些简单的统计操作的~~~
(2)分组聚合查询
使用group by 进行分组,针对每个分组,再分别进行聚合查询
针对指定的列进行分组,把这一列中,值相同的行,分成到一组中
得到若干个组 针对这些组,分别使用聚合函数
select role ,avg(salary ) from emp group by role ;
select role salary from emp group by role;
往往还是要搭配聚合函数使用,否则这里的查询结果,就是没有意义的
使用group by的时候,还可以搭配条件
需要区分清楚,该条件是在分组之前还是在分组之后的条件
(3)练习题
# 查询每个岗位的平均工资,但是排除张三
select role ,avg(salary) from emp where name != ’张三' group by role ;
#查询每个岗位的平均薪资,但是排除平均薪资超过2w的结果
select role ,avg(salary) from emp group by role having avg(salary) <20000;
#查询每个岗位的平均薪资,不算张三,并且保留平均值<2w 的结果
select role ,avg(salary ) from emp where name != '张三' group by role having avg ;
3.0 联合查询(重难点)
多表查询,重点
(1)笛卡尔积
关键思路在于理解 '笛卡尔积'工作过程
笛卡尔积是通过 排列组合 的方式,得到一个更大的表
笛卡尔积的列数,是这两个表的列数相加
笛卡尔积的行数,是这两个表的行数相乘
但是笛卡尔积是简单无脑的排列组合,把所有可能的情况都穷举了一遍
就包含一些合法的数据也包含非法的无意义的数据
进行多表查询的时候,就需要把有意义的数据筛选出来,无意义的数据 过滤掉~
如何通过sql筛选出来 ? id 和 classid 一样的时候 这个时候 用where条件筛选就可以得到结果
(2)示例
查询许仙同学的成绩 下面是步骤:
(1)先把学生表和成绩表进行笛卡尔积 select * from student,score ;
(2) 加上连接条件 ,筛选出 有效数据 select *from student where id= student_id ;
建议写作 表名.列名的方式 (像是JavaSe里面的方式)
select *from student , score where student.id = socre.student_id ;
(3) 结合需求 ,进一步添加条件 针对结果进行筛选
select *from student score where student.id = socre.student__id and name='许仙';
比(2)多一个语句
(3) 根绝查询到的列进行精简 只保留关心的列
select student name, score.score from student where student.id = score.student_id and st
udent.name = ‘许仙’;
一步一步来 循序渐进的写
查询所有同学的总成绩 及同学的个人信息:
select * from student , score(先进行笛卡尔积)
select * from student ,score where student.id = score.student_id ;(指定连接条件)
select student.name ,score .socre from student ,score where student.id = score.student _id ;
(精简列) student表改为student.name socre表改为score.score
针对上述结果,再进行最后的group by进行聚合查询
select student.name ,sum(score.score) from student , score where student.id = score.student_id group by name ;
上面这些操作都是基于内连接完成的,在mysql中多表查询还可以使用外连接
力扣上,也有sql的练习专栏~~~ 主要就是聚合查询+联合查询
算法不是速成的,笔试强训,有难度是比较高的,需要日积月累
四、外连接、内连接、自连接
1.0 内连接
如果这两个表,里面的记录都是存在对应关系,内连接和外连接的结果是一致的
如果存在不对应的记录,内连接和外连接就会出现差别
上述写法得到的结果,就是内连接
2.0 外连接
左外连接 left join
select *from student left join score on student.id = socre.id ;
左外连接,就是以左侧表为基准~~保证左侧表的每个数据都会出现在最终的结果里
如果在右侧表中不存在,对应的列就填成null
右外连接 right join
select * from student right join score on student.id = score.id ;
右外连接,就是以左侧表为基准~~ 保证右侧表的每个数据都会出现在最终的结果里
如果左侧表中不存在,对应的列就填写成null
3.0 自连接
一张表 自己和自己进行笛卡尔积
有的时候,我们需要进行行与行之间比较
而 sql 只能进行列和列之间进行比较 但是有的时候,可能会涉及到
需要进行 行和行 之间的比较
可以使用自连接,把行的关系,转换成列的关系
然后就是和聚合查询那部分一样
感谢大家的支持
更多内容还在加载中...........
如有问题欢迎批评指正,祝大家生活愉快、学习顺利!!!