MySQL

事务4大特性,一致性具体指什么?这4个特性mysql如何保证实现的?
事务的四大特性
  1. 原子性:事务由一系列动作组成,整个事务的所有操作,要么全部完成,要么全部不完成

  2. 一致性:一旦事务完成,在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏

  3. 隔离性:隔离状态执行事务,事务与事务之间互不影响各自的操作和执行

  4. 持久性:在事务完成以后,该事务对数据库所作的更改操作便持久的保存在数据库之中,而不是临时的,也不会回滚

Mysql怎么保证一致性的?

从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。

但是,如果你在事务里故意写出违反约束的代码,一致性还是无法保证的。例如,你在转账的例子中,你的代码里故意不给B账户加钱,那一致性还是无法保证。因此,还必须从应用层角度考虑。

从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!

Mysql怎么保证原子性的?

是利用Innodb的undo log。 undo log名为回滚日志,是实现原子性的关键,当事务回滚时能够撤销所有已经成功执行的sql语句,他需要记录你要回滚的相应日志信息

Mysql怎么保证持久性的?

是利用Innodb的redo log。

采用redo log的好处? 其实好处就是将redo log进行刷盘比对数据页刷盘效率高,具体表现如下

  • redo log体积小,毕竟只记录了哪一页修改了啥,因此体积小,刷盘快。

  • redo log是一直往末尾进行追加,属于顺序IO。效率显然比随机IO来的快。

Mysql怎么保证隔离性的?

利用的是锁和MVCC机制。

MVCC,即多版本并发控制(Multi Version Concurrency Control),一个行记录数据有多个版本对快照数据,这些快照数据在undo log中。

如果一个事务读取的行正在做DELELE或者UPDATE操作,读取操作不会等行上的锁释放,而是读取该行的快照版本。

在事务隔离级别为读已提交(Read Commited)时,一个事务能够读到另一个事务已经提交的数据,是不满足隔离性的。但是当事务隔离级别为可重复读(Repeateable Read)中,是满足隔离性的。

事务隔离级别,4个隔离级别分别有什么并发问题?
  • 未提交读:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

  • 已提交读:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

  • 可重复读:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生

  • 串行化:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

Mysql默认隔离级别?如何保证并发安全?

MySql默认采用可重复读

MySql存储引擎使用的InnoDB,InnoDB支持行级锁和表级锁,默认使用的是行级锁,InnoDB的行级锁有两种:

  • 共享锁:只允许一个事务去读一行,阻止其他事务获取相同数据集的排他锁

  • 排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享锁和排他锁

4、RR和RC如何实现的?RR使用场景?对比volatile可见性,为什么RR的事务要设计成不能读另一个事务已经提交的数据?

隔离级别的单位是数据表还是数据行?如串行化级别,两个事务访问不同的数据行,能并发?
  1. 事务隔离级别为读提交时,写数据只会锁住相应的行

  2. 事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。

  3. 事务隔离级别为串行化时,读写数据都会锁住整张表

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

MYSQL MVCC实现机制参考链接:https://blog.csdn.net/whoamiyang/article/details/51901888

关于next-key 锁可以参考链接:https://blog.csdn.net/bigtree_3721/article/details/73731377**

存储引擎Innodb和Myisam的区别以及使用场景

区别:

  1. MyISAM只支持表级锁,而InnoDB支持表级锁和行级锁

  2. MyISAM不支持外键,而InnoDB支持外键

  3. MyISAM不提供事务支持,而InnoDB提供事务支持

  4. MyISAM 强调的是性能,每次查询具有原子性,其执行速度比 InnoDB 类型更快

  5. MyISAM 在数据崩溃之后不能进行安全恢复,而InnoDB具备崩溃修复能力

  6. 因为 MyISAM 缓存有表 meta-data(行数等),因此在做 COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于 InnoDB 来说,则没有这种缓存

使用场景:

MyISAM 更适合读密集的表,而 InnoDB 更适合写密集的表。 在数据库做主从分离的情况下,经常选择 MyISAM 作为主库的存储引擎。

一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM 的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB 是不错的选择。如果你的数据量很大(MyISAM 支持压缩特性可以减少磁盘的空间占用),而且不需要支持事务时,MyISAM 是最好的选择。

介绍Inodb锁机制,行锁,表锁,意向锁

mysql锁机制:

InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

Innodb 行级锁 record-level lock大致有三种:record lock, gap lock and Next-KeyLocks。

record lock 锁住某一行记录 gap lock 锁住某一段范围中的记录 next key lock 是前两者效果的叠加。

InnoDB实现了以下两种类型的行锁:

  • 共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁;

  • 排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(意向共享锁和意向排他锁)。这两种意向锁都是表锁。意向锁是InnoDB自动加的,不需要用户干预。 对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任意锁。

事务可以通过以下语句显示给记录集加共享锁或者排他锁:

SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE  #共享锁
SELECT * FROM table_name WHERE ... FOR UPDATE  #排他锁

InnoDB的行锁实现的特点:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将会使用表锁。因为MySQL的行锁是针对索引加的锁,
而不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引建,是会出现锁冲突的。

对于键值在条件范围内但并不存在的记录,叫做间隙。InnoDB会对这个间隙加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。 InnoDB使用间隙锁的目的:一是为了防止幻读,二是为了满足其恢复和复制的需要。

InnoDB如何解决死锁问题的:

在InnoDB中,锁是逐步获得的,因此发生死锁是可能的。发生死锁后,InnoDB一般都能自动检测到,并使一个事务释放锁并回退,另外一个事务获得锁,并继续完成事务。但在涉及外部锁, 或涉及表锁的情况下,InnoDB并不能完全自动检测到死锁,这需要通过设置锁等待超时参数innodb_lock_wait_timeout来解决。

介绍MVCC

https://blog.csdn.net/whoamiyang/article/details/51901888

哈希索引是如何实现的?

Hash索引:一对一主键 不利于范围查询 无法利用前缀查询

所谓Hash索引,当我们要给某张表某列增加索引时,将这张表的这一列进行哈希算法计算,得到哈希值,排序在哈希数组上。所以Hash索引可以一次定位,其效率很高

哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

哈希索引可细分为静态哈希和动态哈希这两大类

B树索引为什么使用B+树,相对于B树有什么优点?为什么不能红黑树?要提到磁盘预读

参考:http://www.liuzk.com/410.html

聚簇索引和非聚簇索引区别

1)聚簇索引

  • 一个索引项直接对应实际数据记录的存储页,可谓“直达” 主键缺省使用它

  • 索引项的排序和数据行的存储排序完全一致,利用这一点,想修改数据的存储顺序,可以通过改变主键的方法(撤销原有主键,另找也能满足主键要求的一个字段或一组字段,重建主键)

  • 一个表只能有一个聚簇索引(理由:数据一旦存储,顺序只能有一种)

2) 非聚簇索引

  • 不能“直达”,可能链式地访问多级页表后,才能定位到数据页

  • 表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。

  • 一个表可以有多个非聚簇索引

回表查询和覆盖索引

回表查询:即先定位主键值,再根据主键值定位行记录,性能相对于只扫描一遍聚集索引树的性能要低一些。

覆盖索引:索引覆盖是一种避免回表查询的优化策略。具体的做法就是将要查询的数据作为索引列建立普通索引(可以是单列索引,也可以一个索引语句定义所有要查询的列,即联合索引),这样的话就可以直接返回索引中的的数据,不需要再通过聚集索引去定位行记录,避免了回表的情况发生。

覆盖索引的优点

  1. 索引条目通常远小于数据行的大小,因为覆盖索引只需要读取索引,极大地减少了数据的访问量。

  2. 索引是按照列值顺序存储的,对于IO密集的范围查找会比随机从磁盘读取每一行数据的IO小很多。

  3. 一些存储引擎比如MyISAM在内存中只缓存索引,数据则依赖操作系统来缓存,因此要访问数据的话需要一次系统调用,使用覆盖索引则避免了这一点。

  4. 由于InnoDB的聚簇索引,覆盖索引对InnoDB引擎下的数据库表特别有用。因为InnoDB的二级索引在叶子节点中保存了行的主键值,如果二级索引能够覆盖查询,就避免了对主键索引的二次查询。

参考:https://www.cnblogs.com/yanggb/p/11252966.html

如何创建索引?
    1. 主键索引(PRIMARY KEY):它是一种特殊的唯一索引,不允许有空值。一般在建表的时候同时创建主键索引。

    2. 唯一索引(UNIQUE):唯一索引列的值必须唯一,但允许有空值。

      ALTER TABLE 表名 ADD UNIQUE(字段名)
      
    3. 普通索引(INDEX):最基本的索引,它没有任何限制。

      ALTER TABLE 表名 ADD INDEX 索引名称(字段名称)
      
    4. 组合索引(INDEX):一个索引包含多个列,多用于避免回表查询。

      ALTER TABLE 表名 ADD INDEX 索引名称(字段名称1,字段名称2,字段名称N)
      
    5. 全文索引(FULLTEXT):全文检索,是目前搜索引擎的一种关键技术,一般用于有大量的text类型数据的字段

      ALTER TABLE student_register ADD FULLTEXT(字段名称)
      
如何使用索引避免全表扫描?
  1. 尽量不要使用like进行模糊查询,如果非要使用,尽量使用后导查询(左模糊like:...%)

  2. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描

  3. 尽量避免在 where 子句中使用!=或< >操作符,否则将引擎放弃使用索引而进行全表扫描。

  4. 尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描

  5. in 和 not in 也要慎用,否则会导致全表扫描

  6. 应考虑在 where 及 order by 涉及的列上建立索引。

Explain语句各字段的意义
  1. id

每个被独立执行的操作的标识,表示对象被操作的顺序;id值大,先被执行;如果相同,执行顺序从上到下。

若没有子查询和联合查询,id则都是1。Mysql会按照id从大到小的顺序执行query,在id相同的情况下,则从上到下执行。

  1. select_type

查询中每个select子句的类型

(1)SIMPLE

(2)PRIMARY/UNION

(3)DEPENDENT UNION/UNIOIN RESULT

(4)SUBQUERY/DEPENDENT SUBQUERY

(5)DERIVED/MATERIALIZED

(6)UNCACHEABLE SUBQUERY/UNCACHEABLE UNION

  1. table

名字,被操作的对象名称,通常是表名,或者表的别名,或者一个为查询产生临时表的标示符(如派生表、子查询、集合)。

  1. type

代表查询执行计划中表使用的连接方式。

连接操作类型及级别:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般来说,得保证查询至少达到range级别,最好能达到ref。

  1. partitions

匹配的分区信息(对于非分区表值为NULL)。

  1. possible_keys

备选的索引(列出可能被使用到的索引)

  1. key

经优化器选定的索引;常用ANALYZE TABLE命令,可以使优化器正确地选择索引。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

  1. key_len

被优化器选定的索引键的长度,单位是字节。

  1. ref

表示本行被操作的对象的参照对象(被参照的对象可能是一个常量用const表示,也可能是其他表的key指向的对象)。

  1. rows

查询执行所扫描的元组个数(对于InnoDB,此值是估计值)。

  1. filtered

按照条件表上数据被过滤的元组个数的百分比,rows×filtered/100可以求出过滤后的元组数即实际的元组数。

  1. Extra

(1)using where

(2)using temporary

(3)using filesort

(4)using index

(5)using join buffer

(6)impossible where

(7)select tables optimized away

(8)distinct

最左前缀!!联合索引B+树是如何建立的?是如何查询的?当where子句中出现>时,联合索引命中是如何的? 如 where a > 10 and b = “111”时,联合索引如何创建?mysql优化器会针对得做出优化吗?
MySQL中一条SQL语句的执行过程
image
  1. 连接

    SQL客户端与与服务器建立连接,该请求被发送到连接管理器,连接成功后会验证权限等,这过程其实就是一个TCP连接的过程。注意,MySQL服务器与客户端之间的通信是“半双工”的,意味着任意时刻,要么是服务器向客户端发送数据,要什么是客户端向服务器发送数据(请求),不能同时进行。

  2. 查询缓存

    如果查询命中缓存(一个大小写敏感的哈希查找实现的)则直接返回结果(注意:在返回结果前还会检查一次用户号的权限);如果查询没有命中缓存,则进行下一步sql解析。

  3. 语法解析器和预处理

    首先通过mysql关键字将语句解析,会生成一个内部解析树,mysql解析器将对其解析,查看是否是有错误的关键字,关键字顺序是佛正确; 预处理器则是根据mysql的规则进行进一步的检查,检查mysql语句是否合法,如,库表是否存在,字段是否存在,字段之间是否模棱两可等等,预处理器也会验证权限。

  4. 查询优化器

    sql语句在优化器中转换成执行计划,一条sql语句可以有多种方式查询,最后返回的结果肯定是相同,但是不同的查询方式效果不同,优化器的作用就是:选择一种合适的执行计划 mysql是基于成本的优化器,他将预测执行此计划的成本,并选择成本最小的那条

  5. 执行计划

    和很多关系型数据库不同的是,mysql不会产生查询字节码来执行查询,而是生成查询的一颗指令树,通过存储引擎执行指令并返回结果。最终的执行计划包含了重构查询的全部信息,通过EXPLAIN EXTENDED 和SHOW WARNINGS就可以看到重构的查询。

  6. 执行SQL

    在解析和优化阶段,MySQL将生成查询对应的执行计划,由执行计划调用存储引擎的API来执行查询MySQL就行(在此过程中只是简单的根据执行计划给出的指令逐步执行) 将结果返回给客户端;即使查询不需要返回结果,MySQL也会返回影响到的行数。注意:返回结果时是个逐步返回结果的过程,并不是一次性查询完然后返回一个大的结果集

https://zhuanlan.zhihu.com/p/70295845

数据库几大范式
  • 第一范式:列不可再分,数据表的每一个字段都具备原子性,不能在进行分割

  • 第二范式:在第一范式的基础之上,数据表的每一行数据有一个可进行标识的主属性字段(主键),该行的其余字段都应全部依赖于该主属性字段(主键),如果存在不依赖于该主键的字段,必须将其分离出去

  • 第三范式:在第二范式的基础之上,针对于数据的冗余性,表与表之间的数据引用关系,若存在两张数据表A和B,B的字段中出现了A的主键,则B中不能再出现A中依赖于其主键的其它字段(即不能有依赖传递)

  • 反范式:指不遵循三大范式,通过增加冗余或重复的数据来提高数据库的读性能。反范式可以减轻数据库的关联查找所带来的负担

数据库基本查询关键字使用,如left join on,where,beteen and,group by,having,limit,聚合函数等。
left join,right join,inner join,outer join的含义及区别
mysql主从复制过程,binlog记录格式,复制的异步半同步同步模式区别
主从复制或读写分离等数据不一致性问题以及如何解决
银行的话,可以会考mysql数据类型,如余额要用decimal
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。