数据库服务优化设置
文章目录
- 🌟数据库服务存储引擎应用
- 💡数据库存储引擎作用
- 🧩数据库存储引擎分类
- MyISAM存储引擎(MySQL5.5之前的默认存储引擎)
- InnoDB存储引擎(MySQL5.5之后的默认存储引擎)
- 🛠️数据库存储引擎操作
- 查看数据库存储引擎信息
- 设置数据库存储引擎信息
- 🌟数据库索引功能应用
- 🌏数据库索引应用原理
- 🔑数据库索引类型
- 🍀B+TREE结构组成
- 🍀B+TREE结构应用
- 🌟数据库索引设置
- 🔑聚簇索引(主键索引)
- 创建表的时候设置
- 修改表的索引信息
- 🧩辅助索引
- 普通索引
- 唯一索引
- 联合索引
- 删除索引信息
- 🔍索引应用测试
- 创建测试数据
- 确认测试数据表是否生成
- 进行数据库访问压力测试
- 创建索引功能后再进行压测
- 🌟数据库服务事务概念
- 🔥数据库事务特性
- A: atomicity(原子性)
- C: consistency(一致性)
- I: isolation(隔离性)
- D: durability(持久性)
- 🌏数据库事务执行周期
- 📌数据库事务执行提交方式
- 自动提交方式
- 手动提交方式
- 隐式回滚方式:rollback
- 📐数据库事务隔离级别
- RU(READ-UNCOMMITTED 表示读未提交)
- RC(READ-COMMITTED 表示读已提交)
- RR(REPEATABLE-READ 表示可重复读)
- SR(SERIALIZABLE 可串行化)
🌟数据库服务存储引擎应用
和大多数数据库不同,MySQL中有一个存储引擎的概念,针对不同的存储需求可以选择最优的存储引擎,从而实现数据高效存储和快速调取;
MySQL默认支持多种存储引擎,从而适用于不同领域的数据库应用需要,用户可以通过选择使用不同的存储引擎提高应用的效率,提供灵活的存储;
用户甚至可以按照自己的需要定制和使用自己的存储引擎,以实现最大程度的可定制性。
数据库存储引擎可以用于控制数据库服务程序和磁盘之间的交互(内存交互)
💡数据库存储引擎作用
MySQL服务器把数据的存储和提取操作都封装到了一个名为存储引擎的模块中;
熟悉数据库服务同学都知道,表是由一行一行的记录组成的,但这只是一个逻辑上的概念;
在物理上如何表示记录,怎么从表中读取数据,以及怎么把数据写入具体的物理存储器上(硬盘),都是存储引擎负责的事情。
为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同的存储引擎管理的表可能有不同的存储结构,采用的存取算法也各不相同。
简而言之:数据库存储引擎主要用于接收上层传下来的指令,然后对表中的数据进行读取或写入操作。
🧩数据库存储引擎分类
序号 | 存储引擎 | 描述介绍 |
---|---|---|
01 | ARCHIVE | 用于数据存档(记录插入后不能再修改) |
02 | BLACKHOLE | 丢弃写操作,读操作会返回空内容 |
03 | CSV | 在存储数据时,以逗号分隔各个数据项 |
04 | FEDERATED | 用来访问远程表 |
05 | InnoDB | 支持事务、行级锁、外键约束 |
06 | MEMORY | 数据只存储在内存,不存储在硬盘,多用于临时表 |
07 | MyISAM | 主要的应用的非事务处理存储引擎 |
08 | NDB | MySQL集群专用存储引擎 |
在众多MySQL数据库可以应用的存储引擎中,最常用的就是InnoDB和MyISAM,偶尔还会应用一下MEMORY
MyISAM存储引擎(MySQL5.5之前的默认存储引擎)
MyISAM是MySQL较早的存储引擎之一
优点:可以在高并发情况下,支持数据信息快速读取 但提供了全文索引(select where like 全表扫描)、高速缓存(CDN)等特性
MyISAM适用于读多写少,数据完整性要求不高的场景,如博客,新闻网站等
缺陷:它**不支持事务处理和行级锁定**
InnoDB存储引擎(MySQL5.5之后的默认存储引擎)
InnoDB是MySQL目前的默认存储引擎
优点:由于**支持事务特性、聚簇索引功能,行级锁(支持高并发读写)**,以及自动故障恢复功能(可以恢复内存数据功能)
InnoDB适用于对数据存储安全性,一致性和完整性高的场景,比如:金融行业、游戏行业、电商网站平台等。
🛠️数据库存储引擎操作
查看数据库存储引擎信息
# 查看数据库可用存储引擎
mysql> show engines;# 查看数据库默认存储引擎
mysql> select @@default_storage_engine;
+----------------------------------+
| @@default_storage_engine |
+----------------------------------+
| InnoDB |
+----------------------------------+
1 row in set (0.00 sec)# 查看建表语句获取存储引擎信息
mysql > show create table city;# 查看information_schema数据库获取存储引擎信息
mysql > select table_schema,table_name,engine from information_schema.tables where table_schema not in('sys','mysql','information_schema','performance_schema')
设置数据库存储引擎信息
- 创建表时指定存储引擎
create table 表名 (建表语句
) engine=存储引擎名称;
如果在创建表的语句中没有指定表的存储引擎,那就会使用默认的存储引擎InnoDB
- 修改表的存储引擎
alter 表名 engine=存储引擎名称
- 修改数据库的默认存储引擎
# 永久修改存储引擎配置
vim /etc/my.cnf
default_storage_engine=InnoDB
-- 重启数据库服务生效
/etc/init.d/mysqld restart
🌟数据库索引功能应用
作用:数据库中的索引配置类似书籍的目录,可以加速数据查询效率,较低对磁盘IO性能影响
🌏数据库索引应用原理
索引是数据库中用来提高数据读取性能的常用工具,所有mysql表中的列都可以被索引,对相关列使用索引
可以是提高select操作性能的最佳途径,可以尽可能快的锁定要查询数据的范围,从而达到加速查询的目的(减少IO消耗)
一般索引设置都是应用在比较大的数据表上,比如百万级别、千万级别或亿级别的数据表中,从而完成一些针对性优化
简单理解:数据库索引相当于书的目录,可以借助索引有针对的查看相应数据的信息,避免了全盘检索带来的工作量
🔑数据库索引类型
序号 | 类型 | 说明 |
---|---|---|
类型01 | B+Tree | 默认类型索引(擅于等值和区间查询数据) |
类型02 | Hash | 算法类型索引(擅于等值查询数据) |
类型03 | RTree | 空间类型索引(擅于区间查询数据) |
类型04 | Fulltext | 全文类型索引(擅于过滤查询数据) |
🍀B+TREE结构组成
- 将需要存储的数据信息,均匀分配保存到对应页当中,最终数据信息的均匀存储(落盘)
- **根据页节点存储的数据信息,取出页节节点最小数据信息,并将每个叶节点最小数据信息进行汇总整合,生成相应内部节点数据;**实质上存储的是下层页节点的区间范围,以及与之对应的指针信息,最后构建出内部节点信息;
- **根据内部节点存储的数据信息,取出内部节点最小数据信息,并将每个内部节点最小值信息进行汇总整合,生成相应根节点数据;****根节点只能有占用一个页区域,如果一个页区域空间不够,需要进行内部节点层次扩展,但是尽量要保证层次越少越好;**实质上存储的是下层内部节点的区域范围,以及与之对应的指针信息,最后构建出独立且唯一的根节点信息;
- **整个树形结构,越向上节点存储数据的范围越大,然后依次再分发数据到下面的小范围,最终形成多叉树;**由于出现了多叉树,就表示全部数据分布在多个链表上,避免了单条链表存储数据,同时可以实现并发的访问数据
- 对于加号表示增强,其中增强表示在整个链表上,增加了同级相邻节点之间的双向指针,从而实现相邻节点相互跳转
根节点(根层次结构-只能有一个 根节点也只能有一个)
存储枝节点索引列范围信息和对应枝节点指针信息
枝节点(枝层次结构-可以有多个 枝节点可以有多个)
存储索引列范围信息和对应数据页指针信息
页节点(页层次结构-只能有一个 页节点可以有多个)
存储索引列以及非索引列数据信息
🍀B+TREE结构应用
等值查询数据: 根据BTREE层次高度,消耗等值的IO资源
- 根据根节点索引范围获取对应枝节点指针
- 根据枝节点索引范围获取对应页节点指针
- 根据页节点索引信息获取数据内容
范围查询数据:根据B+TREE层次结构,利用根节点和页节点,以及横向指针获取范围数据
- 根据根节点索引范围获取对应枝节点指针(范围最小值的枝节点)
- 根据枝节点索引范围获取对应页节点指针
- 根据页节点索引信息获取数据内容,并利用双向指针获取其他页节点的范围数据信息
🌟数据库索引设置
🔑聚簇索引(主键索引)
基于主键列建立B+Tree索引结构,在查询数据时,必须使用主键列作为条件进行查询
主键索引在每个表中必须存在,如果没有创建主键索引,mysql数据库服务会自动创建一个隐藏列作为主键索引列
创建表的时候设置
create table test01 (id int,name char(5),age int,gender varchar(1),primary key (id));
desc test01;
show index from test01;
修改表的索引信息
ALTER TABLE test04 ADD PRIMARY KEY (id);
🧩辅助索引
基于非主键列建立B+Tree索引结构,在查询数据时,可以实现基于非主键列获取数据内容
利用辅助索引列查询数据,需要将查询后的主键列数据做应用,返回到聚簇索引中继续查询其他数据内容(回表查询)
① 调取需要建立的辅助索引列信息,并加上相应主键列的所有信息,存储在特定的内存区域中
② 根据调取的辅助索引列信息,进行字符的顺序排序,便于形成范围查询的区间,并将排序后的数据信息存储在特定数据页中
③ 叶子节点构建完后,可以构建no-left(支节点),用于保存的是leaf节点中的字符范围和指针信息
④ 支节点构建完后,可以构建root(根节点),用于保存的是no-leaf节点中的字符范围和指针信息
⑤ 找到相应辅助索引的数据信息后,在根据辅助索引与聚簇索引的对应关系,获取到相应的主键信息,从而获取相应其他数据信息
在利用聚簇索引获取其他数据信息的过程,也可以称之为回表查询过程
普通索引
创建条件:具有重复信息或者空值信息时,对应的列可以创建普通索引
1.对name列进行统计数量
select count(name) from test03;2.对name列进行去重统计数量
select distinct name from test03;3.如果去重数量小于总数,则有重复的4.查询是否有空值
select * from test03 where name is null;
#创建表时设置普通索引
create table 表名 (字段1,字段2....,index 索引名(列名))#创建表后设置普通索引
create index 索引名 on 表名(列名)#修改表的索引信息
alter table 表名 add index 索引名(列名);
创建表时设置普通索引
创建表后设置普通索引
修改表的索引信息
唯一索引
创建条件:没有重复信息时,对应的列可以创建唯一索引
#创建表时设置唯一索引
create table 表名 (....,unique index 索引名(列名)#创建表后设置唯一索引
create unique index 索引名 on 表名(列名)#修改表的索引信息
alter table 表名 add unique index 索引名(列名);
创建表时设置唯一索引
创建表后设置唯一索引
修改表的索引信息
联合索引
创建条件:当数据表的数据量(重复信息)比较多时,并且查询数据信息时会应用多个条件
利用联合索引创建辅助索引BTREE结构,在进行回表查询时,可以减少回表次数(可以获取更精准主键信息),从而优化磁盘IO性能
#创建表时设置联合索引
create table 表名 (字段1,字段2,....,index 索引名(列名01,列名02))#创建表后设置联合索引
create index 索引名 on 表名(列名01,列名02)#修改表的索引信息
alter table 表名 add index 索引名(列名01,列名02);
创建表时设置联合索引
创建表后设置联合索引
修改表的索引信息
序号 | 索引标识 | 解释说明 |
---|---|---|
01 | PK(PRI) | 表示为聚簇索引,也可以理解为主键索引 |
02 | MK(MUL) | 表示为辅助索引,也可以理解为一般索引 |
03 | UK(UNI) | 表示唯一键索引 |
删除索引信息
#主键索引删除
alter table 表名 drop primary key;#聚簇索引删除
alter table 表名 drop index 索引名;
主键索引删除
聚簇索引删除
🔍索引应用测试
创建测试数据
mysql -uroot -pzhu <~/t100w.sql
确认测试数据表是否生成
select count(*) from test.t100w;
100w行数据
进行数据库访问压力测试
mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='test' --query="select * from test.t100w where k2='VWlm'" engine=innodb --number-of-queries=2000 -uroot -pzhu -verbose--defaults-file=/etc/my.cnf -- 压力测试时,需要加载数据库程序配置文件
--concurrency=100 -- 模拟并发访问数量
--iterations=1
--create-schema='oldboy' -- 指定操作数据库信息
--query -- 模拟压力测试对数据库服务发送什么SQL请求
--number-of-queries=2000 -- 指定并发用户总的访问请求次数
创建索引功能后再进行压测
create index index_name on t100w(k2);mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='test' --query="select * from test.t100w where k2='VWlm'" engine=innodb --number-of-queries=2000 -uroot -pzhu -verbose
🌟数据库服务事务概念
🔥数据库事务特性
A: atomicity(原子性)
在完成数据业务操作过程中,每个事务中的语句要么都成功要么都失败,不能有部分成功部分失败的情况;
举例说明:银行转账事务 A账户 --转账金额 50元 --> B账户
update A账户-- 将余额减少50元
update B账户-- 将余额增加50元
转账操作完毕
begin SQL01-成功,SQL02-成功 commit
begin SQL01-成功,SQL02-失败 rollback
C: consistency(一致性)
在完成数据业务操作过程中,当数据库服务出现异常宕机,需要确保数据库服务重启,数据信息和宕机前的数据信息一致
举例说明:银行转账事务 A账户 --转账金额 50元 --> B账户
update A账户-- 将余额减少50元 成功
update B账户-- 将余额增加50元 成功
转账操作完毕
利用redo日志文件保证了,数据库服务异常停止后,可以在重启时恢复内存中的数据。
I: isolation(隔离性)
在数据库被访问期间,需要控制并发读和写的冲突问题
举例说明:客户端读取数据库数据 客户端写入数据信息
读取数据:是想统计财务信息 8月31日 00:00:00 查询财务数据 恢复收入金额 10万 00:00:05 查询财务数据 恢复收入金额 11万
写入数据:新的财务金额变化 8月31日 00:00: 01 存储新的金额数据 1万
会利用隔离级别进行调整设置
D: durability(持久性)
在数据库中存储的数据,存储完毕后,不能出现丢失情况
利用CR机制+双写机制 必须有主从环境
🌏数据库事务执行周期
begin;SQL01,SQL02,commit; -- 以全成功方式结束事务操作
begin;SQL01,SQL02,rollback; -- 以全失败方式结束事务操作
📌数据库事务执行提交方式
自动提交方式
#实现语句执行后,自动提交事务配置
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
手动提交方式
1.修改配置文件
vim /etc/my.cnf
[mysqld]
autocommit=02.重启服务
/etc/init.d/mysqld restart3.登录数据查看
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
隐式回滚方式:rollback
- 情况一:在事务操作过程中,会话窗口自动关闭了,会进行隐式自动回滚;
- 情况二:在事务操作过程中,数据库服务被停止了,会进行隐式自动回滚;
- 情况三:在事务操作过程中,出现事务冲突死锁了,会进行隐式自动回滚;
📐数据库事务隔离级别
现实系统中,多个用户可能同时在用数据库,我们希望每笔交易都像自己独占数据库一样运行
最高级别的隔离性叫“可串行化”,意思是每笔交易像排队买奶茶一样,一个一个来,最安全,但也最慢
作用:可以避免3种数据读取问题
1️⃣** 脏读问题(并行事务可以读取到未提交的数据信息)**
我看到的数据可能是未提交的数据(不准确)
2️⃣不可重复读问题(多次读取数据信息,每次数据信息都不一致)
我看到的数据是已经确认提交的数据(准确),可我再次查看的时候,又有人提交的新的数据,导致我多次查看到的数据不一致
3️⃣幻读问题(在进行范围数据处理时,出现异常数据信息)
我在修改某个范围的数据的时候,其他人也在修改我这个范围内的数据,导致我想确认查看数据的时候,看到了多一些数据,怀疑是我改错了?
RU(READ-UNCOMMITTED 表示读未提交)
此隔离级别设置好,会出现脏读 不可重复读 幻读
vim /etc/my.cnf
transaction-isolation=READ-UNCOMMITTED/etc/init.d/mysqld restart
RC(READ-COMMITTED 表示读已提交)
此隔离级别设置好,会避免出现脏读情况 但不可重复读 幻读依然存在
vim /etc/my.cnf
transaction-isolation=READ-COMMITTED/etc/init.d/mysqld restart
RR(REPEATABLE-READ 表示可重复读)
此隔离级别设置好,会避免出现脏读情况 不可重复读 幻读问题,不会太影响并行事务处理能力
在RR隔离级别下,为了避免幻读出现,应用了一种特殊锁机制(临键锁/邻键锁/下一键锁 next-lock)
vim /etc/my.cnf
transaction-isolation=REPEATABLE-READ/etc/init.d/mysqld restart
SR(SERIALIZABLE 可串行化)
此隔离级别设置好,会避免出现脏读情况 不可重复读 幻读问题,会降低数据库的读或写*并行处理能力
vim /etc/my.cnf
transaction-isolation=SERIALIZABLE/etc/init.d/mysqld restart