数据库的目标是为了数据的集中管理和共享。但是数据库中的数据针对不同的人本就应该有不同的访问权限,以下就是对数据访问管理的概况。
MySQL的用户分两类:
MySQL的用户信息是存放在数据库mysql的user表中的。
因此,在MySQL中,对用户的管理,既可以使用MySQL特定的语句,也可以使用标准的SQL语句,当然前提是拥有相关权限。
用户信息存放在数据库mysql中的user表中。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sakila |
| sys |
| world |
+--------------------+
10 rows in set (0.01 sec)
mysql> use mysql;
Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| .... |
| user |
+---------------------------+
33 rows in set (0.03 sec)
mysql> desc user;
// 查看user表结构
// 这里重点关注三个字段:
// host:可以登录数据库的主机地址
// user:用户名
// authentication_string:加密过的登陆密码
// _priv 结尾的字段:表明用户的权限
基本语法:
create user 用户名@主机名
//用户名区分大小写,主机名连接来自的主机;百分符表示一组主机,localhost表示本地主机
[ identified by [password] ‘密码’]
//密码区分大小写;password省略则自动用密码函数进行加密,不省略则用加密函数后的明文作为密码
[ , 用户名@主机名[identified by [password][‘密码’]] [ ,... ]
//可以同时创建多个数据库用户,中间用逗号分隔。
实践:
mysql> create user cat@localhost identified by 'cat123';
Query OK, 0 rows affected (0.02 sec)
mysql> select host,user,authentication_string from user;
+-----------+------------------+------------------------------------------------------------------------+
| host | user | authentication_string |
+-----------+------------------+------------------------------------------------------------------------+
| localhost | cat | $A$005$I3X*!v/Uf2+Ef^pBk08rUDb.7YBIitg3KJ622TocHgkbzQCHzfLTLy117 |
+-----------+------------------+------------------------------------------------------------------------+
mysql> exit
GRANT语句给用户分配权限
基本语法:
grant 权限类别//权限类别表示各类权限,用逗号隔开;
on 数据库名.表名
to 用户名@主机名
[,用户名@主机名] [,...]
实践证明貌似Grant语句在8.0.18版本里不能添加用户,只能附加权限。
修改用户名
rename user 旧用户名@主机名 to 新用户名@主机名;
mysql> rename user cat@localhost to mouse@localhost;
Query OK, 0 rows affected (0.02 sec)
//要为现有帐户分配或更改密码,请将该 ALTER USER语句与以下IDENTIFIED BY子句一起使用 :
ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';
//如果您不是以匿名用户身份连接的,则可以更改自己的密码,而无需直接命名自己的帐户:
ALTER USER USER() IDENTIFIED BY 'password';
删除用户
drop user 用户名[,..]
drop user mouse@localhost;
MySql中权限表:
表 | 介绍 |
---|---|
user | 最重要的权限表,存储允许连接到服务器的账号。 |
db | 存储用户对某个数据库的操作权限。 |
host | 存储某个主机对数据库的操作权限。 |
tables_priv | 对单个表进行权限设置。 |
columns_priv | 对单个数据列进行权限设置。 |
proc_priv | 对存储过程和存储函数进行权限设置。 |
重点补充:
MySQL的访问控制的两个阶段
权限的递进:先检查user表、然后db、host,再…直到conlumns_priv中都没有,就拒绝请求。
MySQL权限等级:
user
。db
与host
。tables_priv
。columns_priv
。proc_priv
。MySQL权限类型
权限 | 含义 |
---|---|
all[privileges] | 设置除grant option之外的所有简单权限 |
alter | 允许使用alter table |
alter routine | 更改或取消已存储的子过程 |
create | 允许使用create table |
create routine | 创建已存储的子过程 |
create temporary table | 允许使用create temporary table |
create user | 允许使用create user, drop user, rename,user 和 revoke all privileges |
create view | 允许使用create view |
delete | 允许使用delete |
drop | 允许使用drop table |
execute | 允许用户运行已存储的子程序 |
file | 允许使用select…into outfile 和 load data infile |
index | 允许使用create index 和 drop index |
insert | 允许使用insert |
lock tables | 允许对用户拥有select权限的表使用lock tables |
process | 允许使用show full processlist |
references | 未被实施 |
reload | 允许使用flush |
replication client | 允许用户询问从属服务器或主服务器的地址 |
replication slave | 用于复制性从属服务器(从主服务器中读取二进制日志文件) |
select | 允许使用select |
show databases | 允许显示所有数据库 |
show view | 允许使用show create view |
shutdown | show view MySQLadmin shutdown |
super | 允许使用change master,kill,purge masterlogs 和set global 语句;MySQLadmin debug命令;允许用户连接(一次),即使已达到max_connections; |
update | 允许使用update |
usage | “无权限”的同义词 |
grant获取权限:
grant priv_type [(column_list)] //要设置的权限项;
[,priv_type[(column_list)]][,.....n] on
{tbl_name|*|*.*|db_name.*|db_name.tbl_name} //对象类型;
to user[,user][,....n]
[with grant_option] //可以将该用户的权限转移给其他用户;
在MySQL8以上,grant已经没办法创建新用户了
实例:
mysql> grant select on *.* to aa@localhost identified by '123' with grant option;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by '123' with grant option' at line 1
mysql> grant select on *.* to mat@localhost with grant option;
Query OK, 0 rows affected (0.01 sec)
————————————————————————
用revoke收回权限
revoke priv_type [(column_list)][,priv_type[(column_list)]][,.....n] on
{tbl_name|*|*.*|db_name.*|db_name.tbl_name}
from ‘username’@’hostname’[,‘username’@’hostname’][,...n]
实例:收回mat所有权限
mysql> revoke all privileges,grant option from mat@localhost;
Query OK, 0 rows affected (0.01 sec)
————————————————————————————————
查看用户权限
show grants for username@hostname
实践:查看mat的权限
mysql> show grants for mat@localhost;
+-----------------------------------------+
| Grants for mat@localhost |
+-----------------------------------------+
| GRANT USAGE ON *.* TO `mat`@`localhost` |
+-----------------------------------------+
1 row in set (0.00 sec)
————————————————————————
限制权限
max_queries_per_hour count:表示每小时可以查询数据库的次数
max_connections_per_hour count:表示每小时可以连接数据库的次数
max_updates_per_hour count:表示每小时可以修改数据库的次数
实例:
grant all on *.* to test1@localhost
with max_queries_per_hour 50
with max_connections_per_hour 10
with max_updates_per_hour 5;
————————————————————————————————————————
既然权限是存放在对应的表中,那么如果我们手动更新了权限表,是否MySQL服务器会自动立刻生效呢?如果不能,那使用什么方法可以让手动修改的权限生效呢?
MySQL保证数据安全的三种方法:
备份:将数据库中的结构、对象和数据导出,生成副本。
备份的分类:
备份的时机:
mysqldump命令的语法格式
mysqldump -u user -h host -ppassword
[--databases]databasename[,databasename2] //可以指定多个数据库;
[all-databases]//可以指定所有数据库;
[tablename=,[tablename=...]] //可以指定特定表;
> filename.sql //输出文件名,可以指定路径;
实例:
备份所有表:使用mysqldump备份数据库Course中所有的表。
mysqldump -u root -p Course > d:/backup/Course.sql
备份指定表:使用mysqldump备份数据库Course中的student表和teacher表。
mysqldump -u root -p Course student,teacher >d:/backup/Course_teacher_student.sql
备份多个指定数据库:使用mysqldump备份数据库Course 和mysql。
mysqldump -u root -p --databases Course,mysql >d:/backup/Course_mysql.sql
恢复数据库,就是让数据库根据备份的数据回到备份时的状态。主要的方法:
使用mysql命令恢复
mysql -u user -h host -ppassword databasename < filename.sql //注意箭头方向
使用mysql将备份文件Course.sql恢复到数据库Course2中。
mysql -u root -p Course2 < d:\backup\Course.sql
使用souce语句恢复
source filename.sql //需要进入到数据库后运行。
使用source命令将备份文件Course.sql恢复到数据库Course3中。
create course3;
use course3;
source d:\backup\Course.sql;
日志是记录数据库日常操作和错误信息的文件,当数据遭遇意外发生丢失时可以通过日志文件来查询原因,并且通过日志文件进行数据恢复。
日志文件种类
详情
1、错误日志:
默认是开启的,并且无法被禁止。
默认存储在MySQL数据库的数据库文件夹下。
通常错误日志的文件名为“主机名.err”。
可以通过修改配置选项log-err来更改。
通过修改配置选项log-error来更改路径和日志名:
[mysqld]
log-error[ =path/filename] #修改错误日志存放位置及文件名
查询错误日志位置
mysql> show variables like 'log_error';
+---------------+--------------------+
| Variable_name | Value |
+---------------+--------------------+
| log_error | .\HEARTFORLING.err |
+---------------+--------------------+
1 row in set, 1 warning (0.03 sec)
删除错误日志
mysqladmin -u root -p flush -logs
本质上是更新错误日志,创建出一个新的错误日志,旧的错误日志改名为:'原文件名.err-old'
2、二进制日志:
默认是关闭的,通过修改my.ini配置文件的log-bin选项开启。
[mysqld]
log-bin[ =path/[filename]] #开启二进制日志
Expire_logs_days=10 #定义自动清除日志的时间(天数)
max_binlog_size=100M #定义单个二进制文件的大小限制
如何查看二进制日志?
mysqlbinlog XXXX-bin.0001
mysqlbinlog命令恢复数据库:
mysqlbinlog [option] filename mysql -u user -ppassword
option:可选参数,常见的参数有
--start-date (--stop-date) :用于指定数据库恢复的起始时间和结束时间点。
--start-position (--stop-position): 可以指定恢复数据库的开始位置和结束位置。
删除所有二进制日志
reset master
删除指定的日志文件
可以根据编号或者创建的时间来删除,语法格式是:
purge {binary|master} logs to ‘log_name’
purge {binary|master} logs before ‘data’
3、通用查询日志:
默认是关闭的,通过修改my.ini配置文件的log选项开启。
[mysqld]
log[ =path/filename] #开启通用查询日志
4、慢查询日志:
默认是关闭的,通过修改my.ini配置文件的log-slow- queries选项开启。
[mysqld]
log-slow-queries[ =path/filename] #开启慢查询日志
long_query_time = n #最慢的查询时间,单位是秒,默认值是10
一个事务由一条或者多条SQL语句组成,这些SQL语句相互依赖不可分割,如果其中的某一条SQL语句没能完成,前面已经执行的SQL语句就会撤销,回滚到事务开始前的状态。
事务的四个特性(ACID):
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
系统定义事务:
默认情况下,每条单独的语句都是一个事务。语句执行完后,MySQL会自动提交,也就是立刻将结果存储到磁盘中。如要显式关闭自动提交:使用的语句set @@autocommit=0;
用户定义事务:
用户自定义开始,结束,回滚和提交等事务的状态,用到的语句为:
start transaction |begin work:开启事务。
commit[ work] [and [no] chain] [[no] release]:提交事务
Rollback [work][and [no] chain] [[no] release]:回滚事务
会隐式地执行一个commit命令的语句:
drop database / drop table / create index /
drop index / alter table / rename table /
lock tables / unlock tables / set @@autocommit=1
rollback to 语句使事务回滚到某点,需要事先设置一个保存点:
设置保存点使用的语句
savepoint identifier
Rollback [work] to identifier
MySQL四种隔离级别:
序列化(SERIALIZABLE):用户之间通过一个接一个顺序地执行当前事务,这种方式提供了事务之间最大限度的隔离。
可重复读(REPEATABLE READ):MySQL默认隔离级,适用于大多数应用程序。它确保同一事务内相同的查询语句执行结果一致。
提交读(READ COMMITTED):满足了隔离的简单定义,一个事务只能看见已提交事务所做的改变。
未提交读(READ UNCOMMITTED):提供了事务之间最小程度的隔离。这个级别下,所有事务都可以看到其他未提交事务的执行结果。
!隔离级别强度(从左到右减弱):序列化、可重复读、提交读、未提交读。
使用SET TRANSACTION 语句定义隔离级:
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL
SERIALIZABLE |
REPEATABLE READ |
READ COMMITTED |
READ COMMITTED
事务的并发,锁定的机制:
表级锁:一种特殊类型的访问,整个表被客户锁定。
页级锁:锁定表中的某几行(称作页)
行级锁:只有线程使用的行被锁定,其他行对于其他线程是可用的。
MySQL提供LOCK 语句来锁定当前线程的表,语法格式是:
LOCK TABLES table_name [as alias ] {
read [local] | # 用户可以读取表,但是不能修改表
[low_priority] write #只有锁定该表的用户可以修改表,其他的用户无法访问该表。
}
解除锁定:
UNLOCK Table;//不需要指定表,会解锁所有表