(一)必知必会
1 什么是MySQL
MySQL是一个关系型数据库管理系统,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。在Java企业级开发中非常常用,因为MySQL 是开源免费的,并且方便扩展。
2 数据库三大范式
- 第一范式:每个列都不可以再拆分。
- 第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
- 第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。
- 在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能。事实上我们经常会为了性能而妥协数据库的设计。
3 索引
数据库索引可快速地寻找那些具有特定值的记录。索引的原理很简单,首先,数据库索引,是数据库管理系统中一个排序的数据结构,其次,在插入索引时会对创建了索引的列的内容自动排序,并将排序结果生成倒排表。最后,在查询时只需要先拿到倒排表内容,再根据索引取出数据地址链,就能轻松拿到具体数据。其中,索引的优缺点在于:
- 优点:可以大大加快数据的索引速度
- 缺点:时间方面:创建和维护索引要耗费时间,具体地,当对表中的数据增/删/改时,索引也要动态的维护,会降低增/改/删的执行效率;空间方面:索引需要占物理空间。
3.1 索引的类型
- 主键索引:一个表只能有一个主键,主键列不允许重复,不允许为NULL,通常设置属性为autoincrement。
- 唯一索引:一个表允许结合多个列创建唯一索引,唯一索引不允许重复,允许为NULL值。
- 普通索引:基本的索引类型,没有唯一性的限制,允许为NULL值。
- 全文索引: 是目前搜索引擎使用的一种关键技术。
3.2 索引的数据结构
索引的数据结构和具体存储引擎的实现有关,我们经常使用的InnoDB存储引擎的索引包括B+树索引(默认方式)和HASH索引两种。
- hash索引:通过Hash算法将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash碰撞,则在对应Hash键下以链表形式存储。
- B+树索引:用于保存数据的索引且索引间自小而大顺序链接。插入规则:数据对象的插/删仅在叶节点上进行。叶节点:B+树有2个头指针,一个是树的根节点(最大),一个是最小叶节点。
3.3 索引与百万数据的删除
通常,通过索引查询数据比全表扫描要快,但我们也必须注意到它的代价:索引需要空间来存储,也需要定期维护, 每当有记录在表中增/删/改时,索引本身也会被修改,这意味着每条记录的增/删/改将为此多付出4、5 次的磁盘I/O操作,这些操作会降低增/删/改的执行效率。所以,在我们删除数据库百万级别数据的时候,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。所以我们想要删除百万数据的时候可以先删除索引(此时大概耗时三分多钟),然后删除其中无用数据(此过程需要不到两分钟),删除完成后重新创建索引(此时数据较少了)创建索引也非常快,约十分钟左右。与之前的直接删除绝对是要快速很多,更别说万一删除中断,一切删除会回滚,那更是坑了。
4 主键
主键是数据库确保数据行在整张表唯一性的保障,即使业务上本张表没有主键,也建议添加一个自增长的ID列作为主键。设定了主键之后,在后续的删改查的时候可能更加快速。
在主键设置上,推荐使用自增ID,不推荐使用UUID,原因在于:在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据,如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入、数据移动,导致产生很多内存碎片,造成插入性能的下降。
5 数据库结构优化
一个好的数据库设计方案对于数据库性能往往会起到事半功倍的效果。常见的数据库结构优化方案如下:
5.1 字段拆分
背景:对于字段较多的表,如果有些字段的使用频率较低,会导致当该表的数据量很大时,SQL操作会因使用频率低的字段的存在而变慢。
解决:对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。
5.2 增加中间表
对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询。
5.3 增加冗余字段
设计数据表时应尽量遵循范式理论的规约,尽可能的减少冗余字段(属性重复),让数据库设计看起来精致、优雅。但是完全去冗余也是有问题的,当表和表之间的关系越多,需要连接查询的情况也就越多,sql语句就会变得异常庞大与臃肿,并且逻辑非常的复杂,一般在这种情况下数据库要解析我们的sql运行,查询的速度会变得非常慢,对于用户的体验感也会受到影响,当再次需要修改功能时,可能也会对这个sql进行修改,对于我们之后维护与升级也会变得相当的麻烦。这时如果我们适当的把数据进行冗余,我们sql由臃肿给人一种便捷清晰的感觉,没有那么复杂的逻辑,对于之后的维护也会随之变得便利起来,运行速度也会随之提升增强,用户的体验感也会增强!
6 数据库CPU飙升到500%如何处理
- 先用操作系统命令top命令观察是不是mysqld占用导致的,如果不是,找出占用高的进程,并进行相关处理。
- 如果是mysqld造成的, show processlist,看看里面跑的session情况,是不是有消耗资源的sql在运行。找出消耗高的sql,看看执行计划是否准确, index 是否缺失,或者实在是数据量太大造成。一般来说,肯定要 kill 掉这些线程(同时观察cpu 使用率是否下降)等进行相应的调整(比如说加索引、改 sql、改内存参数)之后,再重新跑这些SQL。也有可能是每个sql消耗资源并不多,但是突然之间,有大量的 session 连进来导致 cpu 飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,比如说限制连接数等。
7 主从复制
7.1 主从复制作用
- 主数据库出现问题,可秒级切换到从数据库。
- 可以进行数据库层面的读写分离。
- 可以在从数据库上进行日常备份。
7.2 主从复制解决的问题
- 数据分布:随意开始或停止复制,并在不同地理位置分布数据备份
- 负载均衡:降低单个服务器的压力
- 高可用和故障切换:帮助应用程序避免单点失败
- 升级测试:可以用更高版本的MySQL作为从库
7.3 主从复制工作原理
- 在主库上把更新事件记录到二进制日志
- 从库将主库的日志复制到自己的中继日志
- 从库读取中继日志的事件,将其重放到从库数据中。