mysql--version
为了保证数据库目录与文件的所有者为mysql登录用户,如果以root身份运行mysql服务,需要执行下面的命令初始化
mysqld--initialize--user=mysql
说明:–initialize选项默认以“安全”模式来初始化,则会为root用户生成一个密码并将该密码标记为过期,登录后需要设置一个新的密码。生成的临时密码会往日志中记录一份
查看密码
cat/var/log/mysqld.log
root@localhost:后面就是初始化的密码
启动:systemctl start mysqld.service
关闭:systemctl stop mysqld.service
重启:systemctl restart mysqld.service
查看状态:systemctl status mysqld.service
systemctllist-unit-files|grepmysqld.service
systemctl enable mysqld.service
systemctl disable mysqld.service
mysql-uroot-p
ALTERUSER'root'@'localhost'IDENTIFIEDBY'root';
telnet192.168.117.1003306
关闭防火墙
systemctl start firewalld.service
systemctl status firewalld.service
systemctl stop firewalld.service
systemctl enable firewalld.service
#设置开机启用防火墙
systemctl disable firewalld.service
#设置开机禁用防火墙
开放端口
开放的端口号
firewall-cmd--list-all
设置开放的端口号
firewall-cmd--add-service=http--permanent
firewall-cmd--add-port=3306/tcp--permanent
重启防火墙
firewall-cmd--reload
注意
- 这里的密码是虚拟机上mysql的密码
注意
- 这里的密码是虚拟机的密码
use mysql;
select host,user from user;
update user set host='%' where user = 'root';
ALTERUSER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
flush privileges;
find/-namemysql
MySQL数据库文件的存放路径:/var/lib/mysql/
/usr/bin
(mysqladmin、mysqlbinlog、mysqldump等命令)和/usr/sbin
配置文件目录:/usr/share/mysql-8.0
(命令及配置文件),/etc/mysql
(如my.cnf)
SHOW DATABASES;
mysql自带的四个数据库
mysql –hhostname|hostIP –Pport –uusername– p DatabaseName–e"SQL语句"
-hlocalhost
-P3306
-uroot
-p
databaseName
-e"selecthost,userfromuser"
CREATE USER用户名 [ IDENTIFIED BY '密码' ][ , 用户名[IDENTIFIED BY '密码']];
[]
表示可选,也就是说,可以指定用户登录时需要密码验证,也可以不指定密码验证,这样用户可以直接登录CREATE USER zhangsan IDENTIFIED BY'123';
CREATE USER 'lisi'@'localhost' IDENTIFIED BY '123';
UPDATE mysql.user SET USER='修改后的用户名' WHERE USER = '想要修改的用户名';
FLUSH PRIVILEGES;
方式1
DROP USER user[,user]…;
注意
其中删除用户时,如果用户指定了Host,则必须加上Host
DROP USER zhangsan;
DROP USER 'lisi'@'localhost';
方式2
DELETE FROM mysql.user WHERE Host = 'hostname' AND User = 'username';
FLUSHPRIVILEGES;
DELETE FROM mysql.user WHERE Host='localhost' AND User ='lisi';
ALTER USER USER() IDENTIFIED BY 'new_password';
SET PASSWORD ='new_password';
ALTER USER user [ IDENTIFIED BY '新密码' ][ , user [ IDENTIFIEDBY '新密码']]…;
SET PASSWORD FOR 'username'@'hostname' = 'new_password';
show privileges;
CREATE
和DROP
权限,可以创建新的数据库和表,或删除(移掉)已有的数据库和表SELECT
、INSERT
、UPDATE
和DELETE
权限允许在一个数据库现有的表上实施操作INDEX
权限允许创建或删除索引,INDEX
适用于已有的表。如果具有某个表的CREATE
权限,可以在CREATETABLE
语句中包括索引定义ALTER
权限可以使用ALTERTABLE
来更改表的结构和重新命名表CREATEROUTINE
权限用来创建保存的程序(函数和程序)ALTERROUTINE
权限用来更改和删除保存的程序EXECUTE
权限用来执行保存的程序GRANT
权限允许授权给其他用户,可用于数据库、表和保存的程序FILE
权限使用户可以使用LOADDATAINFILE和SELECT…INTOOUTFILE语句读或写服务器上的文件,任何被授予FILE权权限分布 | 说明 |
---|---|
表权限 | SELECT 、INSERT 、DELETE 、UPDATE 、CREATE 、DROP 、GRANT 、REFERENCES 、INDEX 、ALTER |
列权限 | SELECT 、INSERT 、UPDATE 、REFERENCES |
过程权限 | EXECUTE 、ALTERROUTINE 、GRANT |
GRANT 权限1,权限2,…权限nON数据库名称.表名称 TO 用户名@用户地址 [ IDENTIFIED BY‘密码口令’];
授予用户名@用户地址在数据库或表权限1、权限2…,设置带有密码
SHOW GRANTS;
SHOW GRANTS FOR'user'@'主机地址';
在将用户账户从user表删除之前,应该收回相应用户的所有权限
REVOKE 权限1,权限2,…权限n ON数据库名称.表名称 FROM 用户名@用户地址;
ALL PRIVILEGES
:代表除了GRANT的所有权限
user表是MySQL中最重要的一个权限表,记录用户账号和权限信息,分成4类,分别是范围列(或用户列)、权限列、安全列和资源控制列
DESCRIBE mysql.db;
Create_routine_priv
和Alter_routine_priv
这两个字段决定用户是否具有创建和修改存储过程的权限tables_priv
表用来对表设置操作权限
descmysql.tables_priv;
columns_priv
表用来对表的某一列设置权限
descmysql.columns_priv;
procs_priv表可以对存储过程和存储函数设置操作权限
descmysql.procs_priv;
引入角色的目的是方便管理拥有相同权限的用户,恰当的权限设定,可以确保数据的安全性
CREATEROLE'role_name'[@'host_name'][,'role_name'[@'host_name']]...
host_name
省略,默认为%role_name
不可省略创建一个角色,系统就会自动给一个“USAGE”权限,意思是连接登录数据库的权限,其余权限默认不赋予
GRANT 权限1,权限2... ON table_name TO 'role_name'[@'host_name'];
SHOW GRANTS FOR 'rolename';
REVOKE privileges ON tablename FROM 'rolename';
DROP ROLE role[,role2]...
GRANT role [,role2,...]TOuser[,user2,...];
SET DEFAULT ROLE ALL TO'用户名';
SET GLOBAL activate_all_roles_on_login=ON;
对所有角色永久激活REVOKE role FROM user;
MySQL是典型的C/S架构,即Clinet/Server架构,服务端程序使用的mysqld
客户端进程向服务器进程发送一段文本(SQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)
Connectors,指的是不同语言中与SQL的交互。使用MySQL,首先与MySQL建立TCP连接,之后按照其定义好的协议进行交互。或者比较方便的方法是调用SDK,比如NativeCAPI、JDBC、PHP等各语言MySQLConnecotr,或者通过ODBC。SDK来访问MySQL的本质上还是在TCP连接上通过MySQL协议跟MySQL进行交互
系统(客户端)访问MySQL服务器前,首先建立TCP连接。经过三次握手建立连接成功后,MySQL服务器对TCP传输过来的账号密码做身份认证、权限获取。连接管理的职责是负责认证、管理连接、获取权限信息
服务器会解析查询并创建相应的内部解析树,并对其完成相应的优化:如确定查询表的顺序,是否利用索引等,最后生成相应的执行操作
SQLInterface:SQL接口
Parser:解析器
Optimizer:查询优化器
SELECT id,name FROM student WHERE gender = '女';
- SELECT查询先根据WHERE语句进行选取,而不是将表全部查询出来以后再进行gender过滤
- SELECT查询先根据id和name进行属性投影,而不是将属性全部取出以后再进行过滤
- 将这两个查询条件连接起来生成最终查询结果
Caches&Buffers:查询缓存组件
插件式存储引擎层,负责了MySQL中数据的存储和提取,对物理服务器级别维护的底层数据执行操作,服务器通过API与存储引擎进行通信
所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在文件系统上,以文件的方式存在的,并完成与存储引擎的交互
简化为三层结构:
MySQL的查询流程:
查询缓存:Server如果在查询缓存中发现了这条SQL语句,就会直接将结果返回给客户端;如果没有,就进入到解析器阶段,查询缓存的失效非常频繁
解析器:在解析器中对SQL语句进行词法分析、语法分析
SQL语句的分析分为词法分析与语法分析
分析器先做“词法分析
”。MySQL需要识别出输入由多个字符串和空格组成的一条SQL语句里面的字符串分别是什么,代表什么
接着,要做“语法分析
”。根据词法分析的结果,语法分析器(比如:Bison)会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法
如果SQL语句正确,则会生成一个这样的语法树:
下图是SQL分词分析的过程步骤:
优化器:在优化器中会确定SQL语句的执行路径,比如是根据全表检索
,还是根据索引检索
等。
在开始执行SQL语句之前,要先经过优化器的处理。一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划
比如:优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序,还有表达式简化、子查询转为连接、外连接转为内连接等
举例:如下语句是执行两个表的join:
select*from test1 join test2 using(ID) where test1.name='zhangsan'andtest2.name='Java';
方案1:可以先从表test1里面取出name=‘zhangsan’的记录的ID值,再根据ID值关联到表test2,再判断test2里面name的值是否等于’Java’
方案2:可以先从表test2里面取出name=‘Java’的记录的ID值,再根据ID值关联到test1,再判断test1里面name的值是否等于’zhangsan’
在查询优化器中,可以分为逻辑查询优化阶段和物理查询优化阶段
逻辑查询优化是通过改变SQL语句的内容来使得SQL查询更高效,同时为物理查询优化提供更多的候选执行计划。通常采用的方式是对SQL语句进行等价变换,对查询进行重写。对条件表达式进行等价谓词重写、条件简化,对视图进行重写,对子查询进行优化,对连接语义进行了外连接消除、嵌套连接消除等
物理查询优化是基于关系代数进行的查询重写,而关系代数的每一步都对应着物理计算,这些物理计算往往存在多种算法,因此需要计算各种物理路径的代价,从中选择代价最小的作为执行计划。在这个阶段里,对于单表和多表连接的操作,需要高效地使用索引,提升查询效率
在执行之前需要判断该用户是否具备权限。如果没有,就会返回权限错误。如果具备权限,就执行SQL查询并返回结果
select * from test where id=1;
比如:表test中,ID字段没有索引,那么执行器的执行流程是:
SQL语句在MySQL中的流程是:SQL语句
→查询缓存
→解析器
→优化器
→执行器
→查询结果
select@@profiling;show
select @@profiling;
show variables like'%profiling;';
variableslike’%profiling;'`
profiling=0代表关闭,把profiling打开,即设置为1
set profiling=1;
select * from employees;
show profiles;#显示最近的几次查询
show profile;
show profile for query 7;#查询指定的QueryID
缓冲池和查询缓存不是一个东西
在InnoDB存储引擎中有一部分数据会放到内存中,缓冲池则占了这部分内存的大部分,它用来存储各种数据的缓存,包括了数据页、索引页、插入缓冲、锁信息、自适应Hash和数据字典信息等
缓存池的重要性:
缓存原则(位置*频次):
首先,位置决定效率,提供缓冲池就是为了在内存中可以直接访问数据
其次,频次决定优先级顺序。因为缓冲池的大小是有限的,比如磁盘有200G,但是内存只有16G,缓冲池大小只有1G,就无法将所有数据都加载到缓冲池里,这时就涉及到优先级顺序,会优先对使用频次高的热数据进行加载
注意
查询缓存,在MySQL8.0之后不存在,缓冲池在MySQL8.0之后依然存在
缓冲池管理器会尽量将经常使用的数据保存起来,在数据库进行页面读操作的时候,首先会判断该页面是否在缓冲池中,如果存在就直接读取,如果不存在,就会通过内存或磁盘将页面存放到缓冲池中再进行读取
当对数据库中的记录进行修改的时候,首先会修改缓冲池中页里面的记录信息,然后数据库会以一定的频率刷新到磁盘中。注意并不是每次发生更新操作,都会立即进行磁盘回写。缓冲池会采用一种叫做checkpoint的机制将数据回写到磁盘上,这样做的好处就是提升了数据库的整体性能。
show variables like 'innodb_buffer_pool_size';
默认大小为:134217728/1024/1024=128MB
修改缓冲池大小,比如改为256MB
set global innodb_buffer_pool_size=268435456;
show variables like 'innodb_buffer_pool_instances';
默认情况下,BufferPool的value为1
BufferPool实例创建的越多越好,分别管理各个BufferPool也是需要性能开销的,InnDB规定:当innodb_buffer_pool_size的值小于1G的时候设置多个实例是无效的,InnoDB会默认把innodb_buffer_pool_instances的值修改为1。而我们鼓励在BufferPool大于等于1G的时候设置多个BufferPool实例
存储引擎指的是表的类型,功能为接收上层传下来的指令,然后对表中的数据进行提取或写入操作
查看mysql的存储引擎
show engines;
可以为不同的表设置不同的存储引擎,也就是说不同的表可以有不同的物理存储结构,不同的提取和写入方式
CREATE TABLE表名(
建表语句;
)ENGINE=存储引擎名称;
ALTER TABLE 表名 ENGINE=存储引擎名称;
SHOW CREATE TABLE tablename;