MySQL的基础学习(四)

一、视图

视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。

  • 视图(view) 是一个虚拟表,非真实存在,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用视图名称即可获取结果集,并可以将其当作表来使用
  • 数据库中只存放了视图的定义,而并没有存放视图中的数据。这些数据存放在原来的表中。
  • 使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。因此,视图中的数据是依赖于原来的表中的数据的。一旦表中的数据发生改变,显示在视图中的数据也会发生改变。

视图优势:

  • 操作简单
  • 减少数据冗余
  • 数据安全
  • 适应多变的需求
  • 能够分解复杂的查询逻辑

语法:

CREATE [OR REPLACE] [ALGORITHM ={UNDEFINED|MERGE|TEMPTABLE}] VIEW view_name [(字段列表)]
AS 
select 查询语句
[WITH [CASCADED |LOCAL] CHECK OPTION]

说明:

  • algorithm: 可选项,表示视图选择的算法,
    • Merge:当引用视图时, 引用视图的语句与定义视图的语句合并
    • Temptable:当引用视图时, 根据视图的创建语句建立一个临时表
    • undefined: 未定义,自动让系统帮你选
  • view_name :表示要创建的视图名称。
  • column_list: 可选项,指定视图中各个属性的名词,默认情况下与SELECT语句中的查询的属性相同。
  • select查询语句: 表示一个完整的查询语句,将查询记录映射到视图中。
  • [with [cascaded | local] check option]:可选项,表示更新视图时要保证在该视图的权限范围之内

1. 单表视图

  • 基于bemp构建视图,数据列只有id,name。
create or replace algorithm=temptable view v_emp(id,username)
as
select id,name
from bemp;
desc bemp;
select * from bemp;
desc v_emp;
select * from v_emp;
  • 基于bemp员工表构建视图,要求有编号、名字、薪水和年薪.
create view v_emp1
as
select id,name,salary,salary*30
from bemp;
  • 基于v_emp1构建视图,只需要名字和薪水
create view v_emp_new
as
select name,salary*30 as yearSal
from v_emp1;

2. 多表视图

  • 构建视图v_emp_dept, 能查询员工信息及所属部门
create table v_emp_dept
as
select concat(e.name,'(',d.name,')') as username,e.salary,e.dept_id,d.name dept_name
from bemp e,bdept d
where e.dept_id=d.id;

3. 视图操作语法

  • 查看当前数据库下的视图
    show tables;
  • 查看视图的结构
    desc view_name;describe view_name;
  • 删除视图
    drop view if exists view_name;
  • 修改视图
alter view view_name
as
select 查询语句
  • 重命名视图
    rename table old_view_name to new_view_name;

4. 视图更新

视图是可更新的。也就是说,可以在UPDATE、 DELETE或INSERT等 语句中使用它们,以更新基表的内容。
对于可更新的视图,在视图中的行和基表中的行之间必须具有一对一的关系。

如果视图包含下述结构中的任何一种,那么它就是不可更新的:

  • 聚合函数(SUM(), MIN), MAX(), COUNT()等)
  • select查询列表有数学表达式
  • DISTINCT
  • UNION或UNION ALL
  • 位于选择列表中的子查询
  • GROUP BY
  • HAVING
  • JOIN
  • 常量视图

对基表(数据表)进行更新改会影响视图
案例:

  • 基于bemp构建视图,显示编号和名字,并对数据修改
create view v_bemp
as
select id,name
from bemp;
insert into v_bemp values(6,'briup');
update v_bemp set name='zhaosi' where id=4;

二、索引

索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表, 直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,而不必查看所有数据,那么将会节省很大一部分时间。如:索引类似一本书的目录,比如要查找’briup’这个单词,可以先找到b开头的页然后向后查找,这个就类似索引。

索引的优点:

  • 大大加快数据的查询速度
  • 使用分组和排序进行数据查询时,可以显著减少查询时分组和排序的时间
  • 创建唯一索引,能够保证数据库表中每一行数据的唯一性
  • 在实现数据的参考完整性方面,可以加速表和表之间的连接

索引的缺点:

  • 创建索引和维护索引需要消耗时间,并且随着数据量的增加,时间也会增加
  • 索引需要占据磁盘空间
  • 对数据表中的数据进行增加,修改,删除时,索引也要动态的维护,降低了维护的速度

创建原则:

  • 对where和orderby涉及的列上尽量建立索引
  • 更新频繁的列不应设置索引
  • 数据量小的表不要使用索引
  • 重复数据多的字段不应设为索引(如性别,只有男和女),重复的数据超过百分之15就不该建索引。

1. 原理

1.1 Hash算法

哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值, 并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。在MySQL中, 只有Memory引擎显式支持哈希索引。这也是Memory引擎表的默认索引类型,Memory引擎同时也支持B-Tree索引。需然常见存储引擎并不支持Hash索引,但InnoDB有另一种实现方法:自适应哈希索引。InnoDB存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引。

通过字段的值计算的hash值,定位数据非常快。但是不能进行范围查找,因为散列表中的值是无 序的,无法进行大小的比较。

1.2 二叉树

二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点,都满足其左子树上所有结点的数据域均小于或等于根结点的数据域右子树上所有结点的数据域均大于根结点的数据域。使用二叉树可以提高查询数据的速度,但是有可能产生不平衡类似于链表的结构。

1.3 平衡二叉树

平衡二叉树是采用二分法思维把数据按规则组装成一个树形结构的数据,用这个树形结构的数据减少无关数据的检索,大大的提升了数据检索的速度,其特点:

  • 它的左子树和右子树都是平衡二叉树
  • 左子树比中间小,右子树比中间值
  • 左子树和右子树的深度之差的绝对值不超过1

平衡二叉树插入操作需要旋转,支持范围查询,但回旋查询效率较低,比如要查找大于8的,会回旋到父节点7、10。如果存放百万条数据的情况下,树高度越高,查询效率会越慢。

1.4 BTree

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构,Btree结构可以有效的解决之前的相关算法遇到的问题。
(1)B-Tree
在这里插入图片描述
(2)B+Tree
在这里插入图片描述

2. 操作

2.1 按实现的方式进行分类

  • Hash索引
  • B+ Tree索引

2.2 按照功能划分

2.2.1 单列索引

(1)普通索取
语法:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tb_name [(
字段1 数据类型 [约束条件] [默认值] [COMMENT '注解'],
字段2 数据类型 [约束条件] [默认值] [COMMENT '注解'],
字段3 数据类型 [约束条件] [默认值] [COMMENT '注解'],
 ......
[表约束条件]
index index_name(col_name...)
......
)][engine=innodb] [default charset=utf8];

create index index_name on tb_name(col_name);

alter table tb_name add index index_name(col_name);

案例:

  • 创建教师表,并指定普通索引
create table tea(
id int primary key auto_increment,
name varchar(20),
age int,
index index_name(name)
);
  • 创建教师表之后在构建索引
create table tea1(
id int primary key auto_increment,
name varchar(20),
age int
);
create index index_name on tea1(name);
  • 创建教师表之后在构建索引
create table tea2(
id int primary key auto_increment,
name varchar(20),
age int
);
alter table tea2 add index index_name(name);
  • 查看briup数据库中的所有索引
select *
from mysql.innodb_index_stats
where database_name='briup';

说明:

  • database_name:数据库的名字
  • table_name: 表名
  • index_name:索引名字
  • table_name:表名
  • stat_name:统计信息名称,其对应的值保持在stat_value
    • size: stat_value表示索引中的总页的数量
    • n_leaf_ pages: stat_value表示索引叶子页的数量
    • n_diff_pfxNN: (NN代表数字)stat_value表示索引的Frist column列的唯一数量,列如NN表示02:第一个和第二个列组合索引的唯一值数量
  • stat_value: 保存stat_ name的字段对应统计信息值
  • sample_size: stat_value字段提供的统计信息值的采样页数
  • stat_description: 统计信息名称stat_name字段中指定的统计信息的说明
  • 查看briup数据库中教师表中所有索引
select *
from mysql.innodb_index_stats
where database_name='briup' and table_name='tea';
  • 查看briup数据库中教师表中所有索引
show index from tea;

说明:

  • table表名称

  • non_unique如果索引不能包括重复词,为0,如果可以,则为1

  • key_name索引的名称

  • seq_in_index索引中的列序号

  • column_name列名称

  • collation 列以什么方式存储在索引中,在mysql中,有值’A’ (升序)或者NULL (无分类)

  • cardinality 索引在唯-值的数据的估值,通过运行analyze table xxx_table; 或者myisamchk -a可以更新,技术根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没必要是精确的,基数越大,当进行联合s时,mysql使用该索引的机会越大。myisam中,该值是准确的,INNODB中该值数据是估算的,存在偏差

  • sub_part如果列只是部分的编入索引则为被编入索引的字符的数目,如果整列被编入索引,则为NULL

  • packed指示关键词如何被压缩,如果没有被压缩,则为NULL

  • NULL如果列含有NULL,则含有YES,如果没有,则该例为NO

  • index_type用过的索引方法(BTREE,FULLTEXT,HASH,RTREE)

  • comment 备注

  • index_comment为索引创建时提供了一个注释属性的索引的任何评论

  • 删除tea表中索引

drop index index_name on tea

alter table tea drop index index_name;

(2)主键索引
创建表时,MySQL会自动在主键列上建立一个索引,这就是主键索引。主键是具有唯- -性并且不允许为.NULL
案例:

  • 创建教师表tea4,设置id为主键索引
create table tea4(
id int primary key auto_increment,
name varchar(20),
age int
);

create table tea4(
id int,
name varchar(20),
age int
);
alter table tea4 add primary key(id);

(3)唯一索引
唯一索引与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
案例:

  • 创建教师表tea3, name为唯一索引
create table tea3(
id int primary key auto_increment,
name varchar(20),
age int,
unique index_name(name)
);

create table tea3(
id int primary key auto_increment,
name varchar(20),
age int
);
create unique index index_name on tea3(name);

create table tea3(
id int primary key auto_increment,
name varchar(20),
age int
);
alter table tea3 add unique index_name(name);
2.2.2 组合索引

组合索引也叫复合索引,指的是我们在建立索引的时候使用多个字段,例如同时使用身份证和用户编号建立索引,同样的可以建立为普通索引或者是唯一索引或者主键索引。 复合索引的使用复合最左原则。
案例:

  • 创建教师表tea5,设置id和名字为组合索引
create table tea5(
id int,
name varchar(20),
age int,
index index_name(id,name)
);

create table tea5(
id int,
name varchar(20),
age int
);
create index index_name on tea5(id,name);

create table tea5(
id int,
name varchar(20),
age int
);
alter table tea5 add index index_name(id,name);
2.2.3 全文索引

全文索引的关键字是fulltext,全文索引主要用来查找文本中的关键字,而不是直接与索引中的值相比较,它更像是一个搜索引擎,基于相似度的查询,而不是简单的where语句的参数匹配

要求如下;

  • MySQL 5.6以前的版本,只有MyISAM存储引擎支持全文索引
  • MySQL 5.6及以后的版本,MyISAM和InnoDB存储弓|擎均支持全文索引
  • 只有字段的数据类型为char、varchar、 text 及其系列才可以建全文索引
  • 在数据量较大时候,现将数据放入-个没有全局索引的表中,然后再用create index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多

索引变量:
MySQL中的全文索引,有两个变量,最小搜索长度最大搜索长度,对于长度小于最小搜索长度和大于最大搜索长度的词语,都不会被索引。通俗点就是说,想对一个词语使用全文索引搜索,那么这个词语的长度必须在以上两个变量的区间内。

参数名称默认值最小值最大值作用
ft_min_word_len413600MyISAM引擎表全文索引包含的最小词长度
ft_query_expansion_limit2001000MyISAM引擎表使用with query expansion进行全文搜索的最大匹配数
innodb_ft_min_token_size3016InnoDB引擎表全文索引包含的最小词长度
innodb_ft_max_token_size841084InnoDB引擎表全文索引包含的最大词长度

全文检索语法:
match (col_name1,col_name2,...) against(expr [search_modifier])

案例:

  • 查看索引变量
show variables like '%ft%';
  • 创建表Poetry, 收录诗歌。
create table Poetry(
id int primary key auto_increment,
name varchar(20),
content text,
fulltext(content)
);

create table Poetry(
id int primary key auto_increment,
name varchar(20),
content text
);
create fulltext index index_content on Poetry(content);

create table Poetry(
id int primary key auto_increment,
name varchar(20),
content text
);
alter table Poetry add fulltext index_content(content);
insert into Poetry values(1,'rain','Rain is falling all around');
insert into Poetry values(2,'rain','It falls on field and tree');
insert into Poetry values(3,'rain','It rains on the umbrella here');
insert into Poetry values(4,'rain','And on the ships at sea');
  • 基于全文检索查询含有And内容
select *
from Poetry
where match(content) against('And');
2.2.4 空间索引
  • MySQL在5.7之后的版本支持了空间索引,而且支持OpenGIS几何数据模型
  • 空间索引是对空间数据类型的字段建立的索引,
  • MYSQL使用SPATIAL关键字进行扩 展,使得能够用于创建正规索引类型的语法创建空间索引。
  • 创建空间索引的列,必须将其声明为NOT NULL。

数据类型:

类型含义说明
Geometry空间数据任何一种空间类型
Point坐标值
LineString线有一系列点连接而成
Polygon多边形由多条线组成

三、存储过程

存储过程的英文是Stored Procedure。它的思想很简单,就是一组经过预先编译的SQL语句的封装。执行过程:存储过程预先存储在MySQL服务器上,需要执行的时候,客户端只需要向服务器端发出调用存储过程的命令,服务器端就可以把预先存储好的这一系列SQL语 句全部执行。
语法:

CREATE PROCEDURE 参数名(IN |OUT |INOUT ݇参数类型, . . . )
[LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string ' ]
BEGIN
存储过程体
END

说明:

  • IN:当前参数为输入参数,也就是表示入参, 默认就是IN
  • OUT: 当前参数为输出参数,也就是表示出参
  • INOUT: 当前参数既可以为输入参数,也可以为输出参数
  • characteristics: 存储过程时指定的约束条件
    • LANGUAGE SQL:存储过程执行体是由SQL语句组成的,目前只支持SQL
    • DETERMINISTIC: 表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出
    • NOT DETERMINISTIC: 结果是不确定的,相同的输入可能得到不同的输出,默认
    • CONTAINS SQL :存储过程的子程序包含SQL语句,但是并不包含读写数据的SQL语句,默认
    • NO SQL:储过程的子程序中不包含任何SQL语句
    • READS SQL DATA: 存储过程的子程序中包含读数据的SQL语句
    • MODIFIES SQL DATA:存储过程的子程序中包含写数据的SQL语句
    • SQL SECURITY DEFINER: 存储过程的创建者或者定义者才能执行当前存储过程,默认
    • SQL SECURITY INVOKER :存储过程的访问权限的用户能够执行当前存储过程
    • COMMENT'string': 注释信息,可以用来描述存储过程

存储过程优势

  • 良好的封装性
  • 存储过程可以一次编译多次使用
  • 可以减少开发工作量
  • 存储过程的安全性强
  • 可以减少网络传输量

存储过程缺点

  • 可移植性差
  • 存储过程的版本管理很困难,调试困难
  • 它不适合高并发的场景

结束标记
MySQL默认的语句结束符号为分号;。为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符。
语法:

DELIMITER 新的结束标记

案例:

  • 创建存储过程select_data(), 查看员工表的员工编号小于10的数据
delimiter $
create procedure select_data()
begin
select id,last_name,salary from s_emp where id<10;
end $
-- 存储过程的调用
call select_data()$
  • 创建存储过程avg_emp_salary(), 返回所有员工的平均工资
delimiter $
create procedure avg_emp_salary()
begin
select avg(salary) from s_emp;
end $
-- 存储过程的调用
call avg_emp_salary()$
  • 创建存储过程show_max_salary(), 用来查看员工表的最高薪资值
delimiter $
create procedure show_max_salary()
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '๋最高薪资值'
begin
select max(salary) from s_emp;
end $
-- 存储过程的调用
call show_max_salary()$
  • 创建存储过程show_min_salary(), 查看员工表的最低薪资值。并将最低薪资通过0UT参数minsal输出
delimiter $
create procedure show_min_salary(out minsal float)
begin
select min(salary) into minsal from s_emp;
end $
-- 存储过程的调用 @msal声明变量
call show_min_salary(@msal)$
-- 取出存储过程的返回值
select @msal$
  • 创建存储过程show_someone_salary(), 查看员工表的某个员工的薪资,并用输入员工姓名,返回员工薪资
delimiter $
create procedure show_someone_salary(in name varchar(20),out sal float)
begin
select salary into sal from s_emp where last_name=name;
end $
-- 存储过程的调用 @sal声明变量
call show_someone_salary('Smith',@sal)$
select @sal$
  • 创建存储过程show_mgr_name(), 查询某个员工领导的姓名,输入员工姓名,输出领导的姓名
delimiter $
create procedure show_mgr_name(inout name varchar(20))
begin
select last_name into name
from s_emp s
where s.id=(select manager_id from s_emp where last_name=name);
end $
set @name='Smith'$
-- 存储过程的调用
call show_mgr_name(@name)$
select @name$
  • 创建存储过程,实现累加运算,计算1+2+ …n等于多少;
delimiter $
create procedure add_num(inout n int)
begin
-- 变量的声明
declare i int;
declare sum int;
-- 变量的赋值
set i = 1 ;
set sum = 0 ;
while i <= n do
set sum = sum + i ;
set i = i +1 ;
end while ;
set n=sum;
end $
set @n=100$
call add_num(@n)$
select @n$

存储过程查看删除

案例:

  • 查看存储过程add_num创建信息
show create procedure add_num\G;
  • 查看以add开头存储过程状态信息
show procedure status like 'add%'\G;
  • 删除存储过程
drop procedure add_num;

四、触发器

MySQL从5.0.2版本开始支持触发器, MySQL的触发器和存储过程一样, 都是嵌入到MySQL服务器的一段程序。触发器是由事件来触发某个操作,这些事件包括INSERT、UPDATE、DELETE事件。 所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句时候,就相当于事件发生了,就会自动激发触发器执行相应的操作。当对数据表中的数据执行插入、更新和删除操作,需要自动执行一-些数据库逻辑时,可以使用触发器来实现。
语法:

create trigger 触发器名称
{before |after} {insert |update |delete} ON tb_name
for each row
begin
sql语句
.....
end

说明:

  • tb_ name:表示触发器监控的对象
  • before |after:表示触发的时间。BEFORE 表示在事件之前触发; AFTER 表示在事件之后触发
    • insert 表示插入记录时触发
    • update表示更新记录时触发
    • delete 表示删除记录时触发

触发器优点

  • 触发器可以确保数据的完整性
  • 触发器可以帮助我们记录操作日志
  • 触发器还可以用在操作数据前,对数据进行合法性检查

触发器缺点

  • 触发器最大的一个问题就是可读性差
  • 相关数据的变更,可能会导致触发器出错

案例:

  • 创建触发器,监控订单表,当订单表插入数据的时候,对应库存表删除数据。

库存表:

create table goods(
id int primary key,
good_name varchar(50),
kc int
);
insert into goods values(1,'电脑',50),(2,'手机',50),(3,'自行车',50);

订单表:

create table order1(
id int primary key,
good_id int ,
num int,
foreign key(good_id) references goods(id)
);

触发器:

delimiter $
create trigger tg1
after insert on order1
for each row
begin
update goods set kc = kc-new.num
where id = new.good_id;
end$

订单插入数据:

insert into order1 values(1,1,2);

(1)查看触发器
案例:

  • 查看当前数据库的所有触发器
show triggers\G;
  • 查看当前数据库中某个触发器的的创建过程
show create trigger tg1;
  • 系统库information_schema的TRIGGERS表中查询触发器的信息
select * from information_schema .triggers ;

(2)触发器删除
案例:

  • 删除触发器tg1;
drop trigger if exists tg1;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值