数据库--MySQL三大范式、多表查询、函数sql

news2024/12/22 17:29:14

数据库相关链接:

数据库基础操作--增删改查:http://t.csdn.cn/189CF

数据库--数据类型:http://t.csdn.cn/NnBsY​​​​​​​

数据库--SQL关键字的执行顺序: http://t.csdn.cn/MoJ4i


一、什么是范式?

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

最常用的三大范式

第一范式(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='销售部' );

列子查询 in any some all

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

在这里插入图片描述

# 列子查询
# 查询销售部和市场部的所有员工信息
# 查询销售部和市场部的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='市场部');
 any(英语:任意的)的使用:

1.查询id>1的所有记录

# 查询id>1的所有记录
SELECT bookID FROM books WHERE bookID>1

 2. 查询id     大于(查询id>1的所有记录) 中的任意一个数据

SELECT * FROM `books` where bookID > ANY(SELECT bookID FROM books WHERE bookID>1)

 

解释:

1步骤子查询中查到结果是id = 2,3,4;   

2步骤查询id,只要大于2,3,4中任意一个即可;

总结:可以理解为“>”大于号时子查询结果中取最小值,“<”小于号时子查询结果中取最大值

行子查询

子查询返回的结果是一行(可以是多列),这种子查询为行子查询
常用操作符:=、<>、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;

四、函数sql语法

1. 常见聚合函数

count(列名) max(列名)//求列中的最大值; min (列名)//求列中的最小值; avg(列名) //平均分 sum(列名) //总分

使用格式:

select count(列名),不统计为null的值; select count ( id ) 总人数 from stu1

2. 其他函数

字符串函数、数学函数、日期函数

字符串函数

1,字符串函数length select length(‘字符串’)[ from dual ] //虚表,为让语法更加清晰;

2,字符个数char_length select length(‘字符串’),char_length(‘哈哈’)

3,大小写转换upper&lower select upper(‘HelloMysql’),lower (‘HelloMysql’)

4,截取字符串subString //没有第0位; select subString(‘你看看从哪里截取,从后面截取’,8)

5,部分截取字符串subString subString (字符串,开始位置,结束位置)

6,替换replace select replace(‘我看看傻帽’,‘傻帽’,‘**’)

数学函数

1,四舍五入round select round( 888.25 ), round( 888.78 )

2,保留小数位round select round(888.235 ,2) //参数2是小数位个数;

3,天花板函数ceil ceil( 88.52 ) //比数字大的 最小整数;

4,地板函数floor floor(88.53) //比数字小的最大整数;

5,取余 select mod( 10,3 )

日期函数

1,将字符串转日期格式 select STR_TO_DATE( ‘2023-02-02’,‘%Y-%m-%d’ )

2,将日期格式转换成字符串 select now( ) //获取当前时间; select date_format( now(),‘%Y-%m-%d’) //获取当前日期;

字符串的拼接concat

eg: select concat( name,address ) from stu3 //合并字符串;

select math+English 总分 from stu3 //做相加运算;

select 100+‘100’ //数字+内容是数字的字符串;

select ‘abc’+ 'aa' //字符串使用+,得到0; select ‘abc’+null //字符串+null ,得到null;

相加运算

//数字的话,是数字的和; //数字+内容是数字的字符串=数字;反过来也可以相加; //字符串+字符串=0; //字符串+null =null; select math+english 总分 from stu3

分组查询group by

对一列数据进行分组,相同的内容分为一组,通常与聚合函数一起使用,完成统计工作;

1,语法格式

select 字段1,字段2 from 表名 [条件] group by 分组字段 [having 条件(对于分组结果的筛选) ] [ order by ];

2,案例

查询男女各多少人 select count(*/id) from stu3 group by sex;

查询年龄大于25岁的人,按照性别分组,统计每组的人数 有条件限制时,where在group by前面; select sex 性别,count(*) from stu3 where age>25 group by sex;

查询年龄大于25岁的人,按照性别分组,统计每组的人数,并只显示性别大于2的数据; select sex 性别,count() from stu3 where age>25 group by sex having count()>2;

分组原理: 对原始表进行抽取,抽取到新的表(临时表),created_tem_tables;

分页查询limit

limit 起始行数从0开始,显示的条数; 显示前三条数据:select * from stu3 limit 0,3; 显示第二页的三条数据:select from stu3 limit 3,3;

总结规律: 第pageSize页数,显示的条数num; limit (pageSize-1)num+num;

博主总结不易,点个赞不过分吧,好耶!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Settings 无障碍设置显示大小页面重复加载问题

基于Android 11&#xff0c;跟踪源码 显示大小页面 packages/apps/Settings/src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java 通过commit() 提交更新页面显示大小。该方法是是在其父类PreviewSeekBarPreferenceFragment 实现调用。 基类预览滑动进度…

Vue-6.创建Vue项目

使用预设默认配置创建Vue项目 创建一个简单的 Vue 项目需要使用 Vue CLI&#xff08;命令行界面&#xff09;。Vue CLI 是一个用于快速构建 Vue.js 项目的工具&#xff0c;它可以帮助你设置项目的基本结构、配置以及开发环境。 以下是创建一个简单的 Vue 项目的步骤&#xff…

机器学习基础之《分类算法(1)—sklearn转换器和估计器》

一、转换器 1、什么是转换器 之前做特征工程的步骤&#xff1a; &#xff08;1&#xff09;第一步就是实例化了一个转换器类&#xff08;Transformer&#xff09; &#xff08;2&#xff09;第二步就是调用fit_transform&#xff0c;进行数据的转换 2、我们把特征工程的接口称…

idea中Maven报错Unable to import maven project: See logs for details问题的解决方法

idea中Maven报错Unable to import maven project: See logs for details问题的解决方法。 在查看maven的环境配置和idea的maven配置后&#xff0c;发现是idea 2020版本和maven 3.9.3版本的兼容性问题。在更改为Idea自带的maven 3.6.1版本后问题解决&#xff0c;能成功下载jar包…

个人对哈希数据结构学习总结 -- 实践篇 -- 上

个人对哈希数据结构学习总结 -- 实践篇 -- 上 引言最佳实践Java篇HashMapgetput扩容 ConcurrentHashMapgetput扩容协作扩容读为什么可以不加锁&#xff1f; ThreadLocalMapgetput扩容delete为什么遍历到null桶就可以判断key不存在&#xff1f;ThreadLocalMap为什么不需要锁&…

【uniapp】picker mode=“region“ 最简单的省市区 三级联动

省市区 picker template <picker mode"region" :value"date" class"u-w-440" change"bindTimeChange"><u--inputborder"bottom"class"u-fb u-f-s-28"placeholder"请选择省市区"type"te…

从零实战SLAM-第八课(非特征点的视觉里程计)

在七月算法报的班&#xff0c;老师讲的蛮好。好记性不如烂笔头&#xff0c;关键内容还是记录一下吧&#xff0c;课程入口&#xff0c;感兴趣的同学可以学习一下。 --------------------------------------------------------------------------------------------------------…

ARM04cortex-A7核LED灯实验

文章目录 一、核心板二、扩展板二、硬件术语2.1 原理图2.2 PCB板2.3 丝印2.4 网络编号 三、分析电路图3.1 思路3.2 总结3.3 工作原理 实验目的&#xff1a;实现LED1/LED2/LED3三盏灯工作 一、核心板 二、扩展板 二、硬件术语 2.1 原理图 原理图是用来描述PCB板子上各个硬件连接…

深入理解epoll

文章目录 概述1. epoll_create - 创建一个epoll实例2. epoll_ctl - 控制epoll实例的事件结构体介绍events取值&#xff1a;data&#xff1a; 联合体&#xff08;共用体&#xff09;&#xff1a; 3. epoll_wait - 等待事件发生伪代码总结 概述 在网络编程中&#xff0c;高效地处…

2023 年牛客多校第九场题解

B Semi-Puzzle: Brain Storm 题意&#xff1a;给定 a , m a,m a,m&#xff0c;构造一个非负整数 u u u&#xff0c;使得 a u ≡ u ( m o d m ) a^u \equiv u \pmod m au≡u(modm)。 1 ≤ a < m ≤ 1 0 9 1 \le a<m \le 10^9 1≤a<m≤109&#xff0c; 0 ≤ u ≤ 1 …

Elasticsearch:如何在 Ubuntu 上安装多个节点的 Elasticsearch 集群 - 8.x

Elasticsearch 是一个强大且可扩展的搜索和分析引擎&#xff0c;可用于索引和搜索大量数据。 Elasticsearch 通常用于集群环境中&#xff0c;以提高性能、提供高可用性并实现数据冗余。 在本文中&#xff0c;我们将讨论如何在 Ubuntu 20.04 上安装和配置具有多节点集群的 Elast…

centos7安装protobuf|序列化和反序列化工具

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总https://blog.csdn.net/yu_cblog/categ…

如何利用视频监控与AI智能识别技术实现铁塔基站机房无人值守?

一、项目背景 很多通信铁塔和机房类项目&#xff0c;都呈现高密度、网格化分布的特点&#xff0c;铁塔基站大多都分布在公路边、高山、野外等区域&#xff0c;巡检难度大&#xff0c;维护效率低&#xff1b;基站设备众多且监控方式单一&#xff0c;而且时刻面临着非法闯入、被…

linux学习(进程替换)[10]

创建子进程 fork()创建子进程进行替换&#xff0c;不影响父进程&#xff0c;父进程聚焦在&#xff1a;读取数据、解析数据、指派进程、执行代码的功能。 子进程发生替换后的数据 在加载新程序进去之前&#xff0c;父子之间的的代码是共享的&#xff0c;数据写时拷贝进子进程…

Webshell实例分析解析

Webshell的实例分析 LD_PRELOAD的劫持在 web 环境中实现基于 LD_PRELOAD 的 RCE 命令执行利用 mail 函数启动新进程 绕过不含字母和数字的Webshell异或取反 LD_PRELOAD的劫持 LD_PRELOAD是Linux/Unix系统的一个环境变量&#xff0c;它影响程序的运行时的链接&#xff08;Runti…

ATF bl1 ufshc_dme_get/set处理流程分析

ATF bl1 ufshc_dme_get/set处理流程分析 UFS术语缩略词1 ATF的下载链接2 ATF BL1 ufshc_dme_get/set流程3 ufs总体架构图3.1 UFS Top Level Architecture3.2 UFS System Model 4 ufshc_dme_get/set函数接口详细分析4.1 ufshc_dme_get4.2 ufshc_dme_set4.3 ufshc_send_uic_cmd4.…

Visual Studio 如何放大代码字体的大小

1.打开Visual Studio&#xff0c;新建一个程序&#xff0c;一段代码&#xff0c;为接下去的操作做好准备。单击菜单栏的【工具】选项。 2.在跳出来菜单中找到【选项】&#xff08;一般在最后一项&#xff09;&#xff0c;然后单击。跳出新的窗口。 3.跳出新的窗口后&#xff…

SPI-FlexSPI

概念 SPI 高速全双工通信总线 SPI有四根线&#xff1a; SDO&#xff1a;数据输出-主设备数据输出&#xff0c;从设备数据输入 SDI:数据输入-主设备数据输入&#xff0c;从设备数据输出 SCLK&#xff1a;时钟信号-由主设备产生 CS&#xff1a;片选信号&#xff0c;主设备…

打家劫舍 II——力扣213

动规 int robrange(vector<int>& nums, int start, int end){int first=nums[start]

Python程序设计——字符串处理的特殊方法

学习目标&#xff1a; 学习如何创建字符串使用len、min和max函数获取一个字符串的长度、串中的最大和最小的字符使用下标运算符([])访问字符串中的元素使用截取运算符str[ start:end]从较长的字符串中得到一个子串使用运算符连接两个字符串&#xff0c;通过*运算符复制一个字符…