一、数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。
这种数据结构是根据mysql本身定义的数据类型进行组织的,不同的组织方式只能满足不同的比较机制一般有:
简单索引:建立在一个字段上
组合索引:建立在多个字段上
mysql支持的索引类型:
【B-Tree索引】:最左前缀索引
B-Tree+索引:聚簇索引--cluster index
第二索引
【哈希索引】
【R-Tree索引】
【Fulltext】
【B-Tree索引】:B--Balencing,平衡树索引,是自顶向下的倒置的树状结构来组织的数据结构,每个叶子节点分别对应一个指针,指向数据所在的位置,每个分叉的节点指明了要查找的范围
在mysql中,索引通常又称为键,主键和唯一键都可以看做是B-Tree索引
innoDB的引擎支持的索引是【B-Tree+索引】,可以理解为B-Tree是升级版,它的索引是根据主键来建立的,即它的每个索引所对应的数据不是通过指针指向磁盘块的,而是磁盘块就存储在该索引上,用户只要找到该节点,就相当于直接找到数据本身了;
默认情况下,innoDB的索引都是和主键存储在一起的 ,这种以主键为索引的数据存储类型叫做【聚簇索引--cluster index】
【第二索引】:一张表可以存储多次,除了主键索引直接和数据存储在一起,其他索引叶子节点是指针,指向主键的,这种索引就是第二索引
所以在innoDB引擎中,最好将主键建立在最常查询的字段上
在mysql中B-Tree索引又叫做【最左前缀索引】
在字段上建立索引的时候,是从左往右按照固定长度建立索引的
适用场景:
匹配全名(即全键值匹配):匹配整个字段值,将整个索引中的字段都用作条件,和键中所有列进行匹配
匹配最左前缀:仅适用于索引中的第一列
匹配范围值:>, < 等,仍需要从最左前缀开始
局限性:
只要查找没从最左侧开始,就无法使用该索引
不能跳过索引中的列
【哈希索引】:基于键值对,键是hash码,值是指针
只有memory存储引擎支持显示hash索引的;myISAM不支持,innoDB的hash索引是自适应的hash索引,hash索引只能做等值或不等值匹配,因为它是根据数据指纹进行查找的,没办法根据hash值进行排序
局限性:
不能完成覆盖索引
不支持部分键匹配
不能根据索引排序
只支持使用=,in,<=>
优势:
选定合适的话,速度极快,但碰撞率不能太高(hash值有可能一样)
【R-Tree索引】:空间位置索引
只有myISAM引擎支持,也只能用mysql内置的函数来使用
【Fulltext】:全文索引
可以根据关键字进行全文搜索,只有myISAM引擎支持全文索引,也只能通过相关函数来使用
全文索引项目:
Lucene
Sphinx
这两种全文索引项目解决了用innoDB引擎来解决事务和索引的问题;
索引利用方式:
【覆盖索引】:能够在索引中就能够找到所有数据的索引,这种速度比较高
使用索引:
1.必须要使用隔离列:不能让列参与运算
例如:where age+20>60;这样是不可以的
2.前缀索引和索引选择性至关重要:指定使用固定长度的索引,足以区别不同的行,又尽量让其缩短
计算索引长度:(数字接近31%就可以)
select count(disctict field)/count(*) from table
select count (disctict left(field,n))/count(*) from table
3.尽可能使用合适的覆盖索引
4.使用索引既完成查找又同时完成排序
排序方式:
扫描有序索引:速度快
使用文件排序(filesort)
5.尽可能避免重复索引
如何去创建索引:
创建表的时候直接创建索引:索引类型默认是B-Tree索引
如果创建表的时候忘了创建索引,还可以添加索引
alter table tb ADD index(column1,column2...);
例如:
alter table students add index(name,age);
单独创建索引
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[index_type]
ON tbl_name (index_col_name,...)
例如:
create index createtime on students(CreateTime);
查看某张表上的索引:
show indexes from tb
删除索引:
DROP INDEX index_name ON tbl_name
ALTER TABLE tb DROP {INDEX|KEY} index_name
- mysql> create index NAME_AGE on jiaowu.students(NAME,AGE);
- Query OK, 0 rows affected (1.30 sec)
- Records: 0 Duplicates: 0 Warnings: 0
- mysql> show index from jiaowu.students;
- +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
- | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
- +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
- | students | 0 | SID | 1 | SID | A | 2 | NULL | NULL | | BTREE | | |
- | students | 1 | NAME_AGE | 1 | Name | A | 10 | NULL | NULL | | BTREE | | |
- | students | 1 | NAME_AGE | 2 | Age | A | 10 | NULL | NULL | YES | BTREE | | |
- +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
- 3 rows in set (0.00 sec)
二、mysql锁和事务:
我们知道mysql这样的服务器是用来存储数据的,很有可能是允许多个用户同时访问服务器的,这也就 有可能多个用户同时读写同一个数据,这种情况下必然会产生竞争的,为了避免这种竞争,通常情况下要给我们的数据进行加锁;
锁分为两类:
读锁:共享锁--即读时别人也可以读,但是不可以写
写锁:独占锁--即别人不可以读也不可以写
对mysql而言,通过锁粒度来分,可以分为3类:
表锁--一次直接对整张表进行加锁
页锁--对整个页面进行加锁
行锁--只锁定每一行
锁的实现方式:
对mysql而言,数据存储是在存储引擎上实现的,所以对数据加锁需要存储引擎来实现,这就是存储引擎级别的锁;
还可以手动进行对服务器加锁,这种是服务器级别的锁;
隐式锁:由mysql存储引擎自我实现的
显示锁:作为用户手动施加的锁
因为存储引擎更接近于数据,更知道哪些数据应该施加锁,所以一般不建议使用显示锁,最好让存储引擎自我实现锁管理;
两种存储引擎:存储引擎又称作表类型
【myISAM】:红帽5.5.3之前的默认引擎
多张表可以使用不同的表类型
特性:
不支持事务
表级锁,并发能力不强
索引类型:B-Tree, Fulltext, R-Tree
支持延迟更新索引,尽可能降低磁盘IO
适用场景:数据仓库--一次写入,其他都是读
读多写少的场景中myISAM最适用
【innoDB】
自身完成数据的管理,默认使用表空间管理数据
特性:
支持事务(基于多版本并发控制,MVCC)
在默认隔离级别上使用了间隙(gaps)锁,防止幻读
支持行级锁,锁粒度非常精细
支持预读功能(根据局部性原理实现的)
索引类型:自适应hash索引
查看当前系统上支持的所有引擎类型:show engines;
自定义锁类型:(这是在服务器级别手动施加显示锁)
lock tables tb_name lock_type {write | read}; #加锁
unlock tables;
#解锁
mysql事务:Transaction
事务就是一组sql语句,要么全部执行,要么全部不执行
判定一个存储引擎或服务器能否满足事务的条件:
要满足
ACID标准:
A--原子性(Atomicity)
事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
C--一致性(Consistency)
事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束
I--隔离性(Isolation)
多个事务并发执行时,一个事务的执行不应影响其他事务的执行
D--持久性(Durability)
已被提交的事务对数据库的修改应该永久保存在数据库中
隔离性是通过隔离级别来实现的:
show global variables like 'tx%'; 查看默认隔离级别
【隔离级别】:
READ UNCOMMITTED : 读未提交,最低级别(脏读)
READ COMMITTED :读提交(不可重复读)
REPEATABLE READ :可重读(默认),对别人的提交视而不见,背后会有幻影行出现 (幻读)
SERIALIZABLE : serializable串行化 (加锁读),即语句一条一条的执行
三、mysql日志
错误日志: 记录mysql主从服务器的停止启动,以及mysql操作中的错误信息;
一般查询日志:记录常见的查询操作,它占据的资源较多,一般不开启的;
慢查询日志: 记录查询时间超过了事先设定的时间范围的查询操作,一般是启用的;
中继日志: 复制模型中的从服务器使用的;
二进制日志: 记录和数据库中的数据修改以及潜在发生修改相关的语句操作,备份恢复可以用到;
事务日志: 帮助innoDB引擎完成redo、undo工作,将随机IO转换成顺序IO,它满足ACID机制;
【
建议事务日志单独用RAID进行存储,二进制日志尤其要和数据文件分开存储】
和日志相关的一些命令及参数:
show master status;
显示放弃二进制文件中正在使用哪个文件;
show binlog events;
显示日志事件
show binary logs;
查看所有二进制日志文件
show binlog events in 'binlog_file'; 查看当前文件记录的内容;
flush logs;
手动让日志滚动,关闭当前日志,并打开一个新的日志;
和各类日志相关的参数
二进制日志:
- binlog_format:={statement|row|mixed} 定义二进制日志类型
- log_bin: 是否启用二进制日志功能
- sql_log_bin: 是否真正记录二进制日志
- log_bin=/log/mysql/log-bin : 指定二进制文件路径
- max_binlog_size: 定义二进制文件大小
- binlog_stmt_cache_size : 每用户一个的二进制日志(非事务性引擎)
- binlog_cache_size: 和事务性引擎相关二进制日志缓存大小(每用户)
- sync_binlog: 日志同步(关闭自动提交)
- binlog_direct_non_transactional_updates: 非事务性引擎日志是否直接同步
- expire_logs_days: 定义二进制日志自动过期时间
-
事务日志:innoDB相关
- innodb_flush_log_at_trx_commit : 是不是事务一提交就立即同步
- 0,每秒一次写到磁盘空间
- 1,默认值,有事务提交是将日志缓冲区刷写进磁盘
- 2,每秒钟刷写一次,有事务时提交,只到内核缓冲区
- innodb_locks_unsafe_for_binlog: 是否在搜索和索引扫描中使用间隙锁
- innodb_log_buffer_size: 日志缓冲区大小
- innodb_log_file_size: 文件大小 默认5M
- innodb_log_files_in_group: 日志文件组
- innodb_log_group_home_dir: 文件目录路径
- innodb_mirrored_log_groups: 要不要做镜像
慢查询日志:
- long_query_time=# : 定义查询时间
- log_slow_queries : 是否启用慢查询日志,建议启用
- slow_query_log : 是否记录慢查询日志
- slow_query_log_file : 指定慢查询日志的文件路径
-
中继日志:从服务器上启动
- relay_log: 启用中继日志,最好给其文件名
- relay_log_index: 记录有多少个中继日志文件
- relay_log_info_file: 信息文件,记录已应用的事务
- relay_log_purge: 修剪中继日志
- relay_log_recovery: 是否自动恢复
- relay_log_space_limit: 空间限定
-
一般查询日志:
- log: 定义一般查询日志是否启用
- general_log: 特意定义查询日志
- general_log_file: 一般查询日志的日志文件的路径
- log_output:table| file| none 记录到文件中
错误日志:
- log_error: 直接启用了错误日志
- log_warnings:是否将警告信息记录到错误日志
四、权限授予:
我们知道,对于一个企业来说,数据是最重要的,所以对用户的授权也相当重要;
按权限级别来分:
服务器级别
数据库级别
表级别
字段级别
其中服务器级别属于管理类的权限,数据级别、表级别等数据数据类权限,字段有关的权限一般只用在和字段相关操作的命令上:select 、update、insert
管理类权限:
- create temprary tables 创建临时表
- create user 创建用户
- file 从某文件导入或导出文件 ,和备份命令相关
- lock tables 使用显示锁
- process 和进程相关的权限
- reload 用户是否可使用flush、reset命令
- replication client 主从中,从服务器端复制相关信息
- replication slave 也是从服务器端复制相关的权限
- ######如果想从主服务器上复制相关数据,以上两个是从服务器必有权限######
- show databases 查看数据库
- shutdown 关闭mysql
- super 不便归类的管理类权限
数据类权限:数据库和表级别
- alter 修改表的权限
- alter routine 修改或删除存储历程
- create 创建数据库和表
- create routine 是否有创建存储历程的权限
- create view 创建视图
- delete 从表中删除行的权限
- drop 删除库和表的权限
- execute 执行存储历程的权限
- with grant option 是否可将自己权限授予给其他人
- index 创建或删除索引的权限
- insert 插入数据的权限
- select 查询权限
- show view 是否有查看视图的权限
- update 更改行的权限
两个特殊权限:
ALL / ALL PRIVILEGES
所有的权限
USAGE
没有权限
授权命令常用格式:
授予某张表什么样的权限
grant all on [table/procedure/function] db.table to USER@HOST [identified by 'PASSWD'];
收回权限:
revoke privileges on db.table from USER@HOST;
给用户重命名:
rename user old_user to new_user;
给用户设定密码:
set password for USER@HOST=password('PASSWD');
服务器变量:
- max_connect_errors 一个用户登陆错误的最大连接数
- max_user_connections 同一个用户账号最多连接次数,0表示不作限定
- max_connections 全局允许的并发连接个数
跟用户相关的变量:
- max_allowed_packet 允许发送的最大数据包个数
- Aborted_clients 意外终止的客户端
- Aborted_connects 意外终止的连接数
和innoDB引擎相关的变量:
innodb_file_per_table 设置为ON ,表示每个表使用独立的表空间
管理员密码忘记可以使用的参数
--skip-grant-tables --skip-networking 跳过授权表,跳过网络,只允许自己登陆
更多变量请参考:mysql的官方站点:mysql的官方站点:
dev.mysql.com/doc/refman/5.5/en/index.html