这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战mysql
感谢阅读,但愿能对你有所帮助,博文如有瑕疵请在评论区留言或在主页我的介绍中添加我私聊我,感谢每一位小伙伴不吝赐教。我是XiaoLin,既会写bug也会唱rap的男人算法
命令 | 描述 | 备注 |
---|---|---|
create user xiaolin identified by '123456'; | 建立名称为xiaolin的用户,密码为123456 | |
select host,user,password,select_priv,insert_priv,drop_priv from mysql.user; | 查看用户和权限的相关信息 | |
set password = password('123456') | 修改其余用户的密码 | 全部经过 user 表的修改,必须用 flush privileges;命令才能生效 |
update mysql.user set user = 'zs' where user = 'xiaolin' | 修改用户名 | 全部经过 user 表的修改,必须用 flush privileges;命令才能生效 |
drop user xiaolin | 删除用户 | 不要经过delete from user where user = 'xiaolin'进行删除,系统会有残留信息保存 |
host表示链接类型。sql
user表示用户名,同一用户经过不一样方式链接的权限是不同的。数据库
这里显示的是明文密码经过哦MYSQLSHA1加密算法加密后获得的密文密码,是不可逆的,mysql 5.7 的密码保存到 authentication_string 字段中再也不使用 password 字段。缓存
表示该用户所拥有的权限。安全
咱们能够经过命令来授予用户权限,该权限若是发现没有该用户,则会直接新建一个用户。服务器
格式为:markdown
grant 权限 1,权限 2,…权限 n on 数据库名称.表名称 to 用户名@用户地址 identified by‘链接口令
复制代码
示范:网络
# 给 xiaolin 用户用本地命令行方式下,授予 user 这个库下的全部表的插删改查的权限。
grant select,insert,delete,drop on user.* to xiaolin@localhost;
# 授予经过网络方式登陆的的 xiaolin 用户 ,对全部库全部表的所有权限,密码设为 123.
grant all privileges on *.* to xiaolin@'%' identified by '123';
复制代码
咱们可使用命令来查看当前用户的权限。数据结构
show grants;
复制代码
咱们可使用命令来收回用户的权限,权限收回后,必须用户从新登陆后,才能生效。
revoke
[权限 1,权限 2,…权限 n] on 库名.表名 from 用户名@用户地址 ;
复制代码
示范:
# 收回全库全表的全部权限
REVOKE ALL PRIVILEGES ON mysql.* FROM joe@localhost;
# 收回 mysql 库下的全部表的插删改查权限
REVOKE select,insert,update,delete ON mysql.* FROM xiaolin@localhost;
复制代码
和其它数据库相比,MySQL 有点不同凡响,它的架构能够在多种不一样场景中应用并发挥良好做用。主要体如今存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构能够根据业务的需求和实际须要选择合适的存储引擎。
MySql大概分为四层:
最上层是一些客户端和链接服务,包含本地 sock 通讯和大多数基于客户端/服务端工具实现的相似于 tcp/ip 的通讯。主要完成一些相似于链接处理、受权认证、及相关的安全方案。在该层上引入了线程池的概念,为经过认证安全接入的客户端提供线程。一样在该层上能够实现基于 SSL 的安全连接。服务器也会为安全接入的每一个客户端验证它所具备的操做权限。
服务层提供各类用户使用的接口,同时提供SQL优化器,对用户传进来的SQL语句进行优化。他有几个组件。
组件名 | 描述 |
---|---|
Management Serveices & Utilities | 系统管理和控制工具 |
SQL Interface | SQL 接口。接受用户的 SQL 命令,而且返回用户须要查询的结果。好比 select from就是调用 SQL Interface |
Parser | 解析器。 SQL 命令传递到解析器的时候会被解析器验证和解析 |
Optimizer | 查询优化器。SQL 语句在查询以前会使用查询优化器对查询进行优化,好比有where 条件时,优化器来决定先投影仍是先过滤。 |
Cache 和 Buffer | 查询缓存。若是查询缓存有命中的查询结果,查询语句就能够直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。好比表缓存,记录缓存,key 缓存,权限缓存等 |
存储引擎层,存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器经过 API 与存储引擎进行通讯。不一样的存储引擎具备的功能不一样,这样咱们能够根据本身的实际须要进行选取。
数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。
mysql 的查询流程大体是:
咱们手写一条完整的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 >
复制代码
然而它的执行顺序是这样的.。
FROM <left_table>
ON <join_condition>
<join_type> JOIN <right_table>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
SELECT
DISTINCT <select_list>
ORDER BY <order_by_condition>
LIMIT <limit_number>
复制代码
对比项 | MyISAM | InnoDB |
---|---|---|
外键 | 不支持 | 支持 |
事务 | 不支持 | 支持 |
行表锁 | 表锁,即便操做一条记录也会锁住整张表,不适合高并发操做 | 行锁,操做时只锁住某一行,不对其余行有影响,适合高并发操做 |
缓存 | 只缓存索引不缓存真实数据 | 不只仅缓存索引还缓存真实数据,对内存要求较高,并且内存大小对性能有决定性的影响 |
MySQL 官方对索引的定义为:索引(Index)是帮助 MySQL 高效获取数据的数据结构。能够获得索引的本质:索引是数据结构。能够简单理解为排好序的快速查找数据结构。
在数据以外,数据库系统还维护着知足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就能够在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
左边是数据表,一共是两列七条数据,最左边的是数据记录的物理地址。为了加快 Col2 的查找,能够维护一个右边所示的二叉查找树,每一个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就能够运用二叉查找在必定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。
通常来讲索引自己也很大,不可能所有存储在内存中,所以索引每每以索引文件的形式存储的磁盘上。
MySQL 使用的是 Btree 索引。一颗B树,浅蓝色的块咱们称之为一个磁盘块,能够看到每一个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示)。
磁盘块 1 包含数据项 17 和 35,包含指针 P一、P二、P3,P1 表示小于 17 的磁盘块,P2 表示在 17 和 35 之间的磁盘块,P3 表示大于 35 的磁盘块。
真实的数据存在于叶子节点即 三、五、九、十、1三、1五、2八、2九、3六、60、7五、7九、90、99。
非叶子节点只不存储真实的数据,只是为了做为分隔线,存储指引搜索方向的数据项,如 1七、35 并不真实存在于数据表中。
若是要查找数据项 29,那么首先会把磁盘块 1 由磁盘加载到内存,此时发生一次 IO。
在内存中用二分查找肯定 29在 17 和 35 之间,锁定磁盘块 1 的 P2 指针,内存时间由于很是短(相比磁盘的 IO)能够忽略不计。经过磁盘块 1的 P2 指针的磁盘地址把磁盘块 3 由磁盘加载到内存,发生第二次 IO。
29 在 26 和 30 之间,锁定磁盘块 3 的 P2 指针,经过指针加载磁盘块 8 到内存,发生第三次 IO,同时内存中作二分查找找到 29,结束查询,总计三次 IO。
3层的B树能够表示上百万的数据,若是上百万的数据查找只须要三次 IO,性能提升将是巨大的。
若是没有索引,每一个数据项都要发生一次 IO,那么总共须要百万次的 IO,显然成本很是很是高。
咱们能够看到BTree结构图中,每一个节点不只仅包含key值,同时还有data值,每个页的存储空间是有限的,若是data数据较大时会致使每一个节点(即每个页)能存储的key数量很小,当存储的数据量很大的时候会致使BTree的深度很深,增大了查询时磁盘I/O的次数。
而在B+Tree中,全部数据记录节点都是按照键值大小顺序放在同一层的叶子节点上,而非叶子节点只存储key信息,这样能够大大增长每一个节点存储的key值的数量,下降B+Tree的高度。
实际状况中每一个节点可能不能填满,在数据库中,B+Tree的高度通常在24层之间,MySQL的InnoDB存储引擎在设计时是将根节点常驻内存的(不动用磁盘I/O,直接上内存找),也就是说查找某一键值行记录时最多只须要13次磁盘I/O操做。
单值索引指一个索引只包含单个列,一个表能够有多个单列索引。
# 随着表的创建一块儿创建
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id), KEY (customer_name) );
# 单独建单值索引
CREATE INDEX idx_customer_name ON customer(customer_name);
复制代码
惟一索引指的是索引列必须惟一,可是容许有空值,且只能有一个。
# 随着表的创建一块儿创建
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id), KEY (customer_name), UNIQUE (customer_no) );
# 单独建惟一索引
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);
复制代码
设定为主键后数据库会自动创建索引,innodb为聚簇索引,主键索引列值不能为空。
# 随表一块儿建索引
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id) );
# 单独建主键索引
ALTER TABLE customer add PRIMARY KEY customer(customer_no);
# 删除建主键索引
ALTER TABLE customer drop PRIMARY KEY ;
# 若是须要修改建主键索引,必须先删除掉(drop)原索引,再新建(add)索引
复制代码
他会符合两个原则:
复合索引是一个索引包含多个列。
# 随表一块儿建索引
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id), KEY (customer_name), UNIQUE (customer_name), KEY (customer_no,customer_name) );
# 单独建索引
CREATE INDEX idx_no_name ON customer(customer_no,customer_name);
复制代码
主键索引是在建表时自动建立的。
建表,主键自动建立主键索引
create table t_user(id varchar(20) primary key,name varchar(20));
复制代码
查看索引
show index from t_user;
复制代码
创表的时候一块儿建立索引
# 在建表的时候字段后面用key(列名)来建立索引,可是咱们没办法指定索引名,默认索引名和列名一致。
create table t_user(id varchar(20) primary key , name varchar(20 , key(name)))
复制代码
建立完表之后加索引
# 语法格式
create index 索引名 on 表名(列名);
# 示范
create index index_name on t_user(name);
复制代码
删除索引
# 语法格式
drop index 索引名 on 表名;
# 示范
drop index index_name on t_user;
复制代码
建表的时候建立索引
# 在建表的时候字段后面用unique(列名)来建立索引,可是咱们没办法指定索引名,默认索引名和列名一致。
create table t_user(id varchar(20) primary key , name varchar(20) , unique(name) );
复制代码
建立表以后建立索引
# 格式
create unique index 索引名 on 表名(列名);
# 示范
create unique index index_name on t_user(name);
复制代码
建表的时候建立索引
# 在建表的时候字段后面用key(列名1,列名2...)来建立索引,可是咱们没办法指定索引名,默认索引名和列名一致。
create table t_user (id varchar(20) primary key , name varchar(20) , age int , key(name , age) );
复制代码
建表以后建立
# 语法格式
create index 索引名 on 表名(列名1,列名2...);
# 示范
create index index_name_age on t_user (name , age);
复制代码