mysql优化学习(1)

1.数据库三范式

1.1 范式的基本分类

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。

1.2基本三大范式

第一范式 原子性:每列不可再拆分
第二范式 不产生局部依赖,每列都完全依赖于主键 , 一张表只描述一件事情
第三范式 不产生传递依赖,所有的列都直接依赖于主键,不包含其他表已经包含的非主键信息。

1.3反三范式

3NF提出目的是为了降低冗余,减少不必要的存储,这对于存储设备昂贵的过去是很有必要的,但是随着存储设备的降价以及人们对性能的不断提高,又有人提出反三范式。所谓反三范式就是为了性能,增加冗余。以部门信息表为例,每个部门有部门编号、部门名称、部门简介等信息,按照3NF的要求,为了避免冗余,我们在员工表中就不应该加入部门名称、部门简介等部门有关信息,带来的代价是每次都要查询两次数据库。反三范式允许我们冗余重要信息到员工表中,例如部门名称,这样我们每次取员工信息时就能直接取出部门名称,不需要查询两次数据库,提升了程序性能。

2.Select语句执行顺序

SQL Select语句完整的执行顺序:SQL语言不同于其他编程语言的最明显特征是处理代码的顺序。在大多数据库语言中,代码按编码顺序被处理。但在SQL语句中,第一个被处理的子句式FROM,而不是第一出现的SELECT。SQL查询处理的步骤序号:

2.1.代码编写顺序

select distinct 查询字段
from 表名
JOIN 表名
ON 连接条件
where 查询条件
group by 分组字段
having 分组后条件
order by 排序条件
limit 查询起始位置, 查询条数

SELECT DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
ORDER BY <order_by_condition>
LIMIT <limit_number>

2.2Mysql读取顺序

from 表名
ON 连接条件
JOIN 表名
where 查询条件
group by 分组字段
having 分组后条件
select distinct 查询字段
order by 排序条件
limit 查询起始位置, 查询条数

整体过种:
1.先对多表进行关系,根据条件找出符合条件的记录
2.在符合条件的基础上进行再次where条件筛选
3.对筛选出来的内容进行分组操作
4.分组完成后, 使用having再次筛选出满足条件的记录
5.取所满足条件的记录
6.对取出的记录进行排序
7.最终从取出的记录当中获取多少条记录显示出来

(7)   SELECT          /* 处理SELECT列表,产生 VT7 */
(8)   DISTINCT <select_list>  /* 将重复的行从 VT7 中删除,产品 VT8 */
(1)   FROM <left_table>    /* 对FROM子句中的表执行笛卡尔积(交叉联接),生成虚拟表 VT1。 */
(3)   <join_type> JOIN <right_table>
/* 如果指定了OUTER JOIN(相对于CROSS JOIN或INNER JOIN),保留表中未找到匹配的行将作为外部行添加到 VT2,
生成 VT3。如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,
直到处理完所有的表位置。  */
(2)   ON <join_condition>/* 对 VT1 应用 ON 筛选器,只有那些使为真才被插入到 VT2。 */
(4)   WHERE <where_condition>/* 对 VT3 应用 WHERE 筛选器,只有使为true的行才插入VT4。 */
(5)   GROUP BY <group_by_list> /* 按 GROUP BY子句中的列列表对 VT4 中的行进行分组,生成 VT5 */
(6)   HAVING <having_condition>/* 对 VT5 应用 HAVING 筛选器,只有使为true的组插入到 VT6 */
(9)   ORDER BY <order_by_condition>/* 将 VT8 中的行按 ORDER BY子句中的列列表顺序,生成一个游标
(VC10),生成表TV11,并返回给调用者。 */
(10)   LIMIT <limit_number>

3.内外链接的区别

笛卡儿积现象如果直接查询两张表会出现笛卡儿积现象,就是把两张表的数据直接进行交叉组合

3.1内连接:利用内连接可获取两表的公共部分的记录,内连接分隐式内连接,显式内连接

隐式内连接

select 列名 from 左表,右表 where 主表.主键=从表.外键

显式内连接

--使用INNER JOIN ... ON语句, 可以省略INNER
select 列名 from 左表 inner join 右表 on 主表.主键=从表.外键
--显式内连接与隐式内连接查询结果是一样的**

3.2外连接:外连接分为两种,一种是左连接(Left JOIN)和右连接(Right JOIN)

左外连接:在内连接的基础上,保证左表中所有的记录都出现。相应记录使用NULL和它匹配。

右外连接概念:在内连接的基础上,保证右表中所有的数据都显示。左表中如果没有匹配的数据,使用NULL匹
配。

3.3全连接

在内连接的基础上,查询两个表的全部信息,做法是保全两个表的全部数据。

SELECT <select_list> FROM tableA A FULL Outter JOIN tableB B  ON A.Key = B.Key
-- 注:Mysql 默认不支持此种写法 Oracle支持

-- 示例  可以使用UNION关键字,实现全连接,他是属于并集作用,把共有的跟两边没有的合并在一起
SELECT * from employee e LEFT JOIN department d on e.depart_id = d.id
UNION
SELECT * from employee e RIGHT JOIN department d on e.depart_id = d.id

4 表的级联操作

什么是级联操作
在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作 ON UPDATE CASCADE – 级联更新,主键发生更新时,外键也会更新 ON DELETE CASCADE – 级联删除,主键发生删除时,从表关联的全部数据都会被直接删除。(-- 在创建表的时候添加外键约束,并且添加级联更新和级联删除 ON UPDATE
CASCADE ON DELETE CASCADE)

5.存储引擎的选择

存储引擎的概念:
插件式存储引擎是Mysql中最重要的特性之一,用户可以根据应用的需要选择如何存储数据和索引,是否使用事物等,从而改善你的应用的整体功能。这些不同的技术以及配套的相关功能在 MySQL中被称作存储引擎,MySQL默认支持多种存储引擎,以适应不同领域数据库的需求,用户可以通过选择不同的存储引擎,提高应用的效率,提供灵活的存储,用户也可以按照自己的需求定制和使用存储引擎。

-- 查看存储引擎
show engines;
-- 查看系统当前支持的存储引擎,需要使用如下命令:
show variables like '%storage_engine%';

存储引擎的创建和修改:
引入创建新表时,如果不指定存储引擎,那么系统就会使用默认的存储引擎,MySQL 5.5之前的默认存储引擎是MyISAM, 5.5之后改为了InnoDB,如果需要修改存储引擎可以在核心配置文件中(ini文件)配置如下操作:
default-storage-engine=INNODB

-- 也可以在创建表的时候,通过增加ENGINE关键字设置新表的存储引擎
CREATE TABLE `test1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM default CHARSET=utf8



CREATE TABLE `test2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

-- 也可以把一个已经存在的表的存储引擎,修改成其他表的存储引擎,操作如下:
alter table test1 ENGINE = innoDB;
show create table test1

常见存储引擎的区别

除了上表列出了,重点介绍下MyISAM和InnoDB区别
主外键
MyISAM : 不支持
InnoDB: 支持
事务
MyISAM:不支持
InnoDB:支持
行表锁
MyISAM 表锁 操作一条记录也会锁住整个表 不适合高并发的操作
InnoDB 行锁 操作时,只锁某一行,不对其它行有影响 适合高并发的操作
缓存
MyISAM : 只缓存索引,不缓存数据
InnoDB:不仅缓存索引,还要缓存真实数据,对内存要求比较高,而且内存大小对性能有决定性的影响
关注点
MyISAM性能
InnoDB:事务
默认安装
MyISAM:是
InnoDB:是
总的来说MyISAM适合查询跟批量插入的,InnoDB适合更新删除的操作

6.存储过程,函数,触发器

6.1存储过程,函数的介绍

引入
MySQL从5.0版本开始支持存储过程和函数。
存储过程和函数是事先经过编译和存储在数据库中的一段SQL语句的集合,然后直接通知调用执行即可, 所以调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的
效率是有好处的。
存储过程和函数的区别在于函数必须有返回值,而存储过程没有,存储过程的参数可以使用IN,OUT,INOUT类型,而函数的参数只能是IN类型的,
创建,删除,修改存储过程或者函数都需要权限,例如创建存储过程或者函数需要CREATE ROUNTINE权限,修改或者删除存储过程或者函数需要ALTER ROUTINE权限,执行存储过程或者函数需要EXECUTE权限。
小结
存储过程和函数是事先经过编译和存储在数据库中的一段SQL语句的集合
减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的
存储过程的操作要确定是否有权限。

个人解析:创建完这些操作会比直接写sql快的原因,因为你创建完存储过程完后,不用再跟sql一样去编译,去一步步校验语法是否有误,因为创建完后已经校验过一次了

--  测试数据
REATE TABLE student (
id int primary key auto_increment,
name varchar(20),
age int,
sex varchar(5),
address varchar(100),
math int,
english int
);

INSERT INTO student(NAME,age,sex,address,math,english) VALUES ('马云',55,'男','杭州',66,78),
('马化腾',45,'女','深圳',98,87),('马景涛',55,'男','香港',56,77),('柳岩',20,'女','湖南',76,65),
('柳青',20,'男','湖南',86,NULL),('刘德华',57,'男','香港',99,99),('马德',22,'女','香港',99,99),
('德玛西亚',18,'男','南京',56,65);

CREATE TABLE users(
 id INT PRIMARY KEY AUTO_INCREMENT,
 NAME VARCHAR(20),
 address VARCHAR(30) DEFAULT '广州'
);
-- 添加一条记录,不使用默认地址
INSERT INTO users(NAME , address) VALUES('李四','广州');
INSERT INTO users(NAME , address) VALUES('王五','广州');

-- 创建存储过程
DELIMITER $$
CREATE PROCEDURE testa()
BEGIN
 SELECT * FROM student WHERE id=2;
END $$
-- 调用存储过程
call testa();


-- 删除存储过程  或者操作工具都可以简单实现,个人觉得无须记忆,不过在某些部署场景智能通过执行sql语句来操作
DROP PROCEDURE testa1;
-- 删除函数
DROP FUNCTION testa1;

- 查看存储过程或者函数的状态
SHOW PROCEDURE STATUS LIKE 'testa';
-- 查看存储过程或者函数的定义
SHOW CREATE PROCEDURE testa;

小结
存储过程:
1.创建格式:create procedure 存储过程名
2.包含一个以上代码块,代码块使用begin和end 之间
3.在命令行中创建需要定义分隔符 delimiter $$
4.存储过程调用使用call命令
存储过程的特点:
1.能完成较复杂的判断和运算,而且处理逻辑都封装在数据库端,调用者不需要自己处理业务逻辑,一旦逻辑发
生变化,只需要修改存储过程即可,而对调用者程序完全没有影响。
2.可编程性强,灵活
3.SQL编程的代码可重复使用
4.执行速度相对快一些
5.减少网络之间数据传输,节省开销

select 列名 from 左表,右表 where 主表.主键=从表.外键
select 列名 from 左表,右表 where 主表.主键=从表.外键
select 列名 from 左表,右表 where 主表.主键=从表.外键
select 列名 from 左表,右表 where 主表.主键=从表.外键

你可能感兴趣的:(Mysql,mysql,数据库,sql)