`

mysql学习三之外键、联合查询、子查询、视图、数据备份还原

 
阅读更多


连接查询
将多张表(可以大于2张表)进行记录的连接(按照某个指定的条件进行数据拼接)
最终结果是:记录数有可能变化,字段数一定会增加(至少两张表的合并)

连接查询的意义:在用户查看数据的时候,需要显示的数据来自多张表。

连接查询:join 使用方式 左表 join 右表
左表:在join左边的表
右表:在join右边的表

连接查询分类
SQL中将连接查询分为4类:内连接、外连接、自然连接和交叉连接


交叉连接
从一张表中循环取出每一条记录,每条记录都去另外一张表进行匹配;
匹配一定保留(没有条件匹配),而连接本身字段就会增加(保留),最终
形成的结果是笛卡尔积。

基本语法: 左表 cross join 右表;  等价于 from 左表,右表

--交叉连接
select * from my_student cross join my_class;
没有意义,应该尽量避免
存在的价值:保证连接这种结构的完整性。


内连接
inner join  其中inner关键字可以省略,从左表中取出每一条记录,去
右表中与所有的记录进行匹配;匹配必须是某个条件在左表中与右表中相同
最终才会保留结果,否则不保留。

基本语法: 左表 [inner] join 右表 on 左表.字段 = 右表.字段;
on表示连接条件;条件字段就是代表相同的业务含义

select * from my_student inner join my_class on my_student.c_id = my_class.id;

字段别名以及表别名的使用:在查询数据的时候,不同表有同名字段,这个时候需要别名
才能区分,表名太长可用别名

select * from my_student as s inner join my_class as c on s.c_id = c.id;

内连接可以没有连接条件;没有on之后的内容,这个时候系统会保留所有结果,为笛卡尔积

select * from my_student as s inner join my_class as c where s.c_id = c.id;
内连接可能用where代替on(where没有on效率高);


外连接
以某张表为主,取出里面的所有记录,然后每条与另外一张表进行连接,不管能不能匹配上
条件,最终都会保留;能匹配,正确保留;不能匹配,其他表的字段都置空NULL。

外连接分为两种:是以某张表为主:有主表
left join:左外连接(称为左连接),以左表为主表
right join:右外连接(称为右连接),以右表为主表
基本语法: 左表 left/right join 右表 on 左表.字段 = 右表.字段

--左连接
select s.*,c.name as c_name,c.room from my_student as s left join my_class as c 
	on s.c_id=c.id;


--右连接
select s.*,c.id as c_id,c.name as c_name,c.room from my_student as s right join my_class as c 
	on s.c_id=c.id;

虽然左连接和右连接有主表差异,但是显示的结果:左表的数据在左边,右表的数据在右边


自然连接
就是自动匹配连接条件;系统以字段名字作为匹配模式,同名字段作为条件,多个同名字段,
都作为条件。

自然连接:可以分为自然内连接和自然外连接

自然内连接 左表 natural join 右表;
--自然内连接
select * from my_student natural join my_class ;
自然连接自动使用同名字段作为连接条件;连接之后合并同名字段

--自然左内连接
select * from my_student natural left join my_class;



外键
foreign key,如果一张表中有一个字段(非主键)每指向另一张表的主键,那么将该字段称之为外键。

增加外键
外键可以在创建表的时候或者创建表之后增加(但是要考虑数据的问题)
一张表可以有多个外键

方案一:在创建表的时候增加外键:在所有的表字段之后;使用
foreign key(外键字段) references 外部表(主键字段)

create table my_foreign1(
id int primary key auto_increment,
name varchar(20) not null comment '学生名称',
c_id int comment '班级id',
foreign key(c_id) references my_class(id)
)charset utf8;
外键要求字段本身必须先是一个索引(普通索引),如果字段本身没有索引,外键会先创建一个索引,
然后才会创建外键本身。


方案二:在新增表之后增加外键:修改表结构
alter table 表名 add [constraint 外键名字] foreign key(外键字段) references 父表(主键字段)
create table my_foreign2(
id int primary key auto_increment,
name varchar(20) not null comment '学生名称',
c_id int comment '班级id'
)charset utf8;

alter table my_foreign2 add constraint student_class_1 foreign key(c_id) references my_class(id);

      
修改外键&删除外键
外键不可修改,只能先删除后新增

删除外键
alter table 表名 drop foreign key 外键名; --一张表中可以有多个外键,名字不能相同

--删除外键
alter table my_foreign1 drop foreign key my_foreign1_ibfk_1;
外键删除不能通过查看表结构体现,应该通过查看创建语句体现。


外键的作用

外键默认的作用有两点:一个对父表,一个对子表(外键字段所在的表)
对子表约束:子表数据进行写操作的时候,如果对应的外键字段在父表找不到对应的匹配,那
么操作会失败(约束了子表的数据操作)。

--插入数据:外键字段在父表中不存在
insert into my_foreign2 values(null,'外键',5); --不能新增或者更新一个子行

对父表约束:父表数据进行写操作(删和改:都必须涉及到主键本身),如果对应的主键在
子表中已经被数据所引用,那么就不允许操作

insert into my_foreign2 values(null,'外键1',1);
insert into my_foreign2 values(null,'外键2',2);
insert into my_foreign2 values(null,'外键3',3);

--更新父表记录
update my_class set id=5 where id=1;  --更新失败

外键条件
1、外键要存在:首先必须保证表的存储引擎是innodb(默认的存储引擎);如果不是innodb存储
引擎,那么外键可以创建成功,但是没有约束效果。
2、外键字段的字段类型(列类型)必须与父表的主键类型完全一致。
3、一张表中的外键名字不能重复。
4、增加外键的字段(数据已经存在),必须保证数据与父表主键要求对应。

--插入数据
insert into my_foreign1 values(null,'无外键',5);
--数据已经存在,在新增外键的时候,无法改变不能匹配数据事实,添加外键失败
alter table my_foreign1 add foreign key(c_id) references my_class(id);

外键约束
所就是指外键的作用:之前所讲的外键作用:是默认的作用;其实可以通过对外键的需求,进行定制
操作。

外键约束有三种约束模式:都是针对父表的约束
	district:严格模式(默认的),父表不能删除或者更新一个已经被子表数据引用的记录
	cascade:级联模式:父表的操作,对应子表关联的数据也跟着操作
	set null:置空模式:父表的操作之后,子表对应的数据(外键字段)被置空。

通常的一个合理的做法(约束模式):删除的时候子表置空,更新的时候子表级联操作
指定模式的语法
foreign key(外键字段) references 父表(主键字段) on delete set null on update cascade;

create table my_foreign3(
id int primary key auto_increment,
name varchar(20) not null,
c_id int,
foreign key(c_id) references my_class(id) on delete set null on update cascade
)charset utf8;
	

--插入数据
insert into my_foreign3 values(null,'齐备',1),(null,'苏打',1),(null,'阿哥',1),
(null,'疑心',2),(null,'导游',2);

--更新父表主键,子表会被级联更新
update my_class set id=6 where id=1;
--删除父表主键
delete from my_class where id=2;

更新操作是级联更新,删除操作是置空
删除置空的前提条件:外键字段允许为空。



联合查询
将多次查询(多条select语句),在记录上进行拼接(字段不会增加)

基本语法:
多条select语句构成:每一条select语句获取的字段数必须严格一致(但是字段类型无关)

select 语句1
	union [union 选项]
	select 语句2...

union 选项 与select 选项一样有两个:
	all:保留所有(不管重复)
	distinct: 去重(整个重复):默认的


--联合查询,默认去重
select * from my_class 
		union 
		select * from my_class;
--联合查询,不去重
select * from my_class 
		union all
		select * from my_class;
	
联合查询只要求字段一样,跟数据类型无关。
select id,name,room from my_class 
		union all
		select name,id,number from my_student;

意义:
联合查询的意义分为两咱:
1、查询同一张表,但是需求不同:如查询学生信息,男生身高升序,女生身高降序

2、多表查询:多张表的结构是完全一样的,保存的数据(结构)也是一样的。

--错误
select * from my_student where sex='男'  order by height asc
	union
	select * from my_student where sex='女' order by height desc ;
在联合查询中order by不能直接使用,需要要(),括起来
(select * from my_student where sex='男'  order by height asc)
	union
	(select * from my_student where sex='女' order by height desc );
若要order by 生效:必须搭配limit.limit使用限定

(select * from my_student where sex='男'  order by height asc limit 9999)
	union
	(select * from my_student where sex='女' order by height desc limit 9999);
	

子查询
查询是在某个查询结果之上进行的(一条select语句包含另一条select语句)

子查询分类
子查询有两种分类方式:按位置分类;按结果分类

按位置分类:子查询(select语句)在外部查询(select语句)中出现的位置
	from 子查询:子查询跟在from之后
	where子查询:子查询跟在where条件中
	exists子查询:子查询出现在exists里面

按结果分类:根据子查询得到的数据进行分类(理论上任何一个查询得到的结果为二维表)
	标量子查询:子查询得到的结果是一行一列
	列子查询:子查询得到的结果是一列多行
	行子查询:子查询得到的结果是多列一行(可以多行多列)
		上面几个出现的位置都是在where之后
	表子查询:子查询得到的结果是多行多列(出现的位置是在from之后)

标量子查询

需求:知道班级名字为php0812的学生
select * from my_student where c_id= (select id from my_class where name='PHP0812');


列子查询
需求:查询所有在读班级的学生

1、确定数据源:学生
select * from my_student where c_id in(?) ;
2、确定有效班级的id,所有班级id
select id from my_class;

列子查询
select * from my_student where c_id in(select id from my_class) ;

列子查询返回的结果会比较:一列多行,需要使用in作为匹配条件
select * from my_student where c_id =any(select id from my_class) ;
select * from my_student where c_id =some(select id from my_class) ;
select * from my_student where c_id =all(select id from my_class) ;

行子查询 
行子查询:返回的结果可以是多行多列

需求:要求查询整个学生中,年龄最大且身高是最高的学生。
1、确定数据源 
select * from my_student where age=? and height=?;
2、确定最大的年龄和最高的身高
select max(age),max(height) from my_student;

select * from my_student where 
	age =(select min(age) from my_student)
and 
	height=(select max(height) from my_student);
--(age,height) 称为行元素
select * from my_student where (age,height) = (select min(age),max(height) from my_student);


表子查询
子查询返回的结果是多行多列的二维表;子查询返回的结果是当做二维表来使用

需求:找出每个班中最高的一个学生
1、确定数据源 ;先将学生按照身高进行降序排序
select * from my_student order by height desc;

2、从每个班选出第一个学生
select * from my_student group by c_id; --每个班选出第一个学生

表子查询:from子查询;得到的结果作为from的数据源
select * from (select * from my_student order by height desc) as stu
	group by c_id;

exists子查询 
是否存在的意思,exists子查询就是用来判断某些条件是否满足(跨表),
exists是接在where之后;exists返回的结果只有0和1
--返回100
select exists(select * from my_student);
--返回0
select exists(select * from my_student where id=0);

需求:返回所有的学生;前提条件是班级存在
1、确定数据源 
select * from my_student where ?;
2、确定条件是否满足
exists (select * from my_class);  --是否成功

select * from my_student where exists(select * from my_class where id=1);

select * from my_student where exists(select * from my_class where id=9);


视图
是一种有结构(有行有列)但是没有结果(结构中不真实存放数据)的虚拟表。虚拟表的
结构来源不是自已定义,而是从对应的基表中产生。

创建视图
基本语法:
create view 视图名字 as select 语句; --select语句可以是普通查询;可以是连接查询,可以是联合查询等

--创建单表视图
create view my_v1 as 
	select * from my_student;
create view my_v2 as 
	select * from my_class;
--创建多表视图
create view my_v3 as 
	select s.*,c.id cid,c.name cname,c.room from my_student as s left join my_class c on s.c_id=c.id;

注意:创建视图时不能有同名字段

查看视图
视图是一张虚拟表: 表的所有查看方式都适用 show tables /desc , 

--查看视图创建语句
show create view my_v3\G;

视图一旦创建:系统会在视图对应的数据库文件夹下创建一个对应的结构文件:from文件


使用视图
使用视图主要是为了查询:将视图当做表一样使用
视图的执行:其实本质就是执行封装的select语句

select * from my_v1;

修改视图
视图本身不可修改,但是视图的来源是可以修改的。
修改视图:修改视图本身的来源语句(select语句)

alter veiw 视图名字 as 新的名字 select 语句;

alter view my_v1 as 
select id,name,age,sex,height,c_id from my_student;


删除视图
drop view 视图名字;

create view my_v4 as select * from my_student;

drop view my_v4;

视图的意义
1、视图可以节省SQL语句:将一条复杂的查询语句使用视图进行保存;以后可以直接
对视图进行操作。
2、数据安全:视图操作是主要针对查询的,如果对视图结构进行处理(删除),不会
影响基表数据(相对安全)。
3、视图往往在大项目中使用,而且是多系统使用。可以对外提供有用的数据,但是
隐藏关键(无用)的数据;数据安全。
4、视图可以对外提供友好型;不同的视图提供不同的数据
5、视图可以更好的进行权限控制


视图数据操作

数据新增
直接对视图进行数据新增

1、多表视图不能新增数据
2、可以向单表视图插入数据;但是视图中包含的字段必须包含所有不允许为空的字段
3、视图可以向基表插入数据


删除数据
1、多表视图不能删除数据
2、单表视图可以删除数据


更新数据
理论上单表视图和多表视图都可以

更新限制:with check option; 如果对视图在新增的时候,限定了某个字段有限制;那么在
对视图进行数据更新操作时,系统会进行验证:要保证更新之后,数据依然可以被实体查询出
来,否则不让更新。

--视图 :age字段限制更新
--表示视图的数据来源都是年龄大于30岁;where age>30决定
--with check option:决定通过视图更新的时候,不能将已经得到的 数据age>30的改成小于30的
create view my_v4 as 
select * from my_student where age >30 with check option;


--将视图可以查到的数据改成<30
update my_v4 set age=23 where id=1;

--可以修改数据让视图可以查到
update my_v4 set age=33 where id=1;


--获取所有班级中最高的一个学生
create view my_v5 as
   select * from my_student order by height desc;

select * from my_v5 group by c_id;

视图算法
系统对视图以及外部查询视图的select语句的一种解析方式

视图算法分为三种
	undefined :未定义(默认),这不是一种实际使用算法
	temptable:临时表算法;系统先执行视图的select语句,后执行外部查询语句
	merge:合并算法,系统应该先将视图对应的select语句与外部查询视图的select
	语句进行合并,然后执行(效率高:常态);

算法指定:在创建视图的时候
create ALGORITHM=指定算法 view 

create ALGORITHM=temptable view my_v7 as
	select * from my_student order by height desc;
select * from my_v6 group by c_id;


数据备份与还原
备份:将当前已有的数据或者记录保留
还原:将已经保留的数据恢复到对应的表中

为什么要做备份还原?
1、防止数据丢失;被盗;误操作
2、保护数据记录

数据备份还原的方式:数据表备份、单表数据备份、SQL备份、增量备份

数据表备份 
不需要通过SQL来备份;直接进入到数据库文件夹复制对应的表结构及数据文件,以
后还原的时候,直接将备份的内容放进去即可。
数据表备份有前提条件:根据不同的存储引擎有不同的区别。

存储引擎:mysql进行数据存储的方式:有是innodb和Myisam

对比myisam和innodb:数据存储方式:
	innodb:只有表结构,数据全部存储到ibdata1文件中
	myisam:表、数据、索引全部单独分开存储
	
--创建myisam表
create table my_myisam(
	id int,
	name varchar(20)
)charset utf8 engine=myisam;

这种文件备份通常适用于myisam存储引擎,直接复制三个文件即可,然后放到对应
的数据库下即可以使用。innodb可以复制过来,但是不能使用。

单表数据备份 

每次只能备份一张表,只能备份数据(表结构不能备份)

通常的使用,将表中的数据时行导出到文件

备份: 从表中选出一部分数据存到外部文件中
--前提外部文件不存在
select */字段列表 into outfile 文件所在路径 from 数据源 

--单表数据备份 
select * into outfile 'd:/zdata_student.txt' from my_student ;

高级备份:自己制定字段和行的处理方式
select */字段列表 into outfile 文件所在路径 fields 字段处理 lines 行处理 from 数据源;

fields字段处理:
	enclosed by:字段使用什么内容包裹,默认'',空字符串
	teminated by:字段以什么结束,默认是\t,tab键
	escaped by :特殊符号用什么方式处理,默认是'\\',使用\转义

lines行处理:
	starting by :每行以什么开始,默认是'',空字符串。
	terminated by:每行以什么结束,默认是'\r\n'

--指定备份处理方式
--使用|分隔字段 --字段处理 
select * into outfile 'd:/zdata_student.txt' 
	fields enclosed by '"' 
	terminated by '|'       
	lines 
	starting by 'START:'
FROM MY_STUDENT;


数据还原
将一个在外部保存的数据重新恢复到表中(如果表结构不存在,那么不能恢复)

load data infile 文件所在路径 into table 表名[(字段列表)] fields 字段处理 lines 行处理 
怎么备份的怎么还原

load data  infile 'd:/zdata_student.txt' into table my_student fields enclosed by '"' 
	terminated by '|' lines starting by 'START:';
	
	
SQL备份 
备份的是SQL语句;系统会对表结构以及数据进行处理,变成对应的SQL语句,然后进行备份,
还原的时候只要执行SQL指令即可(主要是针对表结构)

备份: mysql没有提供备份指令;需要利用mysql提供的软件 :mysqldump.exe

mysqldump.exe也是一种客户端,需要操作服务器,必须要连接认证

mysqldump -hPup 数据库名字[数据表名字1[数据表名字2...]]>外部文件目录(建议使用.sql)

--SQL备份 
mysqldump -uroot -proot test my_student > d:/zdata_student.sql 

--整库备份
mysqldump -uroot -proot test > d:/zdata_student.sql 

SQL数据还原:两种方式还原
1、使用mysql.exe客户端还原
mysql -hpup 数据库名字 < 备份文件目录

mysql -uroot -proot test < d:/zdata_student.sql 

2、使用SQL指令还原
source 文件所在路径;

source d:/zdata_student.sql ;

SQL备份优缺点
1、优点:可以备份结构
2、缺点:会浪费空间(额外的增加SQL指令)

增量备份
不是针对数据或SQL指令进行备份,是针对mysql服务器的日志文件进行备份

指定时间段开始进行备份、备份数据不会重复,而且所有的操作都会备份(大项目都用增量备份)





分享到:
评论

相关推荐

    MySQL数据库入门到高级笔记快速学习pdf版本

    内容概要:这是博主自己写的三篇MySQL文章的综合pdf版本,干货满满,同时搭配脑图提高效率,从基础知识,比如对数据库的操作,对数据表的增删改,查单独写了一篇文章从单表到多表,子查询等等,干货满满,最后就是...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例085 还原论坛中帖子的内容 120 实例086 截取论坛标题 121 实例087 分割、合成字符串 121 实例088 查询关键字描红 122 实例089 统计查询关键字的出现次数 123 实例090 获取上传文件的后缀 124 实例091 统一上传...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例085 还原论坛中帖子的内容 120 实例086 截取论坛标题 121 实例087 分割、合成字符串 121 实例088 查询关键字描红 122 实例089 统计查询关键字的出现次数 123 实例090 获取上传文件的后缀 124 实例091 统一上传...

    MYSQL必知必会读书笔记第二章之版本更改

    您可能感兴趣的文章:批处理命令 BAT备份MySQL数据库MySQL 备份还原数据库批处理MySQL数据入库时特殊字符处理详解php+mysqli预处理技术实现添加、修改及删除多条数据的方法MySQL中的max()函数使用教程使用My

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

     数据查询语言 (Data Query Language, DQL) 是SQL语言中,负责进行数据查询而不会对数据本身进行修改的语句,这是最基本的SQL语句。例如:SELECT(查询)  数据控制语言Data Controlling Language(DCL),用来...

    ASP.NET 3.5 开发大全word课件

    这是整部学习资料 由于太大第一章免费供应给大家 在我的上传资源中 如果觉得还不过希望大家给个好评 当然具体本书的作者就不深究了把! 第1章 认识ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET历史与展望 1.1.2 ASP...

    ASP.NET3.5从入门到精通

    第三篇 数据操作篇 第 7 章数据库与 ADO.NET 基础 7.1 数据库基础 7.1.1 结构化查询语言 7.1.2 表和视图 7.1.3 存储过程和触发器 7.2 使用SQL Server 2005 管理数据库 7.2.1 初步认识SQL Server 2005 7.2.2 创建...

    ASP.NET 3.5 开发大全11-15

    第三篇 数据操作篇 第7章 数据库与ADO.NET基础 7.1 数据库基础 7.1.1 结构化查询语言 7.1.2 表和视图 7.1.3 存储过程和触发器 7.2 使用SQL Server 2005 管理数据库 7.2.1 初步认识SQL Server 2005 7.2.2 创建数据库 ...

    ASP.NET 3.5 开发大全

    第三篇 数据操作篇 第7章 数据库与ADO.NET基础 7.1 数据库基础 7.1.1 结构化查询语言 7.1.2 表和视图 7.1.3 存储过程和触发器 7.2 使用SQL Server 2005 管理数据库 7.2.1 初步认识SQL Server 2005 7.2.2 创建数据库 ...

    ASP.NET 3.5 开发大全1-5

    第三篇 数据操作篇 第7章 数据库与ADO.NET基础 7.1 数据库基础 7.1.1 结构化查询语言 7.1.2 表和视图 7.1.3 存储过程和触发器 7.2 使用SQL Server 2005 管理数据库 7.2.1 初步认识SQL Server 2005 7.2.2 创建数据库 ...

    ASPNET35开发大全第一章

    第三篇 数据操作篇 第7章 数据库与ADO.NET基础 7.1 数据库基础 7.1.1 结构化查询语言 7.1.2 表和视图 7.1.3 存储过程和触发器 7.2 使用SQL Server 2005 管理数据库 7.2.1 初步认识SQL Server 2005 7.2.2 创建数据库 ...

    Java面试宝典2020修订版V1.0.1.doc

    44、一个几千万数据,发现数据查询很慢,怎么办? 55 六、Java高级部分 56 1、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 56 2、sleep() 和 wait() 有...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。 该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下: 1. ...

Global site tag (gtag.js) - Google Analytics