MySQL数据库三

1.2 多表查询

1.2.1 内连接

规则:返回两个表的公共记录
语法:

--语法一
select * from 表1 inner join 表2 on 表1.公共字段=表2.公共字段
--语法二
select * from 表1,表2 where 表1.公共字段=表2.公共字段

例题:

-- inner join
select * from  stuinfo inner join stumarks on  stuinfo.stuno=stumarks.stuno;

--相同的字段只显示一次
mysql>select s.stuno,stuname,stusex,writtenexam,labexam from stuinfo s  inner join stumarks m on s.stuno=m.stuno;

--使用where
select * from stuinfo,stumarks where stuinfo.stuno=stumarks.stuno;

多学一招:

1、内连接中inner可以省略
select * from 表1 join 表2 on 表1.公共字段=表2.公共字段

--如何实现三表查询
select * from 表1 inner join 表2 on 表1.公共字段=表2.公共字段 inner join 表3 on 表2.公共字段=表3.公共字段

--连接越多,效率越低

思考:

select * from 表1 inner join 表2 on 表1.公共字段=表2.公共字段
和
select * from 表2 inner join 表1 on 表1.公共字段=表2.公共字段  一样吗?
答:一样的

1.2.2 左外连接

规则:以左边的表为准,右边如果没有对应的记录用null显示
语法:

select * from 表1 left join 表2 on  表1.公共字段=表2.公共字段

例题:

select stuname,writtenexam,labexam from stuinfo left join stumarks on stuinfo.stuno=stumarks.stuno;

思考:

select * from 表1 left join 表2 on 表1.公共字段=表2.公共字段 和
select * from 表2 left join 表1 on 表1.公共字段=表2.公共字段 一样吗?
答:不一样,第一个SQL以表1为准,第二个SQL以表2为准

1.2.3 右外连接

规则:以右边的表为准,左边没有对应的记录用null显示
语法:

select * from 表1 right join 表2 on  表1.公共字段=表2.公共字段

例题:

select stuname,writtenexam,labexam from stuinfo right join stumarks on stuinfo.stuno=stumarks.stuno;

思考:
思考:

select * from 表1 left join 表2 on 表1.公共字段=表2.公共字段 和
select * from 表2 right join 表1 on 表1.公共字段=表2.公共字段 一样吗?
答:一样,都是以表一为准

1.2.4 交叉连接

语法:返回笛卡尔积

select * from 表1 cross join 表2

例题:

--交叉连接
select * from stuinfo cross join stumarks;
--交叉连接有连接表达式与内连接是一样的
select * from stuinfo cross join stumarks on stuinfo.stuno=stumarks.stuno;

小结:
1、交叉连接如果没有连接条件返回笛卡尔积
2、如果有连接条件和内连接是一样的

1.2.5 自然连接

自动判断条件连接,判断的条件是依据同名字段
1、自然内连接(natural join)

select * from stuinfo natural join stumarks;

2、自然左外连接(natural left join)

select * from stuinfo natural left join stumarks;

3、自然右外连接(natural right join )

select * from stuinfo natural right join stumarks;

小结:
1、表连接是通过同名字段来连接的
2、如果没有同名字字段就返回笛卡尔积
3、同名的连接字段只显示一个,并且将该字段放在最前面

1.2.6 using

using用来指定连接字段

select * from stuinfo inner join stumarks using(stuno);

using的结果也会对公共字段进行优化,优化的规则和自然连接是一样的

1.2.7 练习

1、显示地区及每个地区参加笔试的人数,并按人数降序排列

--第一步:显示地区及每个地区参加笔试的人数
select stuaddress,count(writtenexam) from stuinfo left join stumarks using(stuno) group by stuaddress;
-- 第二步:将结果降序排列
select stuaddress,count(writtenexam) c from stuinfo left join stumarks using(stuno) group by stuaddress order by c desc;

2、显示有学生参加考试的地区


-- 表连接实现
--第一步:右连接获取有成绩的地区
select stuaddress from stuinfo right join stumarks using(stuno);
-- 第二步:去重复
select distinct stuaddress from stuinfo right join stumarks using(stuno);
--去除null
select distinct stuaddress from stuinfo right join stumarks using(stuno) having stuaddress is not null;

3、显示男生和女生的人数

select stusex,count(*) from stuinfo group by stusex;
--方法二:union
select stusex,count(*) from stuinfo where stusex='男' union select stusex,count(*) from stuinfo where stusex='女';
--方法三:直接写条件
select sum(stusex='男') 男,sum(stusex='女') 女 from stuinfo;

4、显示每个地区男生、女生、总人数

select stuaddress,count(*) 总人数,sum(stusex='男') 男,sum(stusex='女') 女 from stuinfo group by stuaddress;

1.3 子查询

语法:select * from 表1 where (子查询)
外面的查询称为父查询
子查询为父查询提供查询条件

1.3.1 标量子查询

特点:子查询返回的值是一列

--查询笔试成绩是80的学生
select * from stuinfo where stuno=(select stuno from stumarks where writtenexam=80);

-- 查找最高分的学生
--方法一
select * from stuinfo where stuno=(select stuno from stumarks order by writtenexam desc limit 1);
--方法二
select * from stuinfo where stuno=(select stuno from stumarks where writtenexam=(select max(writtenexam) from stumarks))

1.3.2 列子查询

特点:子查询返回的结果是一列

如果子查询的结果返回多条记录,不能使用等于,用in 或not in

--查询及格的同学
select * from stuinfo where stuno in (select stuno from stumarks where writtenexam>=60);
--查询不及格的同学
select * from stuinfo where stuno in (select stuno from stumarks where writtenexam>=60);
--查询需要补考的学生
select * from stuinfo where stuno not in (select stuno from stumarks where writtenexam>=60);

1.3.3 行子查询

特点:子查询返回的结果是多个字段组成

--查找语文成绩最高的男生和女生
select * from stu where(stusex,ch) in (select stusex,max(ch) from stu group by stusex);

注意:form 后面跟的是数据源,如果将子查询当成表来看,必须给结果集取别名

1.3.5 exists子查询

--如果笔试成绩有人超过80人,就是显示所有学生信息
select * from stuinfo where exists(select * from sumarks where writtenexam>=80);
--没有超过80的学生,就显示所有学生信息
select * from stuinfo where not exists(select * from stumarks where writtenexam>=80);

作用:提高查询效率

1.4 视图

1.4.1 概述

1、视图是一张虚拟表,它表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上
2、视图中并不存放数据,而是存放在视图所引用的原始表(基表)中
3、同一张原始表,根据不同用户的不同需求。可以创建不同的视图

1.4.2 作用

1、筛选表中的行
2、防止未经许可的用户访问敏感数据
3、增加数据的兼容性(数据库的字段名发生变化,程序可以不用改字段名)
4、隐藏数据表的结构
5、降低数据库的复杂度

1.4.3 创建视图

语法:

--创建视图
create[ or replace] view 视图名
as
	select 语句;
--查询视图
select 列名 from 视图

例题:

--创建视图
create view view1
as
select * from stu where ch>=60 and math>=60;

--查询视图
select * from view1;

--视图可以降低SQL语句的复杂度
create view view2
as 
select stuno,stusex,writtenexam,labexam from stuinfo natural join stumarks;

1.4.4 修改视图

语法

alter view 视图名
as
	select 语句

例题:

alter view view2
as
select stuname from stuinfo;

1.4.5 删除视图

drop view view2;

1.4.6 查看视图信息

show tables; --显示所有的表和视图

--方法二:精确查找视图(视图信息存储在information_schema下的views表中)
select table_name from information_schema.views;

--方法三:通过表的comment属性查询视图
show table status where comment='view'\G; --查询表和视图的详细状态信息
show table status where comment='view'\G; --只查找视图信息

查询视图的结构

desc view1;

查询创建视图的语法

show create view view1\G

1.4.7 视图算法

场景:找出语文成绩最高的男生和女生
方法一:

select * from (select * from stu order by ch desc) t group by stusex;

方法二:

create view view3
as
select * from stu order by ch desc;

select * from view3 group by stusex;

结论:方法一和方法二的结果不一样,这是因为视图的算法造成的

视图的算法有:
1、merge:合并算法(将视图语句和外层语句合并后再执行)
2、temptable:临时表算法(将视图作为一个临时表来执行)
3、undefined:未定义算法(用哪种算法有MySQL决定,这是默认算法,视图一般会选merge算法)

重新通过视图实现

创建视图,指定算法为临时表算法
create or replace algorithm=temptable view view3
as
select * from stu order by ch desc;

select * from view3 group by stusex;

结论:和子查询结果一致。

1.5 事务

1.5.1 概述

1、事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作。是一个整体,要么一起执行,要么一起不执行。
2、这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行
3、事务是一个不可分隔的工作逻辑单元

1.5.2 事务特性

事务必须具备以下四个属性,简称ACID属性:
原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。
一致性(Consistency):当事务完成时,数据必须处于一致状态。
隔离性(lsolation):对数据进行修改的所有并发事务是彼此隔离的。
永久性(Durability):事务完成后,它对数据库的修改被永久保持。

1.5.3 事务处理

开启事务

提交事务

回滚事务

rollback

例题:

--插入测试数据
create table bank(
		card char(4) primary key comment '卡号',
		money decimal(10,2) not null
		engine=innodb charset=utf8;

insert into bank values('1001',1000),('1002',1);

--开启事务
begin;

delimiter // --更改定界符

update bank set money=money-100 wher card='1001';
update bank set money=money+100 where card ='1002' //

--回滚事务
rollback//

select * from bank//
card  money
1001   1000.00
1002    1.00
-------------------------------------------------------------
--开启事务
start transaction //

update bank set money=money-100 wher card='1001';
update bank set money=money+100 where card ='1002' //

--提交事务
commit//

select * from bank//
card   money
1001   900.00
1002   101.00

设置事务的回滚点

begin//

insert into bank values ('1003',500) //

--记录事务回滚点
savepoint a1 //

insert into bank values ('1004',200) //

--回滚到回滚点a1
rollback to a1//

select * from bank//

card money
1001  900.00
1002  101.00
1003   500.00

自动提交事务

每一个SQL语句都是一个独立的事务

小结:
1、事务是事务开启的时候开启
2、提交事务、回滚事务后事务都结束
3、只有innodb支持事务
4、一个SQL语句就是一个独立的事务,开启事务是将多个SQL语句放到一个事务中执行

1.6 索引

1.6.1 概述

优点:

加快查询速度

缺点:

带索引的表在数据库中需要更多的存储空间
(增、删、改)操作数据库的命令需要更长的处理时间,因为它们需要对索引进行更新

1.6.2 创建索引的指导原则

适合创建索引的列

1、该列用于频繁搜索
2、该列用于对数据进行排序
3、在WHERE子句中出现的列,在join子句中出现的列。

请不要使用下面的列创建索引:

1、列中仅包含几个不同的值
2、表中仅包含几行,为小型表创建索引可能不太划算,因为MySQL中在索引中搜索数据所花的时间比在表中逐行搜索花的时间更长

1.6.3 创建索引

1、主键索引:主要创建了主键就会自动的创建主键索引

2、唯一索引:创建唯一键就创建了唯一索引

--创建表的时候添加唯一索引
create table t4(
id int primary key,
name varchar(20),
unique ix_name(name) --添加唯一索引
);

-- 给表添加唯一索引
create table t5(
name varchar(20),
addr varchar(50)
);

create unique index ix_name on t5(name);

-- 通过更改表的方式创建唯一索引
create unique index ix_name on t5(name);

普通索引

--创建表的时候添加普通索引
create table t6(
id int primary key,
name varchar(20),
index ix_name(name)
);

--给表添加普通索引
create table t7(
name varchar(20),
add varchar(50)
);

create index ix_name on t7(name);

-- 通过更改表的方式创建索引
alter table t7 add index ix_addr(addr);

多列索引

小结:
1、创建主键就会创建主键索引
2、创建唯一键就会创建唯一索引
3、创建唯一键的语法

--语法一
create unique [index] 索引名 on 表名(字段名)
--语法二
alter table 表名 add unique [index] 索引名(字段名)

4、创建普通索引

--语法一
create index 索引名 on 表名(字段名)
--语法二
alter table 表名 add index 索引名(字段名)

5、索引创建后,数据库根据查询语句自动选择索引

1.6.4 删除索引

语法:drop index 索引名 on 表名

drop index ix_name on t7;

1.7 函数

1.7.1 数字类

-- 获取随机数
select rand();

--随机排序
select * from stuinfo order by rand();

--随机获取一条记录
select * from stuinfo order by rand() limit 1;

--四舍五入,向上取整,向下取整
select round(3.1415926,3) '四舍五入',truncate(3.14159,3) '截取数据',ceil(3.1) '向上取整',floor(3.9) '向下取整';

注意:截取数据直接截取,不四舍五入

1.7.2 字符串类

-- 大小写转换
select ucase('i name is tom') '转成大写',lcase('My Name IS TOM') '转成小写';
转成大写          转成小写
I NAME IS TOM    my name is tom

--截取字符串
select left ('abcdef',3) '从左边截取',right('abcdef',3) '从右边截取',substring('abcdef',2,3) '字符串';
从左边截取		从右边截取		字符串
abc  				def					bcd

--字符串相连
select concat('中国','北京','顺义') '地址'
地址
中国北京顺义

select concat(stuname,'-',stusex) 信息 from stuinfo;
```mysql
信息
张秋丽-男
李文才-女
...

-- coalesce(str1,str2) :str1有值显示str1,如果str1为空就显示str2
-- 将成绩为空的显示为缺考
select stuname,coalesce(writttenexam,'缺考'),coalesce(labexam,'缺考') from stuinfo natural left join stumarks;	

stuname      coalesce(writtenexam,'缺考')    coalesce(labexam,'缺考') 
张秋丽				77												82
王无					缺考													66
张飞					66												缺考

-- length():字节长度,char_length():字符长度
select length('锄禾日当午') 字节,char_length('锄禾日当午') 字符;
字节			字符
10			5

1.7.3 时间类

--时间戳
select unix_timestamp();

--格式化时间戳
select from_unixtime(unix_timestamp());

--获取当前格式化时间
select now();

--获取年、月、日、小时、分钟、秒
select year(now()) 年,month(now()) 月,day(now()) 日,hour(now()) 小时,minute(now()) 分钟,second(now())秒;

--星期,本年第几天
select dayname(now()) 星期,dayofyear(now())  本年第几天;

--日期相减
select datediff(now(),'2010-08-08') 相距天数;

1.7.4 加密函数

1、md5()
2、sha()

select md5('aa');

select sha('aa');

1.8 预处理

预编译一次,可以执行多次。用来解决一条SQL语句频繁执行的问题。

预处理语句:prepare 预处理名字 from 'sql语句'
执行处理语句:execute 预处理名字 [using 变量]

例题:不带参数的预处理

--创建预处理
prepare stmt from 'select * from stuinfo';

--执行预处理
execute stmt;

例题:带一个参数的预处理

--创建预处理
prepare stmt from 'select * from stuinfo where stuno=?';


--调用预处理,并传参数
delimiter //  --更改定界符

set @id='s25301';
execute stmt using @id//

例题:传递多个参数

prepare stmt from 'select * from stuinfo where stuage>? and stusex=?' //

set @age=20;
set @sex='男';
execute stmt using @age,@sex//

小结:
1、Mysql中变量以@开头
2、通过set给变量赋值
3、?是位置占位符

1.9 数据库备份和还原

数据库中的数据需要定期备份,数据量小的可以一周备份一次,数据量大的可以一天备份一次。

1.9.1 数据备份

利用mysqldump工具,语法:

mysqldump 数据库连接 数据库>数据库备份

例题:

--将数据库中所有的表导出到data.sql中
mysqldump -uroot -proot data>c:\data.sql

--将data数据库中的stuinfo、stumarks表
mysqldump -uroot -proot data stuinfo stumarks>c:\data.sql

--导出data数据库,导出的语句中带有创建数据库的语法
mysqldump -uroot -proot -B data>c:datal.sql

1.9.2 数据库还原

方法一:MySQL的source指令

source c:/data.sql;
注意:地址分隔符用斜线,不能用反斜线

方法二:通过mysql指令数据还原(不需要登录MySQL)
语法:

msyql 连接数据库 导入数据库的名 <  导入的SQL文件

例题:

F:\wamp\PHPTutorial\Mysql\bin>mysql -uroot -proot data1 < c:\data.sql
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值