一、事务
1. 什么是事务
MySQL事务是一组sql语句或一个独立运行的工作单元。这个工作单元要么全部执行,要么全部不执行。
2. 事务的四大特性
原子性
:一个事务不可再分割,事务中的所有操作,要么全部完成,要么全部不完成。
一致性
:一个事务执行会使数据从一个一致状态切换到另外一个一致状态。也就是说,在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
隔离性
:一个事务所做的修改在最终提交之前,对其它事务是不可见的。也就是说一个事务的执行不会受到其它事务的干扰。
持久性
:一个事务一旦提交以后,对数据的修改就会永久的保存到数据库中,即便系统故障也不会丢失。
3. 事务的并发问题
① 事务并发问题什么时候发生?
当多个事务同时操作同一个数据库的相同数据时,就会发生并发问题。
② 事务的并发问题有哪些?
脏读
:对于两个事务T1、T2, T1 读取了已经被T2 更新但还没有被提交的数据。如果事务T2进行了回滚, T1读取到的数据就是临时且无效的。
不可重复读
:对于两个事务T1、T2, T1 读取了一个数据, 然后 T2 更新了该数据。如果T1再次读取同一个数据, 值就不相同了。
幻读
:对于两个事务T1、T2, T1 从一个表中读取了一个数据, 然后T2 在该表中插入了一些新的行。如果T1 再次读取同一个表, 就会多出几行。
③ 如何避免事务的并发问题?
通过设置事务的隔离级别进行避免事务的并发问题。事务有以下四个隔离级别:
读未提交
(read-uncommitted)读已提交
(read-committed) 可以避免脏读可重复读
(repeatable-read) 可以避免脏读、不可重复读和一部分幻读串行化
(serializable) 可以避免脏读、不可重复读和幻读
MySQL数据库(InnoDB引擎)默认使用的隔离级别是:可重复读( Repeatable read );
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
二、索引
1. 什么是索引
索引
是对数据库表中一列或多列的值进行排序的一种结构,使用索引可以提高数据库中特定数据的查询速度
2. 索引的优缺点
优点
① 使用索引可以大大加快数据的查询速度
② 通过创建唯一索引,可以保证数据库表中每一行数据的唯一性。
③ 在使用分组和排序子句进行数据查询时,使用索引可以减少在查询中分组和排序的时间。
缺点
① 创建索引和维护索引需要时间,随着数据量的增加所需要时间也会增加。
② 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。
③ 索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸
2. 索引的设计原则
索引设计不合理或者缺少索引都会对数据库和应用程序的性能造成障碍。高效的索引对于获得良好的性能非常重要。设计索引时,应该考虑以下准则:
① 索引并非越多越好,一个表中如有大量的索引,不仅占用磁盘空间,而且会影响 INSERT、 DELETE、UPDATES等语句的性能,因为当表中的数据更改的同时索引也会进行调整和更新。
② 避免对经常更新的表进行过多的索引,并且索引中的列尽可能少。而对经常用于查询的字段应该创建索引,但要避免添加不必要的字段。
③ 数据量小的表最好不要使用索引,由于数据较少,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果。
④ 在条件表达式中经常用到的不同值较多的列上建立索引,在不同值很少的列上不要建立索引。比如在学生表的“性別”字段上只有“男”与“女”两个不同值,因此就无须建立索引。如果建立索引不但不会提高查询效率,反而会严重降低数据更新速度。
⑤ 当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引副需能确保定义的列的数据完整性,以提高查询速度。
⑥ 在频繁进行排序或分组(即进行group by或 order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。
三、数据库设计三大范式
1. 第一范式
确保每列保持原子性
第一范式是最基本的范式。要求数据库表的每一列都是不可分割的原子数据项。
- 第二范式
确保表中的每列都和主键相关
第二范式在第一范式的基础上,第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
- 第三范式
确保每列都和主键列直接相关,而不是间接相关
第三范式是在第二范式的基础上,需要确保数据表中的每一列数据都和主键直接相关,而不是间接相关。
学生表:
课程表:
成绩表:
四、MySQL的主从复制
1. 概念
MySQL 主从复制
是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。
2. 原理
从库生成两个线程,一个I/O线程,一个SQL线程。
I/O线程
去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;
主库会生成一个 log dump 线程,用来给从库 I/O线程传binlog。
SQL线程
会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致。
3. 主从复制用途
①
读写分离
,在开发工作中,有时候会遇见某个sql
语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
②
数据实时备份
,当系统中某个节点发生故障时,可以方便的故障切换。
五、MySQL中的锁
1. 为什么要加锁
数据库的锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。在数据库中加锁是保证在高并发的情况下,访问数据库的时候,数据不会出现问题。
2. 锁的分类
按操作分:
① 读锁(共享锁):针对同一份数据,多个读取操作可以同时进行而不互相影响。
② 写锁(排它锁):当前写操作没有完成前,会阻断其他写锁和读锁。
按粒度分:
① 表锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
② 行锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
③ 页锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
六、如何做 MySQL的性能优化
① 当只需要一条数据的时候,使用 limit 1
② 尽量避免使用 select * ,在查询的时候列出需要查询的字段。
③ 使用 join 代替子查询。
④ 减少使用 or,使用 in 或者 union(union all) 代替。
⑤ 为搜索字段创建索引。但是不要过度索引,索引越多,占用空间越大,反而性能变慢。
⑥ 避免进行类型转换,不然会导致索引失效。
⑦ 对查询语句使用explain 。 使用explain ,可以帮助了解MySQL是如何处理sql语句的, 可以查看到sql的执行计划,这样就能更好的去了解的sql语句的不足,然后优化语句。
⑧ 垂直分割,将常用和有关系的字段放在相同的表中,把一张表的数据分成几张表 这样可以降低表的复杂度和字段的数目,从而达到优化的目的
作者:扬帆向海
原文链接:https://zhangxy.blog.csdn.net/article/details/105999361