数据库--MySQL

一、什么是范式?

范式是数据库设计时遵循的一种规范,不同的规范要求遵循不同的范式。

最常用的三大范式

第一范式(1NF):属性不可分割,即每个属性都是不可分割的原子项。(实体的属性即表中的列)

第二范式(2NF):满足第一范式;且不存在部分依赖,即非主属性必须完全依赖于主属性。(主属性即主键;完全依赖是针对于联合主键的情况,非主键列不能只依赖于主键的一部分)

第三范式(3NF):满足第二范式;且不存在传递依赖,即非主属性不能与非主属性之间有依赖关系,非主属性必须直接依赖于主属性,不能间接依赖主属性。(A -> B, B ->C, A -> C)

举例说明3NF:

1NF

属性不可再分,即表中的每个列都不可以再进行拆分。

如下学生信息表(student):

id、name(姓名)、sex_code(性别代号)、sex_desc(性别描述)、contact(联系方式)

primary key(id)

idnamesex_codesex_desccontact
001张三017835201234_山西省运城市xx村
002李四017735204567_山西省吕梁市yy村
003王五118835207890_山西省太原市zz村

如果在查询学生表时经常用到学生的电话号,则应该将联系方式(contact)这一列分为电话号(phone)和地址(address)两列,这样才符合第一范式。

修改使表满足1NF后:

idnamesex_codesex_descphoneaddress
001张三017835201234山西省运城市xx村
002李四017735204567山西省吕梁市yy村
003王五118835207890山西省太原市zz村

 判断表是否符合第一范式,列是否可以再分,得看需求,如果将电话号和地址分开才能满足查询等需求时,那之前的表设计就是不满足1NF的,如果电话号和地址拼接作为一个字段也可以满足查询、存储等需求时,那它就满足1NF。

2NF

在满足1NF的前提下,表中不存在部分依赖,非主键列要完全依赖于主键。(主要是说在联合主键的情况下,非主键列不能只依赖于主键的一部分)

如下学生成绩表(score):

stu_id(学生id)、kc_id(课程id)、score(分数)、kc_name(课程名)

primary key(stu_id, kc_id)

stu_idkc_idscorekc_name
001101185高数3-1
001102279计算机组成原理
002101159.9高数3-1

表中主键为stu_id和kc_id组成的联合主键。满足1NF;非主键列score完全依赖于主键,stu_id和kc_id两个值才能决定score的值;而kc_name只依赖于kc_id,与stu_id没有依赖关系,它不完全依赖于主键,只依赖于主键的一部分,不符合2NF。

修改使表满足2NF后:

成绩表(score)   primary key(stu_id)

stu_idkc_idscore
001101185
001102279
002101159.9

课程表(kc)   primary key(kc_id)

kc_idkc_name
1011高数3-1
1022计算机组成原理

将原来的成绩表(score)拆分为成绩表(score)和课程表(kc),而且两个表都符合2NF。

3NF:

在满足2NF的前提下,不存在传递依赖。(A -> B, B -> C, A->C)

如下学生信息表(student):

primary key(id)

idnamesex_codesex_descphoneaddress
001张三017835201234山西省运城市xx村
002李四017735204567山西省吕梁市yy村
003王五118835207890山西省太原市zz村

表中sex_desc依赖于sex_code,而sex_code依赖于id(主键),从而推出sex_desc依赖于id(主键);sex_desc不直接依赖于主键,而是通过依赖于非主键列而依赖于主键,属于传递依赖,不符合3NF。

修改表使满足3NF后:

学生表(student)   primary key(id)

idnamesex_codephoneaddress
001张三017835201234山西省运城市xx村
002李四017735204567山西省吕梁市yy村
003王五118835207890山西省太原市zz村

性别代码表(sexcode)   primary key(sex_code)

sex_codesex_desc
0
1

将原来的student表进行拆分后,两个表都满足3NF。

什么样的表越容易符合3NF?

非主键列越少的表。(1NF强调列不可再分;2NF和3NF强调非主属性列和主属性列之间的关系)

如代码表(sexcode),非主键列只有一个sex_desc;

或者将学生表的主键设计为primary key(id,name,sex_code,phone),这样非主键列只有address,更容易符合3NF。


二、多表关系

在进行数据库表结构的设计时,会根据业务的需求和业务模块之间的关系,分析设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系

表与表之间的联系:

1.一对多(多对一)
2.多对多
3.一对一

一对多(多对一)

例如,一个员工对应一个部门,一个部门可以对应多个员工

在这里插入图片描述

一般在多的一方创建外键,指向一的那一方
员工与部门,在员工表上设置外键,指向部门表

多对多

例如,一个学生可以选修多门课程,一个课程可以被多名学生选修
一般会建立第三张表,至少包含两个外键,分别指向两张表的主键

在这里插入图片描述

一对一

例如,用户和自己的学历信息的关系,一个人只对应一条学历信息
可以在任意一方加入外键,关联另一方的主键,并且设置外键为唯一(unique)

 在这里插入图片描述

 注:可以放在一张表中,但是对其进行拆分,一张表放基础信息,另一张表放详情,可以提升操作效率


三、多表查询

概述:
从多张表中查询数据
笛卡尔积:
笛卡尔积为两个集合(两张表)中的每条数据进行两两组合的结果
在多表查询时会产生笛卡尔积,要通过添加条件消除笛卡尔积

在这里插入图片描述

 dept表:

请添加图片描述

 emp表:

请添加图片描述

查询产生笛卡尔积的结果:

select * from emp, dept ;

请添加图片描述

 消除笛卡尔积(添加条件):

select * from emp, dept where emp.dept_id=dept.id;

请添加图片描述

多表查询的分类

1.连接查询:

内连接:相当于查询AB的交集部分
外连接:左外连接:查询A的所有数据,同时拼接上B对应的数据右外连接:查询B的所有数据,同时拼接上A中对应的数据
自连接:表与自身连接查询自连接必须给表取别名

在这里插入图片描述

2.子查询

数据准备

部门表:

create table dept (id int auto_increment primary key comment 'id',name varchar(50) not null comment '部门名称'
) comment '部门表';insert into dept (id, name)
values (1, '研发部'),(2, '市场部'),(3, '财务部'),(4, '销售部'),(5, '总经办'),(6, '人事部');

员工表:

create table emp(id int auto_increment primary key ,name varchar(50) not null ,age int,job varchar(20) comment '职位',salary int ,entrydate date comment '入职时间',managerid int comment '直属领导id',dept_id int comment '所在部门id'
) comment '员工表';insert into emp
values ( 1, '金庸', 66, '总裁', 20000, '2000-01-01', null, 5 ),( 2, '张无忌', 20, '项目经理', 12500, '2005-12-05', 1, 1 ),( 3, '杨晓', 33, '开发', 8400, '2000-11-03', 2, 1 ),( 4, '韦一笑', 48, '开发', 11000, '2002-02-05', 2, 1 ),( 5, '陈玉存', 43, '开发', 10500, '2004-09-07', 3, 1 ),( 6, '小昭', 19, '程序员鼓励师', 6600, '2004-10-12', 2, 1 ),( 7, '灭绝', 60, '财务总监', 8500, '2002-09-12', 1, 3 ),( 8, '周芷若', 19, '会计', 48000, '2006-06-02', 7, 3 ),( 9, '丁敏君', 23, '出纳', 5250, '2009-05-13', 7, 3 ),( 10, '赵敏', 20, '市场部总监', 12500, '2004-10-12', 1, 2 ),( 11, '鹿杖客', 56, '职员', 3750, '2006-10-03', 10, 2 ),( 12, '何碧文', 19, '职员', 3750, '2007-05-09', 10, 2 ),( 13, '东方白', 19, '职员', 5500, '2009-02-12', 10, 2 ),( 14, '张三丰', 88, '销售总监', 14000, '2004-10-12', 1, 4 ),( 15, '鱼梁洲', 38, '销售', 4600, '2004-10-12', 14, 4 ),( 16, '宋远桥', 40, '销售', 4600, '2004-10-12', 14, 4 ),( 17, '陈友谅', 42, null, 2000, '2011-10-12', 1, null );

内连接

语法:

# 隐式内连接
select 字段列表 from 表1,表2 where 条件;
# 显示内连接
select 字段列表 from 表1 [inner] join 表2 on 连接条件;

内连接查询的是两张表交集的部分

# 查询每一个员工的姓名及关联的部门的名称
select emp.name, dept.name from emp, dept where emp.dept_id=dept.id;
select emp.name, dept.name from emp inner join dept on emp.dept_id = dept.id;

外连接

语法:

# 左外连接
select 字段列表 from 表1 left [outer] join 表2 on 条件;
# 右外连接
select 字段列表 from 表1 right [outer] join 表2 on 条件;

左外连接相当于查询表1的所有数据包含表1和表2交集的部分数据
右外连接相当于查询表2的所有数据包含表1和表2交集部分的数据

# 查询emp表的所有数据,和应于的部门信息(左)
select emp.*, dept.* from emp left outer join dept on emp.dept_id = dept.id;
# 查询dept表的所有数据,和对于的员工信息(右)
select dept.*, emp.* from emp right outer join dept on emp.dept_id = dept.id;

左外连接和右外连接可以进行相互转化

自连接

语法:

select 字段列表 from 表a 别名a join 表a 别名b on 条件;

自链接查询可以是内连接查询也可以是外连接查询

# 查询员工及其所属领导的名字
# 自连接可以看成两张一样的表进行连接查询
select a.name, b.name from emp a join emp b on a.managerid=b.id;

联合查询

union、union all
对于联合查询就是把多次查询的结果合并起来,形成一个新的查询结果集
语法:

select 字段列表 from 表a
union [all]
select 字段列表 from 表b
# 将薪资低于5000的员工和年龄大于50的员工查询出来
select * from emp where salary>5000
union all
select * from emp where age>50;
# 没有all重复满足条件的只出现一次
# 将薪资低于5000的员工和年龄大于50的员工查询出来
select * from emp where salary>5000
union
select * from emp where age>50;

对于联合查询的多张表的列数必须保持一致,字段类型也要保持一致
union all会将全部的数据直接合并在一起,union会对合并之后的数据去重

子查询

概念:SQL语句中嵌套select语句为嵌套查询,又称子查询
select * from 表1 where 字段=(select 字段 from 表2);
子查询外的语句可以是insert、update、delete、select中的一个
根据子查询的结构不同,分为:

标量子查询:子查询的结果为单个值
列子查询:子查询的结果为一列
行子查询:子查询的结果为一行
表子查询:子查询的结果为多行多列

根据子查询的位置,分为:

where之后
from之后
select之后

标量子查询

子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询
常用符号:=、<>、>、>=、<、<=

# 根据销售部门的id查询员工信息
# 先分开查询
# 查询销售部门的id
select id from dept where name='销售部'; #id为4
# 查询销售部门中员工的信息
select * from emp where dept_id=4;
# 合并为一个查询
select * from emp where dept_id=(select dept.id from dept where dept.name='销售部' );

列子查询

子查询的结果为一列(可以是多行)的,这种子查询为列子查询
常用操作符:

在这里插入图片描述

# 列子查询
# 查询销售部和市场部的所有员工信息
# 查询销售部和市场部的id
select id from dept where name='销售部' or name='市场部'; #id为2 4
# 查询两个部门的所有员工
select * from emp where dept_id in (2,4);
# 合并
select * from emp where dept_id in (select id from dept where name='销售部' or name='市场部');

行子查询

子查询返回的结果是一行(可以是多列),这种子查询为行子查询
常用操作符:=、<>、in、not in

# 查询与张无忌的薪资及直属领导相同的员工信息
# 查询张无忌的薪资和直属领导
select salary, managerid from emp where name='张无忌';
# 查询与张无忌的薪资及直属领导相同的员工信息
select * from emp where (salary,managerid)=(select salary, managerid from emp where name='张无忌');

表子查询

子查询的结果是多行多列这种查询为表子查询
常用操作符:in

# 查询与鹿杖客和宋远桥的职位和薪资相同的员工信息
select * from emp where (job, salary) in ( select job, salary from emp where name in ('鹿杖客', '宋远桥'));

表子查询的子表作为临时表

# 查询入职日期是’2006-01-01‘之后的员工信息和部门信息
# 先查询出入职在’2006-01-01‘之后员工的所有信息
# 与部门表左连接
select e.*, dept.* from (select * from emp where entrydate>'2006-01-01') e left outer join dept on e.dept_id=dept.id;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/62696.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统搭建相关知识

系统篇 systemctl命令 常用于重启系统的每个服务&#xff0c;例如重启系统的网络&#xff0c;使用restart参数!!! 网络篇 ifconfig命令 注意&#xff1a;如果有过多块网卡&#xff0c;例如&#xff1a;eth0和eth1网卡&#xff0c;一般查看那个参数上面带有RUNNING和UP网卡开…

TFRecords详解

内容目录 TFRecords 是什么序列化(Serialization)tf.data 图像序列化&#xff08;Serializing Images)tf.Example函数封装 小结 TFRecords 是什么 TPU拥有八个核心&#xff0c;充当八个独立的工作单元。我们可以通过将数据集分成多个文件或分片&#xff08;shards&#xff09;…

Flutter父宽度自适应子控件的宽度

需求&#xff1a; 控件随着金币进行自适应宽度 image.png 步骤&#xff1a; 1、Container不设置宽度&#xff0c;需要设置约束padding&#xff1b; 2、文本使用Flexible形式&#xff1b; Container(height: 24.dp,padding: EdgeInsetsDirectional.only(start: 8.dp, end: 5.d…

文档控件DevExpress Office File API v23.1新版亮点 - 支持.NET MAUI

DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库&#xff0c;不用安装Microsoft Office&#xff0c;就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…

web后端解决跨域问题

目录 什么是跨域问题 为什么限制访问 解决 什么是跨域问题 域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。但是一般情况下不能这么做&#xff0c;它是由浏览器的同源策略造成的&#xff0c;是浏览器对js施加的安全…

springboot文件上传和下载接口的简单思路

springboot文件上传和下载的简单思路 文件上传文件下载 文件上传 在springboot中&#xff0c;上传文件只需要在接口中通过 MultipartFile 对象来获取前端传递的数据&#xff0c;然后将数据存储&#xff0c;并且返回一个对外访问路径即可。一般对于上传文件的文件名&#xff0c…

C语言 冒泡排序

目录 一、原理 二、代码演示 三、代码优化 一、原理 假设&#xff1a; int arr[] { 9,8,7,6,5,4,3,2,1,0 }; 将 arr 内的元素进行升序排列&#xff0c;得到一个新的数组 int arr[] { 0&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;…

【HTML】<input>

分类 text password number button reset submit hidden radio checkbox file image color range tel email&#xff08;火狐有校验&#xff0c;360浏览器无校验。&#xff09; url datetime&#xff08;火狐、360浏览器不支持&#xff09; search date、month、week、time、da…

自动测试框架airtest应用一:将XX读书书籍保存为PDF

一、Airtest的简介 Airtest是网易出品的一款基于图像识别和poco控件识别的一款UI自动化测试工具。Airtest的框架是网易团队自己开发的一个图像识别框架&#xff0c;这个框架的祖宗就是一种新颖的图形脚本语言Sikuli。Sikuli这个框架的原理是这样的&#xff0c;计算机用户不需要…

prometheus监控k8s服务并告警到钉钉

一、监控k8s集群 要监控k8s集群需要使用到以下服务用于收集监控的资源信息&#xff0c;node_exporter用于监控k8s集群节点的资源信息&#xff0c;kube-state-metrics用于监控k8s集群的deployment、statefulset、daemonset、pod等的状态&#xff0c;cadvisor用于监控k8s集群的p…

anaconda 基本指令

1.anaconda添加源 这两行命令分别添加了清华Anaconda 仓库的 main 和 free 镜像源。 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/2.anac…

Xcode 基座打包

Xcode基座打包-APP更新版本内容无效 问题&#xff1a;解决&#xff1a; 问题&#xff1a; 使用xcode基座打包之后&#xff0c;上传到appstore进行提审发布。 用户在appstore商城进行更新下载&#xff0c;打开更新后的APP发现版本号是最新的&#xff0c;APP里面的其他内容还是上…