索引
索引就相当于一本书的目录,通过目录可以快速的找到对应的资源。
在数据库方面,查询一张表的时候有两种检索方式:
- 全表扫描
- 根据索引检索(效率很高)
索引为何能提高检索效率?
最根本的原理是缩小了扫描的范围
注意:索引虽然可以提高检索效率,但是不能随意添加索引,因为索引也是数据库当中的对象,也需要数据库不断的维护。是有维护成本的,比如:表中的数据经常被修改,这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护。
何时考虑给字段添加索引?
- 数据量庞大(根据客户需求、根据线上的环境)
- 该字段很少的DML操作(因为字段进行修改操作,索引也需要维护)
- 该字段经常出现在where子句中(经常根据哪个字段查询)
主键和具有unique约束的字段自动会添加索引,根据主键查询效率很高,尽量根据主键检索。
创建索引对象
create index 索引名称 on 表名(字段名);
select ename,sal from emp where sal = 5000;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
+-------+---------+
查看SQL语句的执行计划
explain select ename,sal from emp where sal = 5000;
+----+-------------+-------+------+---------------+------+---------+-----+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-----+------+-------------+
| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL| 14 | Using where |
+----+-------------+-------+------+---------------+------+---------+-----+------+-------------+
给薪资sal字段添加索引
create index emp_sal_index on emp(sal);
explain select ename,sal from emp where sal = 5000;
+----+-------------+-------+------+---------------+---------------+---------+-----+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------------+---------+-----+------+-------------+
| 1 | SIMPLE | emp | ref | emp_sal_index | emp_sal_index | 9 |const| 1 | Using where |
+----+-------------+-------+------+---------------+---------------+---------+-----+------+-------------+
删除索引
drop index 索引名称 on 表名;
drop index emp_sal_index on emp
实现原理
通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的物理地址,最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。
索引的分类
单一索引:给单个字段添加索引
复合索引:给多个字段联合起来添加一个索引
主键索引:主键上会自动添加索引
唯一索引:有unique约束的字段上会自动添加索引
…
索引什么时候失效
select ename from emo where ename like '%A%';
迷糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的!!!
视图(view)
站在不同的角度去看到数据(同一张表的数据,通过不同的角度去看待)
创建视图
注意:只有DQL语句才能以视图对象的方式创建出来
create view myview as select empno,ename from emp;
删除视图
drop view myview;
对视图进行增删改查,会影响到原表数据。(通过视图影响原表数据,不是直接操作原表)
可以对视图进行CRUD操作
select * from myview;
+------+-------+
|empno | ename |
+------+-------+
| 7369 | SMITH |
| 7499 | ALLEN |
| ... | ... |
+------+-------+
update myview set ename='hehe',sal=1 where empno = 7369;//通过视图修改原表数据
select * from myview;
+------+-------+
|empno | ename |
+------+-------+
| 1 | hehe |
| 7499 | ALLEN |
| ... | ... |
+------+-------+
delete from myview where empno = 7369;//通过视图删除原表数据
select * from myview;
+------+-------+
|empno | ename |
+------+-------+
| 7499 | ALLEN |
| ... | ... |
+------+-------+
视图的作用
视图可以隐藏表的实现细节,保密级别较高的系统,数据库只对外提供相关的视图。java程序员只对试图对象进行CRUD。
数据库数据的导入和导出
导出
将数据库当中的数据导出
在Windows的dos命令窗口中执行
导出指定数据库
mysqldump 数据库名>D:\数据库名.sql -uroot -p密码
导出指定数据库当中的指定表
mysqldump 数据库名 表名>D:\数据库名.sql -uroot -p密码
导入数据
create database 数据库名;
use 数据库名;
source D:\数据库名.sql
数据库设计三范式(重点)
设计表的数据,按照这三个范式设计的表不会出现数据冗余
-
第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。
-
第二范式:建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖。
多对多?三张表,关系表两个外键
t_student 学生表 sno(pk) sanme ----------------- 1 张三 2 李四 3 王五 t_teacher 讲师表 tno(pk) tname ----------------- 1 王老师 2 张老师 3 李老师 t_student_teacher_relation 学生讲师关系表 id(pk) sno(fk) tno(fk) ---------------------------------- 1 1 3 2 1 1 3 2 2 4 2 3 5 3 1 6 3 3
-
第三范式:建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。
一对多?两张表,多的表加外键
班级t_class cno(pk) cname --------------------- 1 班级1 2 班级2 学生 t_student sno(pk) sname classno(fk) ----------------------------------- 101 张1 1 102 张2 1 103 张3 2 104 张4 2 105 张5 2
一对一怎么设计
两种方案,第一种:主键共享
t_user_login 用户登录表
id(pk) username password
-----------------------------
1 zs 123
2 ls 456
t_user_detail 用户详细信息表
id(pk+fk) realname tel
----------------------------
1 张三 11111
2 李四 22222
第二种方案:外键唯一
t_user_login 用户登录表
id(pk) username password
-----------------------------
1 zs 123
2 ls 456
t_user_detail 用户详细信息表
id(pk) realname tel userid(fk+unique)
---------------------------------------------
1 张三 11111 1
2 李四 22222 2