文章目录
MySQL基础学习——Day5
索引
1.什么是索引?
索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。
一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。
索引相当于一本书的目录,为了缩小扫描范围儿存在的一致机制。
MySQL在查询方面主要就是两种方式:
第一种方式:全表扫描
第二种方式:根据索引检索。
注:在mysql数据库当中索引也是需要排序的,并且这个索引的排序和TreeSet数据结构相同。TreeSet(TreeMap) 底层是一个自平衡的二叉树!在mysql当中索引是一个B-Tree数据结构。
遵循左小右大原则存放!采用中序遍历方式遍历取数据。
2.索引的实现原理?
1.索引的实现原理:
缩小扫描的范围,避免全表扫描。
假设有一张用户表 : t_user #注意①:在任何数据库当中主键上都会自动添加索引对象,id字段上自动有索引,因为id是PK.另外在mysql当中,一个字段上如果有unique约束的话,也会自动创建索引对象。 #注②: 在任何数据库当中,任何一张表的任何记录在硬盘在硬盘存储上都有一个硬盘的物理存储编号。 #注③: 在mysql当中,索引是一个单独的对象,不同的存储引擎以不同的形式存在,在MyISAM存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中索引存储在一个逻辑名称叫做tablespace的当中。在MEMORY存储引擎中索引被存储在内存中。无论索引存储在哪里,索引在mysql当中都是一个树的形式存在。(自平衡二叉树:B-Tree) id(PK) name 硬盘上的物理编号 --------------------------------------------- 100 zhangsan 0x1111 120 lisi 0x2222 99 wangwu 0x8888 88 zhaoliu 0x9999 101 jack 0x6666 55 lucy 0x5555 130 tom 0x7777 select * from t_user where id= 101; mysql 发现id字段上有索引对象,所以会通过索引对象idIndex进行查找 通过101得出物理编号:0x6666,此时马上SQL语句转换: select * from t_user where 物理编号 = 0X6666;
2.添加索引的条件
1.数据量庞大(庞大多少?需要具体测试,因为每一个硬件环境不同) 2.该字段经常出现在where的后面,以条件的形式存在,也就是说这个字段总是被扫描。 3.该字段很少的DML(insert,delete,update)操作,(因为DML之后,索引需要重新排序。) 建议不要随意添加索引,因为索引也是需要维护额,太多的话反而会降低系统的性能。 建议通过主键查询,或通过unique约束的字段进行查询,效率是比较高的。
3.索引的创建和删除?
1.创建索引
给emp表的ename字段添加索引,起名:emp_ename index
create index emp_ename index on emp(ename);
2.删除索引
将emp表上的emp_ename_index索引对象删除。
drop index emp_name_index on emp;
3.查看语句是否使用的索引进行检索
explain select * from emp where ename = "KING";
4.索引的失效
1.使用or的时候会失效:
explain select * from emp where ename = 'KING' or job = 'MANAGER';
如果使用or那么要求or两边的条件字段都要有索引,才会走索引,如果其中一边有一个字段没有索引,那么另一个字段上的索引也会失效,所以这就是为什么不建议使用or的原因。
2.使用复合索引时候,没有使用左侧的列查找,索引失效。
#复合索引:两个字段或者更多字段联合起来添加一个索引,叫做复合索引。
create index emp_job_sal_indexx on emp(job,sal);
explain select * form emp where job = 'MANAGER'; //使用索引
explain select * from emp where sal = 800; //索引失效
3.在where当中索引列参加了运算,索引失效。
create index emp_sal_index on emp(sal);
explain select * from emp where sal = 800; //使用索引
explain select * from emp where sal+1 = 800; //索引失效
4.在where当中索引列使用了函数
explain select * from emp where lower(ename) = 'smith'; //索引失效
5.索引的分类
单一索引:一个字段上添加索引。
复合索引:两个字段或更多字段上添加索引。
主键索引:主键上添加索引。
唯一性索引:具有unique约束的字段上添加索引。
…
注意:唯一性比较弱的字段上添加索引用处不大。
视图
什么是视图?
view: 站在不同的角度取看待同一份数据。
如何创建视图?
create view emp_view as select * from emp;
怎么删除视图对象?
drop view dept2_view;
注:只有DQL语句才能以view的形式创建。
create view view_name as 这里的语句必须是DQL语句。
用视图干什么?
我们可以面向视图对象进行增删改查,对视图对象的增删改查, 会导致原表被操作! (视图的特点:通过对视图的操作,会影响到原表数据。)
**用途:**可以把复杂的SQL语句以视图的对象的形式新建。在需要编写这条SQL语句的位置直接使用视图对象,可以大大简化开发。 并且利于后期的维护,因为修改的时候也只需要修改一个位置,修改视图对象所映射的SQL语句。
面向视图开发时,使用视图的时候可以像使用table一样。可以对视图进行增删改查等操作。视图不是在内存当中,视图对象也是存储在硬盘上的,不会消失。
C:Create(增)
R:Retrieve(查:检索)
U:Update(改)
D:Delete(删)
面向视图查询
select * from dept2_view;
面向视图插入
insert into dept2_view(deptno,dname,loc) values(60, 'SALES', 'BEIJING');
查询原表数据
select * from dept2;
#例
create view
emp_dept_view
as select
e.ename,e.sal,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno;
DBA常用命令
1.数据导出
在windows的dos命令窗口中:
mysqldump blog>D:\blog.sql -uroot -p123456 //导出数据库
mysqldump blog emp>D:\blog.sql -uroot -p123456 //导出里面的表emp
2.数据导入
需要先登录到mysql数据库服务器上。
然后创建数据库:create database blog; 使用数据库:use blog; 然后初始化数据库: source D:\blog.sql
数据库设计三范式
1.什么是数据库设计范式?
数据库表的设计依据。教你怎么进行数据库表的设计。
2.数据库设计范式
第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分。
第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖。
第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。
设计数据库表的时候,按照以上范式进行,可以避免表中数据的冗余,空间的浪费。
3.第一范式
最核心,最重要的范式,所有表的设计都需要满足。
必须要有主键,并且每一个字段都是原子性不可再分。
4.第二范式
建立在第一范式的基础之上,
要求所有非主键字段必须完全依赖主键,不要产生部分依赖。
学生编号 学生姓名 教师编号 教师姓名
----------------------------------------------------
1001 张三 001 王老师
1002 李四 002 赵老师
1003 王五 001 王老师
1001 张三 002 赵老师
这张表描述了学生和老师的关系:(1个学生可能有多个老师,1个老师有多个学生)
这是非常典型的:多对多关系!
分析以上的表是否满足第一范式?
不满足第一范式。
怎么满足第一范式呢?修改
学生编号+教师编号(pk) 学生姓名 教师姓名
----------------------------------------------------
1001 001 张三 王老师
1002 002 李四 赵老师
1003 001 王五 王老师
1001 002 张三 赵老师
学生编号 教师编号,两个字段联合做主键,复合主键(PK: 学生编号+教师编号)
经过修改之后,以上的表满足了第一范式。但是满足第二范式吗?
不满足,“张三”依赖1001,“王老师”依赖001,显然产生了部分依赖。
产生部分依赖有什么缺点?
数据冗余了。空间浪费了。“张三”重复了,“王老师”重复了。
为了让以上的表满足第二范式,你需要这样设计:
使用三张表来表示多对多的关系!!!!
学生表
学生编号(pk) 学生名字
------------------------------------
1001 张三
1002 李四
1003 王五
教师表
教师编号(pk) 教师姓名
--------------------------------------
001 王老师
002 赵老师
学生教师关系表
id(pk) 学生编号(fk) 教师编号(fk)
------------------------------------------------------
1 1001 001
2 1002 002
3 1003 001
4 1001 002
背口诀:
多对多怎么设计?
多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!
5.第三范式
第三范式建立在第二范式的基础之上
要求所有非主键字典必须直接依赖主键,不要产生传递依赖。
学生编号(PK) 学生姓名 班级编号 班级名称
---------------------------------------------------------
1001 张三 01 一年一班
1002 李四 02 一年二班
1003 王五 03 一年三班
1004 赵六 03 一年三班
以上表的设计是描述:班级和学生的关系。很显然是1对多关系!
一个教室中有多个学生。
分析以上表是否满足第一范式?
满足第一范式,有主键。
分析以上表是否满足第二范式?
满足第二范式,因为主键不是复合主键,没有产生部分依赖。主键是单一主键。
分析以上表是否满足第三范式?
第三范式要求:不要产生传递依赖!
一年一班依赖01,01依赖1001,产生了传递依赖。
不符合第三范式的要求。产生了数据的冗余。
那么应该怎么设计一对多呢?
班级表:一
班级编号(pk) 班级名称
----------------------------------------
01 一年一班
02 一年二班
03 一年三班
学生表:多
学生编号(PK) 学生姓名 班级编号(fk)
-------------------------------------------
1001 张三 01
1002 李四 02
1003 王五 03
1004 赵六 03
背口诀:
一对多,两张表,多的表加外键!!!!!!!!!!!!
总结:
数据库设计三范式是理论的,实践和理论有的时候有偏差。最终目的都是为了满足客户的需求,有的时候会拿冗余换执行速度
在sql中,表和表之间连接次数越多,效率越低。
有的时候可能存在数据冗余,但是为了减少表的连接次数,此做法也合理,并且对于开发人员来说,sql语句的编写难度也会降低。