MySQL高级
一、视图 view
1.1、概念
1、视图是简化查询过程,提?数据库安全性的虚拟表。
2、 视图中保存的仅仅是?条select语句,保存的是视图的定义,并没有保存真正的数据。视图中的源数据都来?于数据库表,数据库表称为基本表或者基表,视图称为虚拟表。
1.2、作用
1、防?未经许可的?户访问敏感数据,确保数据的安全性
2、 封装sql语句,简化查询过程
3、视图可对?户屏蔽真实表结构
1.3、语法
格式:
① 创建视图:CREATE VIEW 视图名字 AS SELECT 语句;
② 查询视图:SELECT * FROM 视图名;
③ 查看视图结构:desc 视图名;
④ 查看创建视图的?本信息:SHOW CREATE VIEW 视图名;
⑤ 修改视图:ALTER VIEW 视图名称 AS SQL语句 ;
⑥ 删除视图:DROP VIEW 视图名称;
CREATE view view_1 as SELECT * from employees where salary >5000;
SELECT * from view_1;
desc view_1;
show create view view_1;
alter view view_1 as select * from employees WHERE salary <= 5000;
drop view view_1;
注意:
查看当前?户是否有创建视图的权限
SELECT Select_priv,Create_view_priv FROM MySQL.user WHERE user=‘?户名’;
参数说明:
(1)Select_priv:属性表示?户是否具有SELECT权限,Y表示拥有SELECT权限,N表示没有。
(2)Create_view_priv:属性表示?户是否具有CREATE VIEW权限,Y表示拥有CREATE 权限,N表示没有;
(3)MySQL.user:表示MySQL数据库下?的user表。
(4)?户名:参数表示要查询是否拥有权限的?户,该参数需要?单引号引起来。
二、存储过程 procedure
2.1、概念
1、**存储过程(Stored Procedure)**是?种在数据库中存储复杂程序,以便外部程序调?的?种数据库对象。类似于java中的?法。
2、存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,?户可通过指定存储过程的名字并给定参数(需要时)来调?执?。
3、存储过程思想上很简单,就是数据库 SQL 语?层?的代码封装与重?。
2.2、优点
1、存储过程在创建的时候直接编译,?sql语句每次使?都要编译,提?执?效率
2、?个存储过程可以被重复使?。(其实sql语句也可以,没什么卵?)
3、?条sql语句,可能需要访问?张表,对数据库连接好?次,存储过程只会连接?次
4、 存储的程序是安全的。数据库管理员可以向访问数据库中存储过程的应?程序授予适当的权限,?不向基础数据库表提供任何权限。
2.3、缺点
1、可移植性太差了
2、对于简单的sql语句,毫?意义
3、对于只有?类?户的系统安全性毫?意义
4、 团队开发,标准不定好的话,后期维护很麻烦
5、对于开发和调试都很不?便
6、复杂的业务逻辑,?存储过程还是很吃?的
2.4、使用
1、创建存储过程
? DELIMITER $$
CREATE PROCEDURE 存储过程名(参数和返回值)
? BEGIN
SELECT * FROM users;
? END$$
DELIMITER $$
说明:
? IN 表示这个存储过程需要的输?参数
out表示这个存储过程需要的输出参数
? inout是可以接受?个参数并输出?个参数
2、 调?存储过程
CALL 存储过程名(参数);
3、 删除存储过程
DROP PROCEDURE 存储过程名;
2.5、案例
delimiter $$
create procedure pro_1()
begin
select * from employees;
end $$
delimiter $$
call pro_1();
delimiter $$
CREATE procedure pro_2(in id int,out username varchar(32))
begin
select last_name into username from employees where employee_id = id;
end $$
delimiter $$
call pro_1(103,@username);
select @username;
delimiter $$
CREATE procedure sum1(in n int,out sum int)
BEGIN
declare i int default 1 ;
declare sums int DEFAULT 0 ;
while i <= n do
SET sums = sums + i;
SET i = i + 1;
end while;
SET sum = sums;
end $$
delimiter $$
call sum1(100,@sum);
SELECT @sum;
drop procedure pro_1;
drop procedure sum1;
三、触发器 tigger
3.1、概念
1、触发器的这种特性可以协助应?在数据库端确保数据的完整性。也可以把触发器理解成?个特殊的存储过程,不需要显示调?,是?动被调?的存储过程。
2、 类似于servlet中的监听器
3、监视某种情况,并触发某种操作,它是提供给程序员和数据分析员来保证数据完整性的?种?法,它是与表事件相关的特殊的存储过程,它的执?不是由程序调?,也不是??启动,?是由事件来触发,例如当对?个表进?操作
(insert,delete, update)时就会激活它执?。
3.2、语法
语法:
? DELIMITER $$
CREATE TRIGGER 触发器名 触发时机(BEFORE|AFTER) 触发事件(INSERT|UPDATE|DELETE)
ON 表名 FOR EACH ROW
BEGIN
执?语句列表;
END $$
DELIMITER $$
说明:
1、 BEFORE和AFTER参数指定了触发执?的时间,在事件之前或是之后。
2、FOR EACH ROW表示任何?条记录上的操作满?触发事件都会触发该触发器,也就是说触发器的触发频率是针对每??数据触发?次。
触发事件参数详解:
1、 INSERT型触发器:插?某??时激活触发器,可能通过INSERT、REPLACE 语句触发;
2、 UPDATE型触发器:更改某??时激活触发器,可能通过UPDATE语句触发;
3、DELETE型触发器:删除某??时激活触发器,可能通过DELETE、REPLACE语句触发。
介绍:
? before INSERT:在添加之前激活触发器
? before DELETE:在删除之前激活触发器
? before UPDATE:在修改之前激活触发器
? after INSERT:在添加之后激活触发器
? after DELETE:在删除之后激活触发器
? after UPDATE:在修改之后激活触发器
3.3、使用
use java0210
CREATE table if not EXISTS user_log(
id int PRIMARY KEY auto_increment comment '日志编号',
log_time datetime comment '时间',
msg varchar(32) comment '日志信息'
)comment '用户日志表';
delimiter $$
create trigger trig1 after insert on user for each row
begin
insert into user_log(log_time,msg) values (now(),'user表中插入了一条数据');
end $$
delimiter $$
desc user;
insert into user(name,age) VALUES('陈爽',27);
SELECT * from user_log;
drop trigger trig1;
delimiter $$
create trigger trig2 after update on user for each row
begin
insert into user_log(log_time,msg) values (now(),concat ('修改前:',old.name,'------修改后:',new.name ));
end $$
delimiter $$
update user set name = '张三' WHERE age = 27;
update user set name = 'lisi' WHERE age = 27;
SELECT * from user_log;
四、存储引擎
4.1、概念
思考:我们在mysql中创建的数据库、表以及表中的数据是保存在哪?的?(都是以?件的形式存储在硬盘上的)
1、在关系型数据库中每?个数据表就对应?个?件,?这些?件是以什么?式存储在硬盘上的就取决于选择的存储引擎类型,不同的存储引擎存储?件的?式也是不?样的。
2、我们可以认为数据库存储引擎是规定数据表如何存储数据,如何为存储的数据建?索引以及如何?持更新、查询等技术的实现。
3、不同的存储引擎提供不同的存储机制、索引技巧、锁定?平等功能,使?不同的存储引擎,还可以获得特定的功能
4、由于在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型,也就是说存储引擎是针对表??的
5、查看MySQL?持的存储引擎类型:show engines
6、查看当前默认的存储引擎类型:show variables like ‘%storage_engine%’
4.2、详解
4.2.1、MyISAM
特点
1、在做插?、查询时速度快,性能?
2、 ?持全?索引,表级锁
3、不?持事务,外键
4、 其数据的物理组织形式是?聚簇表。数据和索引分开存储,顶级节点只存索引,数据都存储在B+树的叶?节点
文件存储格式:
1、tb01.frm:存储tb01表结构信息(表中有哪些列,数据类型等)
2、tb01.MYI:MY表示MYISAM存储引擎,I是index索引,这?存储tb01的索引信息。
3、tb01.MYD:MY表示MYISAM存储引擎,D是data数据,这?存储tb01的数据信息(即表中的记录)
4.2.2、InnoDB
特点
1、?持外键、?持事务
2、?持?级锁,因此在?并发量的情况下效率?
3、不?持全?索引
4、 其数据的物理组织形式是聚簇表。数据和索引放在?块,都位于B+树的叶?节点上。
文件存储格式:
1、xx.frm:同MYISAM存储引擎,也是?来存储表结构信息。
2、ibdata1:共享表空间,且来存储所有InnoDB数据表的数据信息,包含索引信息
4.2.3、指定存储引擎
建表时
create table 表名(
id bigint(12),
name varchar(200)
) ENGINE=MyISAM;
create table 表名(
id int(4),
cname varchar(50)
) ENGINE=InnoDB;
已建表修改
alter table 表名 engine = innodb;
五、索引
5.1、概念
1、索引是?种特殊的?件(InnoDB数据表上的索引是表空间的?个组成部分),它们包含着对数据表?所有记录的引?指针。更通俗的说,数据库索引好?是?本书前?的?录,能加快数据库的查询速度
2、索引分为聚簇索引和?聚簇索引两种
5.2、分类
1、 普通索引 :仅加速查询
2、 唯?索引 :加速查询 + 列值唯?(可以有null)
3、 组合索引 :多列值组成?个索引,
4、主键索引:加速查询 + 列值唯? + 表中只有?个(不可以有null)
5.3、创建索引
1、创建表的时候创建索引
语法:
CREATE TABLE tbl_name(
字段名称 字段类型 [完整性约束条件],
…
? INDEX 索引名称
);
2、在已经存在的表上创建索引:
语法:
1、create index 索引名称 on 表名(字段名)
2、alter table 表名 add index 索引名称(字段名称);
3、查看索引
show index from 表名;
4、 删除索引
drop index 索引名 on 表名;
CREATE TABLE if not EXISTS tb01(
id int PRIMARY KEY,
xx varchar(24),
index xx
)
alter TABLE user add index index_i(name,age);
show index from user;
drop index index_i on user;
5.4、索引使用
1、建议使用
① 主键?动建?唯?索引,任何表?定要建主键
② 频繁作为查询条件的字段应该创建索引
③ 查询中与其它表关联的字段,外键关系建?索引
④ 组合索引的选择问题, 组合索引性价?更?
⑤ 查询中排序的字段,排序字段若通过索引去访问将??提?排序速度
⑥ 查询中统计或者分组字段
2、不建议使用
① 表记录太少
② 经常增删改的表或者字段,因为对表进?INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存?下索引?件。
③ Where条件??不到的字段不创建索引
3、注意事项
① 如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。
② 不在索引列上做任何操作(计算、函数、(?动or?动)类型转换),会导致索引失效?转向全表扫描
③ 存储引擎不能使?索引中范围条件右边的列
④ mysql 在使?不等于(!= 或者<>)的时候?法使?索引会导致全表扫描
⑤ is not null 也?法使?索引,但是is null是可以使?索引的(和?空约束有关系)
⑥ like以通配符开头(‘%abc…’)mysql索引失效会变成全表扫描的操作
⑦ 字符串不加单引号索引失效
六、锁机制
6.1、锁概念
1、锁是计算机协调多个进程或线程并发访问某?资源的机制。
2、在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争?以外,数据也是?种供许多?户共享的资源。如何保证数据并发访问的?致性、有效性是所有数据库必须解决的?个问题,锁冲突也是影响数据库并发访问性能的?个重要因素。从这个?度来说,锁对数据库??显得尤其重要,也更加复杂。
6.2、锁分类
1、从对数据操作的类型(读\写)分
① 读锁(共享锁):针对同?份数据,多个读操作可以同时进??不会互相影响。
② 写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
2、从对数据操作的粒度分
① 表锁
特点:偏向MyISAM存储引擎,开销?,加锁快;?死锁;锁定粒度?,发?锁冲突的概率最?,并发度最低。
② ?锁
特点:
1). 偏向InnoDB存储引擎,开销?,加锁慢;会出现死锁;锁定粒度最?,发?锁冲突的概率最低,并发度也最?。
2).InnoDB与MyISAM的最?不同有两点:?是?持事务(TRANSACTION);?是采?了?级锁
3、从锁的用法分
【悲观锁】
我们使?悲观锁的话其实很简单(?动加?锁就?了):select * from xxxx for update,在select 语句后边加了for update相当于加了排它锁(写锁),加了写锁以后,其他事务就不能对它修改了!需要等待当前事务修改完之后才可以修改.也就是说,如果操作1使?select … for update,操作2就?法对该条记录修改了,即可避免更新丢失。
【乐观锁】
乐观锁不是数据库层?上的锁,需要?户?动去加的锁。?般我们在数据库表中添加?个版本字段version来实现,例如操作1和操作2在更新User表的时,执?语句如下:
update A set Name=lisi,version=version+1 where ID=#{id} and version=#{version},此时即可避免更新丢失。
【间隙锁 GAP】
当我们?范围条件检索数据?不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合范围条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在 的记录,叫做“间隙(GAP)”。
InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁。
–例?:假如emp表中只有101条记录,其empid的值分别是1,2,…,100,101
Select * from emp where empid > 100 for update;
上?是?个范围查询,InnoDB不仅会对符合条件的empid值为101的记录加锁,也会对empid?于101(这些记录并不存在)的“间隙”加锁
InnoDB使?间隙锁的?的有2个:
为了防?幻读(上?也说了,Repeatable read隔离级别下再通过GAP锁即可避免了幻读)
满?恢复和复制的需要:MySQL的恢复机制要求在?个事务未提交前,其他并发事务不能插?满?其锁定条件的任何记录,也就是不允许出现幻读
【死锁】
1、产?原因
所谓死锁:是指两个或两个以上的进程在执?过程中,因争夺资源?造成的?种互相等待的现象,若?外?作?,它们都将?法推进下去.此时称系统处于死锁状态或系统产?了死锁,这些永远在互相等待的进程称为死锁进程。表级锁不会产?死锁.所以解决死锁主要还是针对于最常?的InnoDB。
死锁的关键在于:两个(或以上)的Session加锁的顺序不?致。
那么对应的解决死锁问题的关键就是:让不同的session加锁有次序
2、产生实例
需求:将投资的钱拆成?份随机分配给借款?。
起初业务程序思路是这样的:
投资?投资后,将?额随机分为?份,然后随机从借款?表??选?个,然后通过?条条select for
update 去更新借款?表??的余额等。
【例如】:两个?户同时投资,A?户?额随机分为2份,分给借款?1,2
B?户?额随机分为2份,分给借款?2,1,由于加锁的顺序不?样,死锁当然很快就出现了。
对于这个问题的改进很简单,直接把所有分配到的借款?直接?次锁住就?了。
Select * from xxx where id in (xx,xx,xx) for update
在in??的列表值mysql是会?动从?到?排序,加锁也是?条条从?到?加的锁
|