mysql

2022-11-24  本文已影响0人  呦丶耍脾气

1. 常规

MyISAM与InnoDB的区别是什么?

(1)存储结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。

(2)存储空间
MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

(3)可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。

(4)事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
(5)表锁差异
MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

(6)全文索引
MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:5.6版本开始支持全文索引。
(7)表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
(8)表的具体行数
MyISAM:保存有表的总行数,如果select count() from table;会直接取出出该值。
InnoDB:没有保存表的总行数,如果使用select count(
) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。
(9)CURD操作
MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。
(10)外键
MyISAM:不支持
InnoDB:支持

MyISAM索引与InnoDB索引的区别

2.mysql锁

2.1 锁的分类

  • 按照粒度分类:
    表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
    行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
  • 按照功能分类:
    共享锁(读锁):其他事务可以并发读取数据,阻止一切修改操作。
    排它锁(写锁):某个事务对某行数据加了排它锁,只有该事务能对其进行读和写操作,其他事务不能对其加任和锁。其他进程不能读取,也不能进行写操作。排它锁是悲观锁的一种实现方式。排它锁或阻塞其他的排它锁和共享锁。
    全局锁:使用场景比如做全库逻辑备份,该命令可以使整个库处于只读状态,阻止一切修改操作。
  • 按照逻辑分类:
    乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。

2.2 乐观锁和悲观锁的实现

版本号控制:一般是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数。当数据被修改时,version 值会 +1。当线程 A 要更新数据时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值与当前数据库中的 version 值相等时才更新,否则重试更新操作,直到更新成功。
悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。
注:

1、实现悲观锁利用select ... for update加锁, 操作完成后使用commit来释放锁;
2、innodb引擎时, 默认行级锁, 当有明确字段时会锁一行, 如无查询条件或条件字段不明确时, 会锁整个表,条件为范围时会锁整个表;
3、查不到数据时, 则不会锁表。

SELECT * FROM user WHERE id=3 FOR UPDATE;

验证:

进程 1 进程 2
begin; -
SELECT * FROM user WHERE id = 1 FOR UPDATE; -
- UPDATE user SET name = ‘test’ WHERE id = 2; 成功
- UPDATE user SET name = ‘test’ WHERE id = 1; 等待
commit; -
- 执行等待的任务,成功

2.3 死锁和死锁检测

在并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁


事务A在等待事务B释放id=2的行锁,而事务B在等待事务A释放id=1的行锁。事务A和事务B在互相等待对方的资源释放,就是进入了死锁状态。当出现死锁以后,有两种策略:
一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数innodb_lock_wait_timeout来设置
另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数innodb_deadlock_detect设置为on,表示开启这个逻辑

2.4 隔离级别与锁的关系?

3.事务

3.1事务特性(ACID)

3.2ACID各自的实现原理是什么?

3.3 事务的隔离级别

3.4 事务的实现原理

事务是通过redo日志和innodb的存储引擎日志缓冲(Innodb log buffer)来实现的。 当开始一个事务的时候,会记录该事务的lsn(log sequence number)号; 当事务执行时,会往InnoDB存储引擎的日志的日志缓存里面插入事务日志; 当事务提交时,必须将存储引擎的日志缓冲写入磁盘(通过innodb_flush_log_at_trx_commit来控制)。 也就是写数据前,需要先写日志。这种方式称为“预写日志方式”(waf)。

4.最左原则

顾名思义 从最左边进行匹配查询 ,一直向右边匹配,只遇到范围内查询进行停止 (< > + %);

5 b+树层高、好处、为啥不用二叉树

B+树层一般高为三层(可以存2千w数据),叶子节点保存索引和数据,分叶子节点保存索引,减少内存的使用,可以节约资源,而且相互之间有指针,可以提高查找效率。数据结构比较稳定。
二叉树是链表结构,相当于全表扫描。查询效率比b+树慢

6. 读写分离

  1. 工作原理
    让主数据库处理事务性增、删、改操作(INSERT、DELETE、UPDATE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
  2. 为什么要读写分离
  1. 什么时候要读写分离
    数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
  2. mysql支持的复制类型
  • MySQL-Proxy:MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。
  • Atlas:是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
  • Amoeba:由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。

7 MySQL的复制原理

8 索引

索引的分类

1)B-tree索引(包含b+tree索引)

2)辅助索引:

3)哈希索引
哈希索引是基于哈希表实现的,只有精确匹配索引所有列的查询才有效。对于每一行数据存储引擎都会对所有的所有列计算一个哈希码。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。
在MySQL中,自有Memory引擎显式支持哈希索引。哈希索引只存储对于的哈希值,所以索引的结构十分紧凑,这也让哈希索引的查找速度非常快。
哈希索引的缺点:

4)全文索引
全文索引fulltext :用于搜索很长一篇文章的时候,效果最好。全文搜索的索引。只能用于InnoDB或MyISAM表,只能为CHAR、VARCHAR、TEXT列创建。
5)空间数据索引
空间索引spatial :MyISAM表支持空间索引,用作地理数据存储。空间索引会冲所有维度来索引数据,查询时,可以有效的使用任意比较索引中的值。

B-Tree、B+Tree以及MySQL的B+Tree的区别

为什么mysql的索引使用B+树而不是B树

索引的设计原则

MySQL优化有哪些方向?

慢查询的原因有哪些

mysql底层

mysql底层

  • Server层:主要包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
  • Store层: 存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。也就是说如果我们在create table时不指定 表的存储引擎类型,默认会给你设置存储引擎为InnoDB。

因为查询缓存往往弊大于利。查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。 因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率 会非常低
一般建议大家在静态表里使用查询缓存,什么叫静态表呢?就是一般我们极少更新的表。比如,一个系统配置表、字典表,那这张表上的查询才适合使用查询缓存。好在 MySQL 也提供了这种“按需使用”的方式。你可以将my.cnf参数 query_cache_type 设置成 DEMAND。

SELECT id,name FROM student WHERE gender = '女';
这个SELECT查询先根据WHERE语句进行 选取 ,而不是将表全部查询出来以后再进行gender过滤。 这个SELECT查询先根据id和name进行属性 投影 ,而不是将属性全部取出以后再进行过滤,将这两个查询条件 连接 起来生成最终查询结果。

update执行逻辑

上一篇 下一篇

猜你喜欢

热点阅读