MySQL数据库|表设计+新增+分组查询

表的设计

OOA 面向对象分析 -- > OOD 面向对象设计 --> OOP 面向对象编程

1.从需求中获得类,类对应到数据库中的实体,实体在数据库中就表现为一张一张表,类中对应者表中的字段(列)

2.确定类与类之间的关系(一对一关系,一对多关系,多对多关系,没有关系)

针对一对一关系,设计表时,有两种方式

(1)把两个实体所有的信息全部都放在一张表里

(2)创建两张表,分别记录用户信息与账户信息,并把这两张表做关联

一对多关系

分别为不同的实体创建表,创建表之后建立表与表之间的关联关系

多对多关系

(1)分别创建实体表

(2)创建关系表,在关系表中为实体表之间创建关联关系

练习:创建班级表,学生表,课程表与成绩表

1.班级表(班级编号,班级名)

2.学生表(学生编号,学号,姓名,年龄,邮件,班级编号)

3.课程表(课程编号,课程名)

4.成绩表(编号,学生编号,课程编号)

班级表与学生表之间是一对多的关系

学生表与课程表之间是多对多的关系,通过一个关系表进行关联

3.使用SQL去创建具体的表

设计表的时候会遵守一些规则,一般我们把这些规则称为三大范式

什么是范式

范式描述的是数据关系的模型,一对一关系,一对多关系,多对多关系

分类:第一范式:1NF,第二范式:2NF,第三范式:3NF

其余范式:BC范式,BCNF

第一范式1NF

关系型数据库的一个基本的要求,不满足第一范式就不可以称为关系型数据库

表里的字段不可再进行拆分

可以继续拆分在关系型数据库中绝对不允许的

在定义表的时候,对照数据中的数据类型每一个字段都可以用一个数据类型表示,那么当前这个表就天然满足第一范式

第二范式2NF

在满足第一范式的基础上,不存在非关键字段对任意候选键的部分函数依赖(存在于复合主键的情况下)

非关键字段:可以理解为非关键字段

候选键:可以理解为主键,外键,没有主键时的唯一值

复合主键:一个表中不能存在两个主键,但是一个主键可以包含多个列(primary key (列名,列名))

对于由两个或多个关键字段决定一条记录的情况

如果一些数据中有些字段只与关键字端中的一个有关系,那么这种就说它只存在部分函数依赖

如果有这样的情况就说明这个表达式不满足第二范式

如果想避免这种情况,可以将表进行拆分,这样设计,每张表都有非关键字段,都强依赖于主键,满足了第二表达式

另外,一个表中没有复合主键(主键只有一列)那么这种的表天然满足第二范式

不满足第二范式可能出现的问题

1.数据冗余

2.更新异常

3.插入异常

4.删除异常

第三范式3NF

在第二范式的基础上,不存在非关键字段,对任一候选键的传递依赖

一张表可以通过外键与另一张表建立关系

第三范式可以解决数据冗余,更新异常,插入异常,删除异常的问题

第一范式将数据不可再分

第二范式消除部分函数依赖

第三范式消除传递依赖

新增

新建一张表,把旧表中的指定列的数据导入到新表中

语法:insert into table_name [(column [, column ....])] select ....

select:要从旧表中查询出来的列

需要把stu中的数据复制到stu1中去

1.一条一条的重新插入一遍

2.把原来的数据导出来,再把表名改一下,再改入到目标表中

3.可以使用insert into select 语句

stu1是目标表

(id,name)表示要插入的列,必须要与要插入的列匹配

stu是原始表

聚合查询

MYSQL中内置的一些函数

COUNT----返回数量

SUM----返回总和

AVG----返回平均值

MAX---返回最大值

MIN---返回最小值

以上操作都是针对某一列进行运算的,之前学的表达式查询,是对一行记录中的列和列之间进行运算,比如:数学成绩+语文成绩+英语成绩

聚合查询是本质是针对数据表中的行和行进行运算

1.COUNT():统计所有的行

*是统计表中的行数,使用常量也可以进行统计,但推荐使用count(*)

count(列名),如果说列表中有null,则不会被统计在内

2.SUM(列名) 求和

示例:计算所有学生的语文成绩的总分

结果在一个临时表中,结果不受表中的字段长度约束

在SUM()求和时,NULL值不参与运算

如果对非数值类型的列进行运算,会得到一些警告信息

3.AVG()

对所有行的指定列进行求平均值运算

1.对所有同学的语文成绩求平均值

2.求语文,数学,英语三门课的总分的平均值

参数可以是表达式,也可以是别名

4.MAX(),MIN()

求所有行中指定的最大值,与最小值

1.找出语文成绩的最高分和英语成绩的最低分

多个聚合函数可以同时使用

2.查找出语文成绩的最高分和最低分

同一列可以使用不同的聚合函数

在使用关于运算的聚合函数时,不拔用在非数值上,比如说sum(),avg(),max(),min()

GROUP BY字句---分组查询

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查 询时,SELECT 指定的字段必须是"分组依据字段",其他字段若想出现在SELECT 中则必须包含在聚合函数中

没有指定的字段,呈现时要通过聚合函数,比如,求和,平均

分组依据字段:要对哪个列进行分组

语法:select column1,sum(column),...from table group by column1,column3;

column1:分组的列名

sum(column2):没有被分组的列(需要运算的列),但是要显示结果,那么就需要用到聚合函数

group by column1,column3:要分组的列

1.计算不同人的平均工资

要分组的列时role列

注意:ROUND(数值,小数点位数)

groby之后可以跟order by子句

HAVING

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用 HAVING

找到对分组之后的结果进行过滤,比如说,找出平均工资大于1万,小于10万的角色

having可以把这个结果集中的数据进行过滤操作,平均工资并不是表中真正数据,而是通过聚合函数计算得出来的

having跟在group by字句之后,对分组结果进行过滤

where是对标中表中每一行的真实数据进行过滤的,having是对group by之后,计算出来的结果进行过滤

如果需求要对真实数据进行过滤,同时需要对分组结果进行过滤,那么在合适的位置写where和having即可

查询每个角色的最高工资,最低工资和平均工资

1.按角色分组

2.使用相应的聚合函数

联合查询

联合多个表进行查询

设计数据时把表进行拆分,为了消除表中的字段的依赖关系,比如部分函数依赖,传递依赖,这时会导致一条SQL语句查出来的数据时不完整的,我们就可以使用联合查询把关系中的数据全部查出来

联合查询时MYSQL是如何执行的

1.去多张表的笛卡尔机

对多张表进行笛卡尔积的过程,

  1. 先从第一张表中取一条记录,然后再与第二张表中的第一条记录进行组合,生成一条新的记录
  2. 先从第一张表中取一条记录,然后再与第二张表中的第二条记录进行组合,生成一条新的记录
    。。。。

最后得到的结果就是一个全排列结果集

语法:select * from 表名,表名;

通过观察,两张表取笛卡尔积之后,有些数据是无效数据

如何过滤这些无效数据?

2.通过连接条件过滤掉无效条件

两个表之间是有主外键关系,只需要判断两个表中的主外键字段是否相等即可

class_id在两张表中都存在,MYSQL分不清当前语句中的class_id应取自哪张表

可以通过表名.列名的方式来解决这个问题

3.能通过指定列查询,来精减结果集

查询列表中通过表名.列名的方式指定要查询的字段

通过给表名起别名的方式来简化SQL语句

联合查询也叫表连接查询

1.首先确定哪几张表要参与查询

2.根据表与表之间的主外键关系,确定过滤关系

3.精减查询字段,得到想要的结果

内连接

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;

select 字段 from 表1, 表2 别名2 where 连接条件 and 其他条件;

(1)查询'许仙'同学的成绩

1.首先确定哪几张表要参与查询

成绩表和学生表

取两张表的笛卡尔积

2.根据表与表之间的主外键关系,确定过滤条件

两张表中通过student_id作为主外键关联字段

确定结果集中的过滤条件

在where条件中,增加student.name='许仙'的过滤条件

3.精减查询类表中的字段

学生名,分数

(2)查询所有同学的总成绩及个人信息

需要使用聚合函数

1.确定要查询的表是学生表和成绩表

总成绩要用分组查询group by

对行与行之间进行运算,使用SUM()进行求和

2.取两张表的笛卡尔积

3.确定两张表之间的关联关系

所有同学成绩的结果集

4.按学生的id进行分组,并在查询列表中,使用聚合函数sum(分数),计算总分

5.在查询列表中精减和确定要查询的列

询步骤细化之后

1.确定查询中涉及到哪些表

2.对目标取笛卡尔积

3.确定连接条件

4.确定对整个结果集的过滤条件

5.精减查询字段

相关推荐
ss2732 小时前
食谱推荐系统功能测试如何写?
java·数据库·spring boot·功能测试
l1t3 小时前
DeepSeek总结的数据库外部表
数据库
m0_674294643 小时前
如何编写SQL存储过程性能对比_记录执行时间评估优化效果
jvm·数据库·python
014-code3 小时前
CompletableFuture 实战模板(超时、组合、异常链处理)
java·数据库
运气好好的3 小时前
怎样开启phpMyAdmin的操作审计日志_记录每条执行的SQL
jvm·数据库·python
それども4 小时前
DELETE 和 TRUNCATE TABLE区别
java·数据库·mysql
wenha4 小时前
数据库隔离级别
数据库·mysql·sqlserver·隔离级别
2401_871492854 小时前
Layui如何修改Layui默认的UI主题颜色(换肤功能实现)
jvm·数据库·python
Edward111111115 小时前
4.27mysql ,数据库,数据源
数据库·mysql
小徐敲java5 小时前
踩坑实录:MySQL8.0 导入SQL报错 2006 - MySQL server has gone away 完美解决
数据库·sql