mysqlDay02

1.DQL核心

1.1 5大聚合函数

# 1.统计学生总数
# 说明:聚合函数统计行记录数使用:count(字段名称)
# 注意事项:count中统计的字段的值如果为null,那么这一行的统计就丢失了;
select count(id) from student3;-- 8
select count(english) from student3;-- 7
# 扩展:如何实现,只要某一行有任意值,就加入统计
# *匹配任意列,只要列存在,那么就加入统计
select count(*) from student3;
# 2.查询年龄大于40的总数
# 说明:如果有条件,那么先进行条件的过滤,然后再聚合统计
select count(*) from student3 where age > 40;
# 3.统计数学成绩总分
select sum(math) from student3;
# 4.一个sql统计出数学成绩最高分和最低分
select max(math) as 最高成绩,min(math) as 最低成绩 from student3;
# 5.统计数学和英语的总成绩
# 分析:方式1:先每列的math+english 然后再sum求和
#       方式2:sum(math)+sum(english)
select sum(math)+sum(english) from student3;-- 1206
# 在myslq中任何值与null进行数学运算,那么结果都为null,而聚合函数对null不处理
select sum(math+english) from student3;-- 1120 差86
# 如何解决?使用ifnull(v1,v2)
select id,name,ifnull(english,'没有成绩') from student3;
select sum(ifnull(math,0)+ifnull(english,0)) from student3;-- 1206
# 6.数学成绩平均分数
select avg(math) from student3;-- 79.5000
select round(avg(math),0) from student3;-- 80
# 四舍五入函数,举例:
# 说明:round中参数1:表示要四舍五入的数,参数2:保留的小数位
select round(12.6735,3);-- 12.674
# 不做四舍五入处理,仅仅数字截取
select truncate(12.6735,3);-- 12.673

1.2 分组查询

1.2 分组查询

# 查询停车场每种颜色车辆的总价
# 分析:1.先根据颜色分组,形成各种颜色的小组  2.在每个小组内使用聚合函数统计各自的车的总金额
# 第一步:统计每种颜色
select color from car group by color;
select distinct color from car
# 第二步:统计每种颜色小组下的总金额
select color,sum(price) from car group by color;

# 2.统计每种颜色的车辆中总金额大于30的颜色对应的总金额信息;
# 语法错误:You have an error in your SQL syntax;
# 结论:where关键字后边不能直接使用聚合函数
select color,sum(price) from car group by color where sum(price)>30;
# Invalid use of group function
select color,sum(price) from car where sum(price)>30 group by color ;
# 如何解决?使用having关键字
select color,sum(price) from car group by color having sum(price)>30;
# having与where区别?
# 1.where后边不能使用聚合函数,但是having可以
# 2.having一般在group by后边使用,但是where一般用于group by之前,做条件的第一道过滤;
# 3.where能用的地方,having都可以用,虽然如何,非必须,使用where关键字;
# 4.因为where查询可以走索引,提高查询效率,但是having不走索引;

# 可以查询到
select id,color from car where id > 4;
select id,color from car having id > 4;
# 可以查询到
select color from car where id > 4;
# 出错:Unknown column 'id' in 'having clause' 推断:having查询基于select后边指点的字段,如果
# 字段没有指定,查询报错
select color from car having id > 4;

where与having区别?

# having与where区别?
# 1.where后边不能使用聚合函数,但是having可以
# 2.having一般在group by后边使用,但是where一般用于group by之前,做条件的第一道过滤;
# 3.where能用的地方,having都可以用,虽然如何,非必须,使用where关键字;
# 4.因为where查询可以走索引,提高查询效率,但是having不走索引;
# 5.使用having查询时,having条件使用的字段必须在select语句中使用;

2.DCL

# 1.创建u1用户,只能在本机登录,不能远程登录,且密码1234'
create user 'u1'@'localhost' identified by '1234';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v3tEhDM7-1628997548998)(img/image-20210814104040849.png)]

# 1.创建u2用户,在任意电脑都可以登录,且密码1234'
# 说明:%匹配任意IP地址或者域名
create user 'u2'@'%' identified by '1234';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cUi9ijTh-1628997549000)(img/image-20210814104321164.png)]

用户授权与撤销权限:

# 3.给u1用户分配对heima01的操作权限,但是不包含对表中数据删除操作
# 说明:之前学习的sql的语句的首个关键字都是权限
# heima01.*:表示指定的权限只能作用在heima01下的所有的表
grant create,alter,insert,update,select on heima01.* to 'u1'@'localhost';
# 4.撤销u1用户的所有权限
revoke create,alter,insert,update,select on heima01.* from 'u1'@'localhost';
# all:关键字,匹配所有权限
revoke all on heima01.* from 'u1'@'localhost';

删除用户和密码修改:

# 1.删除u2 (删除普通用户)
drop user 'u2'@'%';
# 2.修改root超级管理员密码
[root@localhost ~]# mysqladmin -uroot -p123456 password root
# 3.修改普通用户密码 u1 666
set password for 'u1'@'localhost' =password('666');

2.数据库备份与还原

# 1.将数据库db1备份,保存在day02.sql文件下
# 注意:备份时,仅仅备份库中表的信息,数据库的创建语句不备份
[root@localhost ~]# mysqldump -uroot -proot db1 > ./day02.sql
# 2.还原数据到day01
# 注意:还原数据时,数据库需要自己创建
[root@localhost ~]# mysql -uroot -proot day01 < ./day02.sql 

3.约束

3.1 主键约束

# 1.创建表,并指定id主键
create table st1(
	id int primary key,
	name varchar(10),
	age int
);
# 测试 唯一+非空
# 测试唯一
insert into st1 values(1,'zhangsan',18);
# Duplicate entry '1' for key 'PRIMARY'
insert into st1 values(1,'zhangsan2',20);
# 测试非空
# Column 'id' cannot be null
insert into st1 values(null,'zhangsan3',20);
# 2.测试主键自增
create table st2(
	id int primary key auto_increment,
	name varchar(10),
	age int
);
# 插入数据
# 主键递增默认值从1开始
insert into st2 values(null,'zhangsan',18);
# 以此递增
insert into st2 values(null,'zhangsan2',18);
insert into st2 values(10,'zhangsan2',18);
# 主键递增在最大主键值的基础上递增操作,下边操作从11开始
insert into st2 values(null,'zhangsan2',18);

2.唯一约束

# 1.测试唯一约束,name唯一,id主键
create table st3(
	id int primary key auto_increment,
	name varchar(10) unique
);
# 测试
insert into st3 values(null,'zhangsan');
# Duplicate entry 'zhangsan' for key 'name' 虽然插入失败,但是浪费了一次递增
insert into st3 values(null,'zhangsan');
# 测试null,在唯一约束中,对null不处理 null是个例
insert into st3 values(null,null);
insert into st3 values(null,null);

主键约束与唯一+非空约束区别?

# 扩展:联合主键(联合索引)
# 主键只能有一个,但是可以由多个字段组成一个主键-联合主键(id,name)
# 联合主键特点与普通主键一致,也就是有多个字段组成一个主键,所以,多个字段组成的值要唯一
# 比如:primary key(id,name)===>1-马云,如果你再次保存1-马云,报错:Duplicate,同时各个字段
# 不能为null==》null-田七,id不能为null
1.主键约束在表中只能存在一个,但是唯一+非空可以多个;
2.主键约束可以配合主键自增使用,但是唯一+非空不行;
3.主键约束底层维护了主键索引,但是唯一约束底层维护唯一索引;

3.非空约束

# 1.设置name字段未能为null:非空约束
create table st4(
	id int,
	name varchar(10) not null
);
# 测试
# Column 'name' cannot be null
insert into st4 values(1,null);
insert into st4 values(1,'王五');

4.默认值约束

# 设置默认值约束,address默认值上海
create table st5(
	id int,
	name varchar(10) not null,
	address varchar(50) default '上海'
);
# 测试默认值约束
# 如果给值,则使用给定的值
insert into st5 values(1,'zhangsan','北京');
# 直接赋值为null时,不使用默认值
insert into st5 values(1,'zhangsan',null);
# 如果不定义值,那么就使用默认值
insert into st5(id,name) values(2,'lisi');

5.外键约束

​ 外键约束作用:维护多表之间数据的正确,有效,合理性;

# 1.创建程序员表
create table coder(
	id int primary key auto_increment,
	name varchar(10),
	salary double
);
# 2.项目表
create table project(
	id int primary key auto_increment,
	name varchar(10)
);
# 3.创建中间表,简化关系:多对多转一对多
create table coder_project(
	coder_id int,
	project_id int
);
# 插入测试数据
-- 添加测试数据
insert into coder values(1,'张三',12000);
insert into coder values(2,'李四',15000);
insert into coder values(3,'王五',18000);

insert into project values(1,'QQ项目');
insert into project values(2,'微信项目');

insert into coder_project values(1,1);
insert into coder_project values(1,2);
insert into coder_project values(2,1);
insert into coder_project values(2,2);
insert into coder_project values(3,2);
# 如何解决?设置外键约束
truncate table coder;
truncate table coder_project;
# 1.给coder_project中字段coder_id条件外键约束,关联coder表的主键id
alter table coder_project add constraint fk_coder foreign key(coder_id) 
references coder(id);
# 2.给coder_project中字段project_id条件外键约束,关联project表的主键id
alter table coder_project add constraint fk_project foreign key(project_id) 
references project(id);
# 3.测试约束
# 3.1 中间表插入不存在的程序员ID
# Cannot add or update a child row: 
# a foreign key constraint fails (`day02`.`coder_project`, CONSTRAINT 
# `fk_coder` FOREIGN KEY (`coder_id`) REFERENCES `coder` (`id`))
insert into coder_project values(50,2);
# 2.主表删除数据
# Cannot delete or update a parent row: a foreign key constraint fails (`day02`.`coder_project`, CONSTRAINT `fk_coder` 
# FOREIGN KEY (`coder_id`) REFERENCES `coder` (`id`))
delete from coder where id=1;
# 3.主表更新数据
# Cannot delete or update a parent row: a foreign key constraint fails (`day02`.`coder_project`, CONSTRAINT `fk_coder` 
# FOREIGN KEY (`coder_id`) REFERENCES `coder` (`id`))
update coder set id=10 where id=1;
# 4.解决重复插入问题 联合主键:由coder_id和project_id联合组成一个主键,唯一确认表中记录
alter table coder_project add primary key(coder_id,project_id);

级联做演示:

# 5.级联操作
# 1.删除主表
# 先删除中间表,在删除主表
drop table coder_project;
drop table coder;
drop table project;
# 导入数据
# 1.创建程序员表
create table coder(
	id int primary key auto_increment,
	name varchar(10),
	salary double
);
# 2.项目表
create table project(
	id int primary key auto_increment,
	name varchar(10)
);
# 3.创建中间表,简化关系:多对多转一对多
create table coder_project(
	coder_id int,
	project_id int
);
# 插入测试数据
-- 添加测试数据
insert into coder values(1,'张三',12000);
insert into coder values(2,'李四',15000);
insert into coder values(3,'王五',18000);

insert into project values(1,'QQ项目');
insert into project values(2,'微信项目');

insert into coder_project values(1,1);
insert into coder_project values(1,2);
insert into coder_project values(2,1);
insert into coder_project values(2,2);
insert into coder_project values(3,2);
# 添加级联操作
# 1.给coder_project中字段coder_id条件外键约束,关联coder表的主键id
alter table coder_project add constraint fk_coder foreign key(coder_id) 
references coder(id) on update cascade on delete cascade;
# 2.给coder_project中字段project_id条件外键约束,关联project表的主键id
alter table coder_project add constraint fk_project foreign key(project_id) 
references project(id) on update cascade on delete cascade;
# 测试级联删除 特点:删除主表数据时,中间表关联的数据也一并删除
delete from coder where id=1;
# 测试级联更新 特点:主表主键更新时,中间表中关联的字段值也跟着更新
update coder set id=10 where id=2;

6.一对多

# 一对多:作家与小说 关系由多的一方维护:小说
create table author(
	id int primary key,
	name varchar(10)
);
create table book(
	id int primary key,
	name varchar(10),
	author_id int
);
# 添加外键约束
alter table book add constraint fk_author foreign key(author_id) 
references author(id) ;

7.一对一约束

# 一对一:玩家与微信绑定
create table wechat(
	id int primary key,
	name varchar(10)
);

create table player(
	id int primary key,
	name varchar(10),
	wechat_id int
);
# 添加外键约束
alter table player add constraint fk_wechat foreign key(wechat_id) 
references wechat(id);
# 给player中wechat_id添加唯一约束,实现一对一
alter table player add unique(wechat_id);

8.可视化操作约束

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SPjucEzp-1628997549000)(img/image-20210814161921835.png)]

唯一约束操作:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KGSdHJ5N-1628997549000)(img/image-20210814162230046.png)]

外键约束

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LjXRiMWH-1628997549002)(img/image-20210814162651749.png)]

4.多表查询

1.内连接查询

内连接查询特点:都满足条件的才显示;(交集查询)

-- 价格 1
create table price( 
   id int primary key auto_increment,
   price double
);
-- 水果 n
create table fruit(
  id int primary key auto_increment,
  name varchar(20) not null,
  price_id int,
  foreign key(price_id) references price(id)
);
insert into price values(1,2.30);
insert into price values(2,3.50);
insert into price values(4,null);

insert into fruit values(1,'苹果',1);
insert into fruit values(2,'橘子',2);
insert into fruit values(3,'香蕉',null);
-- 一种水果有一个价格 一个价格对应多种水果
-- 价格 1 水果 n 水果将价格主键作为外键

# 查询水果和价格的信息
select * from fruit,price;
# 笛卡尔积过滤:条件过滤
# 隐式内连接
select * from fruit,price where fruit.price_id=price.id;
# 显示内连接
select * from fruit inner join price on fruit.price_id=price.id;
# 练习:查询苹果信息,包含id,name,price
select 
   fruit.id,fruit.name,price.price 
from fruit inner join price 
on fruit.price_id=price.id  and fruit.name='苹果';
# 隐式内连接实现
select 
   fruit.id,fruit.name,price.price 
from fruit,price 
where fruit.price_id=price.id  and fruit.name='苹果';

2.外连接查询

左外特点:左表都显示,右表只显示满足条件的数据;

# 1.无论水果信息是否有关联的price,水果信息都要显示;
select * from fruit left outer join price on fruit.price_id=price.id;

右外特点:右表都显示,左表只显示满足条件的数据;

# 1.无论水果信息是否有关联的price,价格信息都要显示;
select * from price left outer join fruit on fruit.price_id=price.id;
select * from fruit right outer join price on fruit.price_id=price.id;

3.子查询

1.单行单列查询
# 查询工资最高的员工信息
# 薪资最高的员工不一定是一个人,可能是多个
select * from emp order by salary desc limit 1;
# 子查询实现
# 1.查询最高的薪资
select max(salary) from emp;-- 9000
# 错误查询:聚合函数是从多个数据集合中统计出来的,结果集不属于具体某一行记录
select id,name,gender, max(salary) from emp;
# 2.查询薪资等于最高薪资的员工信息
select * from emp where salary=9000;
-- 子查询合并sql
select * from emp where salary=(select max(salary) from emp);

# 需求2:查询工资小于平均工资的人的信息
# 1.获取平均工资
select avg(salary) from emp;-- 5860
# 2.查询小于平均工资值的人的信息
select * from emp where salary < 5860;
-- 合并
select * from emp where salary < (select avg(salary) from emp);
2. 多行单列查询
# 1.查询薪资大于5000的员工都来自哪些部门
# 1.1 连接查询实现
# 分析思路:
# 1.确定需求需要哪些表 2.确定表与表之间的关联关系 3.确定其他条件 4.确定查询的字段
select distinct dept.name  
from dept,emp where emp.dept_id=dept.id and emp.salary > 5000;
# 使用子查询实现
# 在满足业务实现的前提下,优先选择使用连接查询实现
# 分析:
# 1.查询薪资大于5000的员工对应的部门id的集合
select dept_id from emp where salary > 5000;-- 1,2
# 2.使用in关键字在部门表查询在上述集合内的部门的名称
select name from dept where id in(1,2);
# 合并
select name from dept where id in(select dept_id from emp where salary > 5000);
3.多行多列查询
# 1.查询2011入职的员工信息,包含部门名称
# 连接查询实现
# 如果查询中给表去别名,那么原来的名字在select后边不可用
select e.*,d.name from emp as e,dept as d 
where e.dept_id=d.id and e.join_date > '2011-01-01';
# 子查询多行多列实现:
# 1.查询出入职时间在2011之后的员工信息 (多行多列),然后将结果作为一张表与部门表
# 关联查询
select * from emp where join_date > '2011-01-01' as tmp;
# 使用as给查询结果取别名,作为一张表与部门表关联查询

select tmp.*,dept.name 
from (select * from emp where join_date > '2011-01-01') as tmp,dept 
where tmp.dept_id=dept.id;

总结

1.DQL

1.聚合函数==5大聚合函数
	select 聚合函数(字段) from 表;
	最大值:max()
	最小值:min()
	平均值:avg()
	记录数:count()
	亲和:sum()
注意事项:聚合函数对null不处理;  	
2.分组 ===group by 字段 配合聚合函数一块使用
	select 分组字段,聚合函数(字段) fromgroup by 分组字段 having 条件;
  havingwhere区别?
  	1.having后边可以使用聚合函数,但是where不可以;
  	2.having查询不走索引,但是where可以走索引;
  	3.having用于分组之后的条件过滤,但是where一般应用于分组之间的条件过滤;
  	4.having条件中使用的字段必须在select语句中声明
2.限制查询==limit
	select * from 表名 where 条件 limit 索引位,返回的记录数;
	注意事项:1.索引位默认从0开始 ,如果从0开始那么省略不写索引位;
	分页公式:索引位=(当前页-1*每页大小;

2.DCL

1.创建用户
create user '用户名称'@'登录主键名称' identified by '密码';
2.授权
	grant create,insert,... on *.*  to '用户名称'@'登录主键名称';
3.撤销
	revoke create,insert,... on *.*   from '用户名称'@'登录主键名称';
4.删除用户
	drop user '用户名称'@'登录主键名称';

3.多表关系与设计原则

1】关系
1.多对多:程序员与项目、渣男与渣女、用户与角色,从任意一方看,都是一对多;
2.一对多:班级与学生;
3.一对第一:用户与身份证,玩家与微信号
【2】设计原则
多对多:通过设计一张中间表将主表之间多对多的关系,转换成与中间中之间一对多的关系(简化关系)
一对多:由多的一方维护2表的关系;
一对一:任意一方都可以维护,实际情况,根据业务做选择;

4.约束

约束关键字作用
主键约束primary key auto_increment唯一+非空
唯一约束unique 注意:null唯一
非空约束not null约束不能为null
默认值约束default 值如果客户端给声明值,则使用默认;
外键约束add constraint 约束名称 foreign key(字段) references 表(字段)
on update cascade ; on delete cascade;
维护多表之间关系

5. 3大范式

第一范式:表中每一列不能分割;
第二范式:1.满足第一方式 2.消除部分依赖(在联合主键中才能出现)
第三范式:1.满足第二范式 2.先出传递依赖(分类描述---》分类---》商品)

反3范式:

满足3范式的设计,不一定是最最好的设计,因为实际情况要根据具体的业务场景分析;
加入冗余字段,来提高数据库的运行效率,提高查询性能; 用户与订单,在订单中加入用户信息,避免大表联查,提高查询效率;

6.多表查询

1.查询方式:
	表的连接查询
		内连接查询:特点交集查询,只显示都满足条件的数据
			隐式内连接
				select * from t1 ,t2 where 条件;
			显示内连接
				select * from t1 inner join t2 on 条件;
		外连接查询
			左外连接查询:左侧表都显示,右表只显示满足条件的数据
				select * from t1 left join t2 on 条件;
			右外连接查询:右侧表都显示,左表只显示满足条件的数据
			    select * from t1 right join t2 on 条件;
	子查询:一个sql语句嵌套在另一个sql语句内
		单行单列:
			使用比较运算符 eg:select * from student where score =(select max(score) from student);
		多行单列:
			使用in关键字:eg:select * from emp where dept_id in (select id from dept where name in ('财务''开发'))
		多行多列:
			子查询结果多行多列,使用as取别名作为一张表与其他表关联查询;
2.多表查询规则:
	1.确定业务需要哪些表; 2.确定表与表之间的关系(字段之间连接--》外键字段练习)3.确定其他的查询条件
	4.确定需要查询的列信息
			
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值