mysql的简介
概述
就是一个关系型数据库管理系统,由瑞典MYSQL AB公司开发,目前属于Oracle公司。
mysql是开源的。所以你不需要支付额外的费用
mysql是可以定制的,采用了GPL协议,你可以修改源码来开发自己的mysql系统。
mysql支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
mysql的安装
mysql5.5
下载地址:https://dev.mysql.com/downloads/mysql/
国内的下载的镜像地址我推荐使用清华镜像地址:https://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/
检查工作
检查当前的系统是否安装过mysql
在centOS6中
rpm -qa | grep mysql
rpm命令是是RPM软件包的管理工具,
其中-q:使用询问模式,当遇到任何问题时,rpm指令会先询问用户;
-a:查询所有套件;
-e<套件档>或--erase<套件档>:删除指定的套件;
如果存储mysql-libs的旧版本包如下:
请先执行卸载命令:rpm -e --nodeps mysql-libs
在centOS7中
rpm -qa | grep mariadb
如果存储如下:
请先执行卸载命令:rpm -e --nodeps mariadb-libs
检查/tmp文件夹的权限
由于mysql安装过程中,会通过mysql用户在/tmp目录下新建tmp_db文件,所以请给/tmp较大的权限
执行: chmod -R 777 /tmp (如果你是在root用户下操作的,可以省略)
安装
首先把安装包上传到linux服务器上。我这个版本我放在了/opt 目录下。
/opt目录用来安装附加软件包,是用户级的程序目录,可以理解为D:/Software,opt有可选的意思
在mysql的安装目录下执行:
rpm -ivh MySQL-client-5.5.54-1.linux2.6.x86_64.rpm (安装客户端)
rpm -ivh MySQL-server-5.5.54-1.linux2.6.x86_64.rpm (安装服务端)
安装完设置初始化的密码:
mysqladmin -u root password '你的密码'
mysql的安装位置
在linux中查看安装目录:ps -ef | grep mysql
参数 | 路径 | 解析 | 备注 |
--basedir | /usr/bin | 相关命令目录 |
mysqladmin mysqldump等命令 |
--datadir | /var/lib/mysql/ | mysql数据库文件的存放路径 | |
--plugin-dir | /usr/lib64/mysql/plugin | mysql插件存放路径 | |
--log-error | /usr/lib64/mysql/jack.at***.err | mysql错误日志路径 | |
--pid-file | /var/lib/mysql/jack.**.pid | 进程pid文件 | |
--socket | /var/lib/mysql/mysql.sock | 本地连接时用的unix套接字 | |
/usr/share/mysql | 配置文件目录 | mysql脚本及配置文件 | |
/etc/init.d/mysql | 服务启停相关脚本 |
自启动:chkconfig mysql --list
开始使用
mysql -uroot -proot (进入mysql命令窗口)
显示数据库:show databases
创建一个数据库:create database mydb
使用其中的一个库 :user mydb
创建表:crate table mytable(id int , name varchart(200));
插入数据:insert into mytable values(1,'张三');
查询数据:select * from mytable;
发现出现了乱码
显示字符集:show varables like 'character%';
修改字符集
cd /usr/share/mysql/ 发现很多mysql的配置
拷贝my-huge.conf 到 /etc/
在/usr/share/mysql/目录下执行
cp my-huge.cnf /etc
重命名
mv my-huge.conf my.cnf
修改my-cnf文件:
[client] default-character-set=utf8 [mysqld] character_set_server=utf8 character_set_client=utf8 collation-server=utf8_general_ci [mysql] default-character-set=utf8 |
使用vi 命令打开文件: vi my.cnf 把上面的配置加上去。ctrl+: 输入wq!保存退出。
重启mysql服务
service mysql restart (如果没有配置错误就可以了)
进去查询那条数据还是乱码的,因为开始的时候就是以拉丁的字符集创建的,现在改成utf8还是乱码的。需要把这条数据更新或者删除才可以解决。
现在远程连接mysql发现还是连接不上的。
mysql > GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '数据库的密码' WITH GRANT OPTION; 就可以远程连接了
mysql的用户和权限管理
mysql的用户管理
创建用户
create user zhangsan identified by '123456' (表示创建名称为张三的用户,密码设为123456)
了解用户表
查看用户:
select host,user,password,select_priv,insert_priv,drop_priv from mysql.user,
host : 表示连接类型
%表示所有远程通过TCP方式连接
IP地址 如(192.168.0.147,127.0.0.1)通过指定ip地址进行的TCP方式的连接
机器名 通过制定网络中的机器名进行TCP方式的连接
::1 IPV6的本地地址 等同与IP4的127.0.0.1
localhost 本地方式通过命令方式的连接。比如mysql -uxxx -p123xxx方式的连接。
User: 表示用户名
同一用户通过不同方式连接的权限是不一样的。
password 密码
所有密码串通过password(明文字符串)生成的密文字符串。加密算法为MYSQLSHA1.不可逆。
mysql5.7的密码保存到authentication_string字段中不再使用password字段。
设置密码
修改当前用户密码
set password =password('123456')
修改某个用户密码:
update mysql.user set password=password('123456') where user='用户名称'
flush privileges; #所有通过user表的修改,必须用该命令才能生效。
修改用户
修改用户名:
update mysql.user set user='lisi' where user='wangwu';
flush privileges; #所有通过user表的修改,必须用该命令才能生效。
删除用户
drop user 用户名称;
权限管理
授予权限
授权命令:grant 权限1,权限2,...权限n on 数据库名称.表名称 to用户名@用户地址 identified by '连接口令’;
该权限如果发现没有该用户,则会直接新建一个用户。
比如:
grant select,insert,delete,drop on atfycdb.* to lisi@localhost ;(给lisi用户用本地命令行方式下,授予atfycdb这个库下的所有表的插删该查的权限)
grant all privileges on *.* to fyc@'%' identified by '123';(#授予通过网络方式登陆的fyc用户,对所有库的所有表的全部权限,密码设为123)
收回权限
收回权限命令 revoke 权限1,权限2,... 权限n on 数据库名称.表名称 from 用户名@用户地址;
revoke all privileges on mysql.* from fyc@localhost;(#收回全库全表的所有权限)
REVOKE select,insert,update,delete ON mysql.* FROM fyc@localhost; (#收回mysql库下的所有表的插删改查权限)
必须用户重新登陆后才能生效。
查看权限
查看当前用户权限: show grants;
查看某用户的全局权限:select * from user;
查看某用户的某个表的权限:select * from tables_priv;
通过工具远程访问
grant all privileges on *.* to root@'%' identified by 'root';
mysql > GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '数据库的密码' WITH GRANT OPTION;
专项配置
出现问题的demo
create TABLE mytabl2(id INT,name VARCHAR(200),age INT,dept INT); INSERT into mytabl2 VALUES(1,'zhangsan',33,101); INSERT into mytabl2 VALUES(2,'lisi',33,101); INSERT into mytabl2 VALUES(3,'wang5',34,102); INSERT into mytabl2 VALUES(4,'zhaoliu',34,102); INSERT into mytabl2 VALUES(5,'tianqi',36,102); #每个部门年龄最大的人 SELECT NAME,dept,MAX(age) FROM mytal2 GROUP BY dept;
需要的实际结果应该是lisi和tianqi的名字,但是出现的却是zhangsan和wang5。
mysql的sql_mode合理配置
sql_mode是个很容易被忽略的变量。默认值是空值,在这种设置下是可以允许一些非法操作的。比如允许一些非法数据的插入。在生产环境中必须将这个值设置为严谨模式。所有开发、测试环境的数据库爷必须要设置,这样在开发测试阶段就可以发现问题。
show variables like 'sql_mode';
sql_mode常用值如下:
set sql_mode =‘ONLY_FULL_GROUP_BY’;
ONLY_FULL_GROUP_BY: 对于group by 聚合操作,如果在select中的列。没有在group by中出现,那么这个sql是不合法的,因为列不在group by从句中。
NO_AUTO_VALUE_ON_ZERO: 该值影响自增长列的插入。默认设置下,插入0或null代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。
STRICT_TRANS_TABLES: 该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制
NO_ZERO_IN_DATE: 在严谨模式下,不允许日期和月份为零。
NO_ZERO_DATE: 设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。
mysql逻辑架构介绍
总体概览
和其他数据库相比,mysql优点与众不同,它的架构可以在多种不同场景中应用并发挥良好的作用。主要体现在存储引擎的架构上,
插入式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎。
下图就是MySQL的逻辑架构图:
MySQL架构总共三层,在上图中以虚线作为划分。
首先,最上层的服务并不是MySQL独有的,大多数给予网络的客户端/服务器的工具或者服务都有类似的架构。比如:连接处理、授权认证、安全等。
第二层的架构包括大多数的MySQL的核心服务。包括:查询解析、分析、优化、缓存以及所有的内置函数(例如:日期、时间、数学和加密函数)。同时,所有的跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
第三层包含了存储引擎。存储引擎负责MySQL中数据的存储和提取。服务器通过API和存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对上层的查询过程透明化。存储引擎API包含十几个底层函数,用于执行“开始一个事务”等操作。但存储引擎一般不会去解析SQL(InnoDB会解析外键定义,因为其本身没有实现该功能),不同存储引擎之间也不会相互通信,而只是简单的响应上层的服务器请求。
1、Connectors
指的是不同语言中与SQL的交互。
2、Connection Pool
管理缓冲用户连接,线程处理等需要缓存的需求。负责监听对 MySQL Server 的各种请求,接收连接请求,转发所有连接请求到线程管理模块。每一个连接上 MySQL Server 的客户端请求都会被分配(或创建)一个连接线程为其单独服务。而连接线程的主要工作就是负责 MySQL Server 与客户端的通信,接受客户端的命令请求,传递 Server 端的结果信息等。线程管理模块则负责管理维护这些连接线程。包括线程的创建,线程的 cache 等。
3、 Management Serveices & Utilities
系统管理和控制工具。
4、 SQL Interface
接受用户的SQL命令,并且返回用户需要查询的结果。
5、 Parser
SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的,是一个很长的脚本。在 MySQL中我们习惯将所有 Client 端发送给 Server 端的命令都称为 query ,在 MySQL Server 里面,连接线程接收到客户端的一个 Query 后,会直接将该 query 传递给专门负责将各种 Query 进行分类然后转发给各个对应的处理模块。
主要功能:
a 、 将SQL语句进行语义和语法的分析,分解成数据结构,然后按照不同的操作类型进行分类,然后做出针对性的转发到后续步骤,以后SQL语句的传递和处理就是基于这个结构的;
b、 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的。
6、 Optimizer
查询优化器:SQL语句在查询之前会使用查询优化器对查询进行优化。就是优化客户端请求query,根据客户端请求的 query 语句,和数据库中的一些统计信息,在一系列算法的基础上进行分析,得出一个最优的策略,告诉后面的程序如何取得这个 query 语句的结果。
使用的是“选取-投影-联接”策略进行查询:
用一个例子就可以理解: select uid,name from user where gender = 1;
这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤;然后根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤。最后将这两个查询条件联接起来生成最终查询结果。
7 、Cache和Buffer
查询缓存:主要功能是将客户端提交 给MySQL 的 Select 类 query 请求的返回结果集 cache 到内存中,与该 query 的一个 hash 值 做一个对应。该 query 所取数据的基表发生任何数据的变化之后, MySQL 会自动使该 query 的Cache 失效。在读写比例非常高的应用系统中, Query Cache 对性能的提高是非常显著的。当然它对内存的消耗也是非常大的。
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等。
8 、存储引擎接口
MySQL区别于其他数据库的最重要的特点就是其插件式的表存储引擎。MySQL插件式的存储引擎架构提供了一系列标准的管理和服务支持,这些标准与存储引擎本身无关,可能是每个数据库系统本身都必需的,如SQL分析器和优化器等,而存储引擎是底层物理结构的实现,每个存储引擎开发者都可以按照自己的意愿来进行开发。
注意:存储引擎是基于表的,而不是数据库。
利用show profile 查看sql的执行周期
#先开启:show VARIABLES LIKE '%profiling%';
SET profiling=1;
SELECT * FROM xxx;
SHOW PROFILES; #显示最近的几次查询
SHOW PROFILE cpu,block io FOR QUERY query_id; #查看程序的执行步骤
查询说明
sql的执行顺序
手写
select distinct <select_list> from <left_table> <join_type> join <right_table> on <join_condition> where <where_condition> group by <group_by_list> having <having_condition> order by <order_by_condition> limit <limit_number>
机读
随着mysql版本的迭代更新。其优化器也在不断的升级,优化器会分析不同执行顺序产生的性能消耗不同而调整执行顺序。
下面是经常出现的查询顺序: