深入浅出Mysql

深入浅出MySQL:Mysql的的三个核心知识点:一是存储引擎的对比,二是分区的要点,三是索引的使用

(1)

InnoDB:事务性存储引擎,适合做一些经常需要更新和修改的操作当中,一般是行级锁定

MyISAM:非事务性存储引擎,适合做一些插入和读取操作比较频繁当中,一般是表级锁定

 

(2)

对于分组之后的条件不能再用where筛选而是采用having来筛选;

我们尽可能用where先过滤记录,这样因为结果集减少,将对聚合的效率大大

提高,最后再根据逻辑用having在进行过滤即可

 

(3)

Mysql在类型后面加的小括号其实是自动补全前面的空白,不是代表这个数据的长度

例如init(5),就代表会为前面带5个0修饰,实际长度还是-21474这么大8648--2147483647

 

(4)

数据类型的话,如果要求精度很高,则使用定点数(bigDecimal),如果不是那么高,就可以

采用浮点数(double,float)

 

(5)

最适合做索引的方法是

列是在where子句中的列,或者连接子句中的列,而不是在select后面的列

该列的值越不一样,越适合做索引,像性别这一列就不适用于做索引,因为只有两个,效率不明显

一般是用B-tree索引为主

 

(6)

Mysql的分区不能只对表分区而不对索引分区,两者必须同样对待。

对于同一个分区表的所有分区,必须使用同一个存储引擎

 

(7)

无论是哪种Mysql的分区类型,要么分区表上没有主键或者唯一键,否则一定是要以主键作为分区键

 

(8)

Range分区:利用取值范围将数据分成分区,区间要连续并且不能重叠,使用Values less

than 操作符进行分区定义。优点:当对于百万条数据需要删除某些记录时,直接找到对应的分区

进行删除即可,就不用delete根据id一条条比对了

List分区,采用枚举的形式进行分区

 

(9)

分表的方式:有垂直拆分和水平拆分

 

(10)

反规范化在一定程度上起着不错的作用,就是通过增加冗余列来避免多次的连接查询

 

(11)

负载均衡:利用某种均衡算法,将固定的负载量分布到不同的服务器上,以减轻单台服务器的负载

Mysql的应对措施是,主从复制或者采用分布式架构

 

(12)

表级锁,开销小,粒度大,并发度最低,其中包括了读锁和写锁

页面锁,开销中,粒度中,并发度中

行级锁,开销大,粒度小,并发度大

 

(13)

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

 

 

(14)

Mysql语句的执行过程

深入浅出Mysql_第1张图片

 

(15)

两个重要的日志模块,redo log和binlog

两者区别:redo log是在存储引擎层为Innodb引擎特有的,拥有crash-safe能力(即使数据库发生异常重启,之前提交的记录都不会丢失),是物理日志,记录的是“在某个数据页上做了什么修改”

binlog是Server层为所有引擎持有的,没有crash-safe能力,是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。

两者采用的是两阶段提交的方式来保证数据一致性

 

(16)

Mysql包含4种隔离级别

Read Uncommitted(读取未提交内容),不推荐

Read Committed(不可重复读)读取会不一致,只读取提交事务的值

Repeatable Read(可重复读)读取会一致,因为版本号控制,可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。

Serializable(可串行化),锁表严重,不推荐

 

(17)

分析sql语句性能有两种方式,一种是explain关键字分析sql语句,还有一种是启动慢查询日志

 

(18)

有时候Mysql即使设计了索引但不会使用索引,两种方式,第一种是加force index强制使用索引

select * from t force index(a) where a between 10000 and 20000;/*Q2*/

另一种是引导Mysql使用索引,可以加个order by

 

(19)

explain主要看三个参数,key看使用了哪个索引,rows看查询了多少行,Extra看是否有排序

 

(20)

复合索引必须满足最左前缀原则

 

(21)

如果索引字段在函数内被使用的话,是没有任何效果的

 

(22)

要选择数据量小的作为驱动表(也就是左边那个表)

 

(23)

乐观锁和悲观锁的区别?这两种锁在Java和MySQL分别是怎么实现的?

悲观锁假定会发生冲突,访问的时候都要先获得锁,保证同一个时刻只有线程获得锁,读读也会阻塞;乐观锁假设不会发生冲突,只有在提交操作的时候检查是否有冲突Java乐观锁通过CAS实现,悲观锁通过synchronize实现。mysql乐观锁通过MVCC,也就是版本实现,悲观锁可以通过select... for update加上排它锁

 

(24)

Mysql使用什么引擎?为什么?

支持事务、聚簇索引、MVCC

 

(25)

在一张表里查询重复的记录

思路:先分组,再having计数

SELECT email from person GROUP BY email having COUNT(eamil) > 1

 

(26)

事务的基本要素(ACID)

  1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。


(27)

事务的并发问题

  1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

  3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

(28)

MySQL事务隔离级别

事务隔离级别             脏读        不可重复读    幻读
读未提交(read-uncommitted)    是          是                    是
不可重复读(read-committed)    否        是                    是
可重复读(repeatable-read)        否        否        是
串行化(serializable)        否        否        否
总结:虽说串行化可以解决事务并发问题,可是并发程度非常低,一般不会使用,默认的事务隔离级别是可重复读.
可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。

(29)

两阶段提交试用与分布式事务,用来保证ACID。第一次提交协调者询问参与者是否准备提交或者回滚,第二次提交则执行提交或者回滚操作

(30)

一、悲观锁

顾名思义,就是对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据。所以在整个数据处理过程中,需要将数据锁定。

悲观锁的实现,通常依靠数据库提供的锁机制实现,比如mysql的排他锁,select .... for update来实现悲观锁。

二:乐观锁
顾名思义,就是对数据的处理持乐观态度,乐观的认为数据一般情况下不会发生冲突,只有提交数据更新时,才会对数据是否冲突进行检测。

如果发现冲突了,则返回错误信息给用户,让用户自已决定如何操作。

乐观锁的实现不依靠数据库提供的锁机制,需要我们自已实现,实现方式一般是记录数据版本,一种是通过版本号,一种是通过时间戳。

给表加一个版本号或时间戳的字段,读取数据时,将版本号一同读出,数据更新时,将版本号加1。

当我们提交数据更新时,判断当前的版本号与第一次读取出来的版本号是否相等。如果相等,则予以更新,否则认为数据过期,拒绝更新,让用户重新操作。

 

 

你可能感兴趣的:(Mysql)