MySql高级知识总结

Num01-->mysql账户管理

Test01-->定义

在生产环境下操作数据库时,绝对不可以使用root账户连接,而是创建特定的账户,授予这个账户特定的操作权限,然后连接进行操作,主要的操作就是数据的crud

MySQL账户体系:根据账户所具有的权限的不同,MySQL的账户可以分为以下几种

1、服务实例级账号:启动了一个mysqld,即为一个数据库实例;如果某用户如root,拥有服务实例级分配的权限,那么该账号就可以删除所有的数据库、连同这些库中的表

2、数据库级别账号:对特定数据库执行增删改查的所有操作

3、数据表级别账号:对特定表执行增删改查等所有操作

4、字段级别的权限:对某些表的特定字段进行操作

5、存储程序级别的账号:对存储程序进行增删改查的操作

6、账户的操作主要包括创建账户、删除账户、修改密码、授于权限等

注意:进行账户操作时,需要使用root账户登录,这个账户拥有最高的实例级权限

Test02-->授予权限

需要使用实例级账户登录后操作,以root为例
常用权限主要包括:create、alter、drop、insert、update、delete、select
如果分配所有权限,可以使用all privileges

创建账户并授权
语法如下:
grant 权限列表 on 数据库 to '用户名'@'访问主机' identified by '密码';

授权
语法如下:
grant 权限名称 on 数据库 to 账户1,账户2,... with grant option;

示例:
step1:使用root登录
mysql -uroot -p
回车后写密码,然后回车

step2:创建账户并授予所有权限,说明如下
用户名为py1,密码为123
操作python数据库的所有对象python.*
访问主机通常使用百分号%表示此账户可以使用任何ip的主机登录访问此数据库
访问主机可以设置成localhost或具体的ip,表示只允许本机或特定主机访问
grant all privileges on python.* to 'py1'@'%' identified by '123';

step3:退出root的登录
quit

step4:使用py1账户登录
mysql -u py1 -p
回车后写密码,然后回车

Test03-->回收权限

需要使用实例级账户登录后操作,以root为例
如果不希望某用户拥有此权限,可以将此权限从用户上撤销
语法如下:
revoke 权限列表 on 数据库名.* from  '用户名'@'主机';

示例
step1:使用py1登录后,向表classes中插入数据python3
use python;
insert into classes(name) values('python3');

step2:退出py1
quit
使用root登录
mysql -uroot -p
回车后写密码,然后回车

step3:回收insert权限
revoke insert on python.* from 'py1'@'%';

step4:退出root
quit

step5:使用py1账户登录
mysql -u py1 -p
回车后写密码,然后回车

step6:向表classes中插入数据python3,就会报错
use python;
insert into classes(name) values('python3');

Test04-->账户操作

需要使用实例级账户登录后操作,以root为例
主要操作包括:
查看所有用户
修改密码
删除用户

1、查看所有用户
所有用户及权限信息存储在mysql数据库的user表中
查看user表的结构
desc user\G;

主要字段说明:
host表示允许访问的主机
user表示用户名
authentication_string表示密码,为加密后的值
查看所有用户
select host,user,authentication_string from user;

2、修改密码
语法1:不需登录
mysqladmin -u py1 -p password '新密码'
例:
mysqladmin -u py1 -p password '123456'
回车后写密码,然后回车
语法2:使用root登录,修改mysql数据库的user表
使用password()函数进行密码加密
注意修改完成后需要刷新权限
update user set authentication_string=password('新密码') where user='用户名';
例:
update user set authentication_string=password('123') where user='py1';

刷新权限:flush privileges
语法1用于账户自己修改密码
语法2用于修改自己或其它账户的密码,一般是dba或经理修改员工的密码

3、删除账户
语法1:使用root登录
drop user '用户名'@'主机';
例:
drop user 'py1'@'%';
语法2:使用root登录,删除mysql数据库的user表中数据
delete from user where user='用户名';
例:
delete from user where user='py1';
推荐使用语法1删除用户
如果主机的字母大写时,使用语法1删除失败,采用语法2方式

Num02-->mysql存储过程

Test01-->定义

存储过程,也翻译为存储程序,是一条或者多条SQL语句的集合,可以视为批处理,但是其作用不仅仅局限于批处理

Test02-->mysql创建存储过程

语法如下
delimiter //
create procedure 存储过程名称(参数列表)
begin
sql语句
end
//
delimiter ;
说明:delimiter用于设置分割符,默认为分号
在“sql语句”部分编写的语句需要以分号结尾,此时回车会直接执行,所以要创建存储过程前需要指定其它符号作为分割符,此处使用//,也可以使用其它字符

示例
要求:创建查询过程,查询学生信息
step1:设置分割符
delimiter //
step2:创建存储过程
create procedure proc_stu()
begin
select * from students;
end
//
step3:还原分割符
delimiter ;

Test03-->mysql查看存储过程

所有存储过程和函数,都存储在mysql数据库下的proc表中
查看表结构
desc mysql.proc\G;

主要字段说明:
name表示名称
type表示类型,为存储过程、函数
body表示正文脚本
db表示属于的数据库

查看python数据库的所有存储过程
select name,type,body from mysql.proc where db='python';

Test04-->mysql调用存储过程

语法如下
call 存储过程(参数列表);

示例:
要求:调用存储过程proc_stu
call proc_stu();

Test05-->mysql删除存储过程

语法如下
drop procedure 存储过程名称;
说明:存储过程内部的sql语句无法修改,如果之前创建的存储过程不能满足要求,可以删除后重新创建

示例:
要求:删除存储过程proc_stu
drop procedure proc_stu;

Num03-->mysql函数

Test01-->mysql创建函数

语法如下
delimiter $$
create function 函数名称(参数列表) returns 返回类型
begin
sql语句
end
$$
delimiter ;
说明:delimiter用于设置分割符,默认为分号
在“sql语句”部分编写的语句需要以分号结尾,此时回车会直接执行,所以要创建存储过程前需要指定其它符号作为分割符,此处使用//,也可以使用其它字符
示例

要求:创建函数py_trim,用于删除字符串左右两侧的空格

step1:设置分割符
delimiter $$

step2:创建函数
create function py_trim(str varchar(100)) returns varchar(100)
begin
declare x varchar(100);
set x=ltrim(rtrim(str));
return x;
end
$$

step3:还原分割符
delimiter ;

Test02-->mysql查看函数

所有函数存储在mysql数据库下的proc表中
说明:存储过程与函数都存储在proc表中,区别在type字段,func表中无数据

查看python数据库中的函数
select name,type from mysql.proc where db='python';

Test03-->mysql函数调用

语法如下
select 函数名称(参数列表);

示例
要求:调用自定义函数py_trim
select py_trim(' a ');

Test04-->mysql函数删除

说明:函数的代码无法修改,如果不能满足要求可以删除后重新创建
语法如下
drop function 函数名称;

示例
要求:删除函数py_trim
drop function py_trim;

Test05-->mysql函数变量

声明变量,语法如下
declare 变量名 类型 default 默认值;

例:
declare x varchar(100);
设置变量值,语法如下
set 变量名=值;

例:
set x='abc';
使用变量:将变量写到表达式中,即可调用变量的值

Test06-->mysql函数判断

语法如下
if 条件1 then
语句1;
elseif 条件2 then
语句2;
else
语句
end if;

Test07-->mysql函数循环

语法如下
while 条件 do
语句;
end while;

退出循环:leave,相当于break
退出本次循环:iterate,相当于continue

Num04-->mysql视图

对于复杂的查询,在多个地方被使用,如果需求发生了改变,需要更改sql语句,则需要在多个地方进行修改,维护起来非常麻烦
解决:定义视图
视图本质就是对查询的封装
定义视图,建议以v_开头
create view 视图名称 as select语句;

例:创建视图,查询学生对应的成绩信息
create view v_stu_sco as 
select students.*,scores.score from scores
inner join students on scores.stuid=students.id;

查看视图:查看表会将所有的视图也列出来
show tables;

删除视图
drop view 视图名称;

例:
drop view v_stu_sco;

使用:视图的用途就是查询
select * from v_stu_score;

Num05-->mysql事务

Test01-->定义

为什么要有事务

事务广泛的运用于订单系统、银行系统等多种场景
例如:A用户和B用户是银行的储户,现在A要给B转账500元,那么需要做以下几件事:
检查A的账户余额>500元;
A账户扣除500元;
B账户增加500元;
正常的流程走下来,A账户扣了500,B账户加了500,皆大欢喜。那如果A账户扣了钱之后,系统出故障了呢?A白白损失了500,而B也没有收到本该属于他的500。以上的案例中,隐藏着一个前提条件:A扣钱和B加钱,要么同时成功,要么同时失败。事务的需求就在于此
事务(Transaction)是并发控制的基本单位。所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行。所以,应该把他们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性
事务四大特性(简称ACID)

原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行
一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致
隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的
持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障
事务命令

要求:表的引擎类型必须是innodb类型才可以使用事务,这是mysql表的默认引擎
查看表的创建语句,可以看到engine=innodb
show create table students;
修改数据的命令会触发事务,包括insert、update、delete

开启事务,命令如下:

开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中
begin;
提交事务,命令如下
将缓存中的数据变更维护到物理表中
commit;
回滚事务,命令如下:
放弃缓存中变更的数据
rollback;

Test02-->提交

为了演示效果,需要打开两个终端窗口,使用同一个数据库,操作同一张表
step1:连接
终端1:查询学生信息
select * from students;

step2:增加数据
终端2:开启事务,插入数据
begin;
insert into students(sname) values('张飞');
终端2:查询数据,此时有新增的数据
select * from students;

step3:查询
终端1:查询数据,发现并没有新增的数据
select * from students;

step4:提交
终端2:完成提交
commit;

step5:查询
终端1:查询,发现有新增的数据
select * from students;

Test03-->回滚

为了演示效果,需要打开两个终端窗口,使用同一个数据库,操作同一张表

step1:连接
终端1
select * from students;

step2:增加数据
终端2:开启事务,插入数据
begin;
insert into students(sname) values('张飞');
终端2:查询数据,此时有新增的数据
select * from students;

step3:查询
终端1:查询数据,发现并没有新增的数据
select * from students;

step4:回滚
终端2:完成回滚
rollback;

step5:查询
终端1:查询数据,发现没有新增的数据
select * from students;

Num06-->mysql索引

思考:在图书馆中是如何找到一本书的?
一般的应用系统对比数据库的读写比例在10:1左右,而且插入操作和更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重
当数据库中数据量很大时,查找数据会变得很慢

优化方案:索引
主键和唯一索引,都是索引,可以提高查询速度

主键是数据物理存储的位置
索引会单独创建一个目录,对应数据的位置

索引分单列索引和组合索引
单列索引,即一个索引只包含单个列,一个表可以有多个单列索引
组合索引,即一个索引包含多个列

语法
查看索引
show index from 表名;

创建索引
如果指定字段是字符串,需要指定长度,建议长度与定义字段时的长度一致
字段类型如果不是字符串,可以不填写长度部分
create index 索引名称 on 表名(字段名称(长度))

删除索引:
drop index 索引名称 on 表名;
缺点
虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件
建立索引会占用磁盘空间的索引文件
示例
创建测试表testindex
create table test_index(title varchar(10));
向表中加入十万条数据
创建存储过程proc_test,在存储过程中实现插入数据的操作

step1:定义分割符
delimiter //

step2:定义存储过程
create procedure proc_test()
begin
declare i int default 0;
while i<100000 do
insert into test_index(title) values(concat('test',i));
set i=i+1;
end while;
end //

step3:还原分割符
delimiter ;
执行存储过程proc_test
call proc_test();
查询
开启运行时间监测:
set profiling=1;
查找第1万条数据test10000
select * from test_index where title='test10000';
查看执行的时间:
show profiles;
为表title_index的title列创建索引:
create index title_index on test_index(title(10));
执行查询语句:
select * from test_index where title='test10000';
再次查看执行的时间
show profiles;

你可能感兴趣的:(MySql高级知识总结)