MySQL面试总结

MySQL逻辑架构

第一层与传统C/S 架构相似,包含:连接处理、授权认证、安全等。

第二层是MySQL的核心服务 包括:查询解析、分析、优化、缓存以及所有的内置函数(例如:日期、时间、数学和加密函数)。以及所有的跨存储引擎的功能:存储过程、触发器、视图等。

第三层是存储引擎。存储引擎负责MySQL中数据的存储和提取。服务器通过API和存储引擎进行通信。
不同的存储引擎对外暴露统一封装好的API提供调用,调用者不需要关注底层实现,不同存储引擎之间也不会相互通信,而只是简单的响应上层的服务器请求。

InnoDB和MyISAM的差异

  1. 事务 InnoDB支持,MyISAM不支持。
  2. 外键 InnoDB支持,而MyISAM不支持。
  3. 索引B+叶子阶段存储的信息不一样,InnoDB是聚簇索引叶子节点存储的是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。
  4. InnoDB不保存表的具体行数,执行select count(*) 需要全表扫描。而MyISAM用一个变量保存了整个表的行数。[InnoDB 无内置变量是因为不同事务下的行数不一样]
  5. InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁。[InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上,如果访问没有命中索引,也无法使用行锁,将要退化为表锁。update ... where 没命中索引会锁整个表]
  6. InnoDB表必须有唯一索引(如主键)(用户没有指定的话会自己找/生产一个隐藏列Row_id来充当默认主键),而Myisam可以没有

MyISAM:写操作是锁表[排他锁],读操作是共享锁,支持在读的时候插入数据,读性能优秀,不支持事务,崩溃后修复困难。

Select语句的执行过程

  1. 客户端发送一条查询给服务器
  2. 服务器先查询缓存,如果命中了缓存,立刻返回存储在缓存中的结果。否则进入下一阶段。
  3. 服务器进行SQL解析,预处理,染回优化器生产对应的执行计划。
  4. MySQL 根据优化器生成的对应的执行计划,调用存储引擎的API来执行查询。
  5. 将结果返回给客户端。

事务的基本特性

ACID 原子性/持久性/隔离性/一致性
一致性:一个事务必须使数据库从一个一致性状态变换到另一个一致性状态[语义上的合法状态],原子性/持久性/隔离性都是为了来保障一致性的。

  1. Atomicity(原子性):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  2. Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  3. Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  4. Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

ACID实现原理

  1. C 一致性:
    • 数据库层面:数据库通过A原子性、I隔离性、D持久性来保证一致性。
    • 应用层:通过代码保障逻辑上的一致,人为决定是否回滚和提交事务。
  2. A 原子性: 事务要么成功要么失败,不允许部分成功失败,通过undo log回滚来保障。
  3. D 持久性: 持久是通过redo log
  4. I 隔离性: 锁+MVCC机制来保障不同事务之间不出现相互影响。

InnoDB情况下 有表锁吗

锁表,是通过行锁+间隙锁来实现的。RU和RC都不存在间隙锁,所以也不存在锁表的情况。
该说法只在RR和Serializable中是成立的。如果隔离级别为RU和RC,无论条件列上是否有索引,都不会锁表,只锁行!
PS: mysql 会对

Record Locks Gap Locks

Record Locks:简单翻译为行锁吧。注意了,该锁是对索引记录进行加锁!锁是在加索引上而不是行上的。注意了,innodb一定存在聚簇索引,因此行锁最终都会落到聚簇索引上!
Gap Locks:简单翻译为间隙锁,是对索引的间隙加锁,其目的只有一个,防止其他事物插入数据。在Read Committed隔离级别下,不会使用间隙锁。这里我对官网补充一下,隔离级别比Read Committed低的情况下,也不会使用间隙锁,如隔离级别为Read Uncommited时,也不存在间隙锁。当隔离级别为Repeatable Read和Serializable时,就会存在间隙锁。
Next-Key Locks:这个理解为Record Lock+索引前面的Gap Lock。记住了,锁住的是索引前面的间隙!比如一个索引包含值,10,11,13和20。那么,间隙锁的范围如下

(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

MySQL隔离级别

读未提交/读已提交/可重复读/串行化

MySQL 默认是RR 为什么你们项目中用RC

在RC级别下,不可重复读问题需要解决么?

不用解决,这个问题是可以接受的!毕竟你数据都已经提交了,读出来本身就没有太大问题!Oracle的默认隔离级别就是RC,你们改过Oracle的默认隔离级别么?

在RC级别下,主从复制用什么binlog格式?

OK,在该隔离级别下,用的binlog为row格式,是基于行的复制!Innodb的创始人也是建议binlog使用该格式!
前提:主从复制是基于binglog的 binlog的三种

  • statement:记录的是修改SQL语句 「早期5.1之前 binlong 使用这个格式 会主从不一致性的问题!EG: 就是在master上执行的顺序为先删后插!而此时binlog为STATEMENT格式,它记录的顺序为先插后删【因为没有间隙锁 记录的SQL顺序可能和实际执行顺序不一样】从(slave)同步的是binglog,因此从机执行的顺序和主机不一致!就会出现主从不一致,所以此历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!」
  • row:记录的是每行实际数据的变更
  • mixed:statement和row模式的混合

MySQL默认是 可重复读,实际项目中一般使用读以提交

select * from test where id ❤️ for update;

  • 在RR隔离级别下,存在间隙锁,出现死锁的概率比RC的大。「在RR下,存在间隙锁,可以锁住(2,5)这个间隙,防止其他事务插入数据!
    而在RC隔离级别下,不存在间隙锁,其他事务是可以插入数据!」
  • 在RR隔离级别下,列条件没中索引会锁表,RC这种情况下锁行。

在update 时候 在RC隔离级别下,其先走聚簇索引,进行全部扫描,并加上X锁「排他锁」,实际中,MySQL做了优化,在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,把不满足条件的记录放锁。在RR隔离级别下,走聚簇索引,进行全部扫描,最后会将整个表锁上,「record lock + gap lock」把行和间隙全部上锁,看起来像是表锁了。

  • 在RC隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性!

在5.1.15的时候,innodb引入了一个概念叫做“semi-consistent”,减少了更新同一行记录时的冲突,减少锁等待。
所谓半一致性读就是,一个update语句,如果读到一行已经加锁的记录,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足update的where条件。若满足(需要更新),则MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)!

+----+-------+
| id | color |
+----+-------+
| 1 | red |
| 2 | white |
| 5 | red |
| 7 | white |
+----+-------+

脏读/不可重复读/幻读

  1. 脏读:读出来其他事物还未提交的数据
  2. 不可重复读:在同一个事务中,针对相同的行,2次查询的数据内容不一致。
  3. 幻读: 在同一个事务中的 相同条件的 多次查询出现了行的增减。

不可重复读侧重的是数据内容的修改,幻读侧重的是数据行的增删。

redolog/undolog/binlog

Redolog:来记录某数据块被修改后的值,可以用来恢复未写入 datafile 的已成功事务的数据。[事务At提交成功 但未写入datafile,系统重启,重启后会根据redolog执行剩下的更新操作]

Undolog:也就是我们常说的回滚日志文件 主要用于事务中执行失败,进行回滚,以及MVCC中对于数据历史版本的查看。

binlog:是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志文件。

MVCC机制

https://zhuanlan.zhihu.com/p/367820387
多版本并发控制的前提是 快照度「 readview」 和隐藏列。
readview 是某一时刻所有未提交事务的快照。其中包含几个关键参数【最大、最小、当前 事务号 活跃的事务列表】

  • m_ids:表示生成ReadView时,当前系统正在活跃的读写事务的事务Id列表。
  • min_trx_id:表示生成ReadView时,当前系统中活跃的读写事务的最小事务Id。
  • max_trx_id:表示生成ReadView时,当前时间戳InnoDB将在下一次分配的事务id。
  • creator_trx_id:当前事务id。
    每一行数据后都有2个隐藏列
  • trx_id 记录当前【最新】修改该行的事务号。
  • roll_pointer 指针指向上一个版本的位置信息.一般是指的备份的版本信息[指向undoLog,插入操作时无上个版本该字段为空]
  • ReadView 用来存储当前活跃的事务[记录的是trx_id],也就是开始还未提交的事务。如果当前行的trx_id小于ReadView中的最小值,说明事务以提交当前行可展示,若trx_id在ReadView的范围内,说明当前行正在进行事务中,不能被展示,则根据roll_point找到上一行的信息,并且判断trx_id和ReadView的关系来辨别是否可以展示,若不可以则重复以上操作。

RC级别下每次查询都会使用一个最新的ReadView,RR级别下第一次读会生成一个ReadView,之后的读都复用之前的ReadView。

MVCC只在RR RC2个级别下工作,Read Uncommit 总是读取到最新的行而不是符合当前事务版本的数据行,Serializable会对读取的所有行加锁,也用不上多版本并发控制.

快照读和当前读

  1. 快照读:读取的是记录数据的可见版本(可能是过期的数据),不用加锁
    • 一般select是快照读,所以在事务A中修改数据,在事务B中读取该数据依然能够读取,是因为读取的快照。而不是违背了X锁的原则。
    • 事务A还未提交,那么select出来的数据都是read view版本链中的数据,不会因为其它事务的提交或者未提交影响事务对同一张表的查询结果(遵循多版本并发控制规则)
  2. 当前读: 读取的是记录数据的最新版本,并且当前读返回的记录都会加上锁,保证其他事务不会再并发的修改这条记录。
    • update、insert、delete 当前读

MySQL的锁

  1. Intention Locks(意向锁)

    • 直接根据意向锁是否存在而判断是否有锁冲突。可以避免进行数据扫描到具体行来判断是否存在锁冲突。
  2. 共享锁/排他锁

  3. Gap Locks(间隙锁):间隙锁可以被多个事务同时锁定。

    • 只在RR & Serializable 2个级别下生效。
  4. Next-Key Locks : 索引记录上的记录锁定和索引记录之前的间隙上的间隙锁定的组合。[ record lock + Cap lock 锁住当前记录及记录前后最近的间隙防止其他事务插入数据出现幻读的现象。]

  5. Record Locks(记录锁):也就是常说的行锁。

  6. 表级别锁:

    • Lock Table...Read / Lock Table...Write 方式开启表锁。
    • 意向锁Intention Locks也是表级锁。
    • 其他默认行级锁。

官方文档上标注的锁

锁的开启方式

  1. for update: 加上排他锁,持有排他锁的事务可以进行读写,其他事务不可以进行读写。
    • 另一个非锁定读的操作来读取该行那么数据不会阻塞,读取的是该行的快照版本,而不是当前版本,当前版本读会被阻塞。
    • 指改行之前的数据版本,也就会出现脏读,所以也称为非锁定读,因为不需要等待被访问行的锁的释放。非锁定读的方式极大提高了数据库的并发性。在InnoDB存储引擎中,这是默认的读取方式。
  2. lock in share model: 加上共享锁,持有意向锁的事务可以进行读写,其他事务可读不可写。

索引的数据为什么是B+树

数据查询上: B+树和B树的区别在于 B树非叶子节点也存储了数据「这个数据结构导致了 如果要将索引加载到内存中 因为非叶子节点也带了data 会占用非常多的内存空间 」,在进行数据查找的时候,B树非叶子节点的查找全部是随机IO,会比较耗时。B+树的非叶子节点只存储索引 可以加载到内存中,只有第一次读叶子节点是随机IO 后续全是顺序IO节省时间。因为后续的叶子节点数据 是顺序存储的。

数据更新上

类似于 Redis的跳表数据结构一样 当数据足够大的时候 我们使用小空间换时间是非常划算的,这时候只需要把索引加载到内存中 可以极大的提升查询效率。
https://blog.csdn.net/a519640026/article/details/106940115

MySQL查询效率中有个很关键的指标 磁盘IO次数,且磁盘IO一次读出的数据量是固定的,B-数非叶子节点上比b+数多了数据域data,会使当前IO下的磁盘IO次数增多,且B+数的所有数据都在叶子节点且存在指向下一个叶子节点的指针便于范围查询,B-树的范围查询需要遍历整个树。

红黑树一般是在内存中使用的数据结构,若用在数据库索引中会出现数的深度过大导致的磁盘IO读写过于频繁。

  1. Hash索引 : 使用hash表实现的,无法保障顺序性,区间查询无法使用索引,需要扫描全表。等值查询的效率较高。
  2. 二叉查找树:可以解决排序问题,极端情况下会退化为链表。
  3. 平衡二叉树:旋转操作效率低
    • 非叶子节点最多拥有两个子节点
    • 非叶子节值大于左边子节点、小于右边子节点
    • 树的左右两边的层级数相差不会大于1
    • 没有值相等重复的节点
  4. B树 :B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个)
  5. 红黑树: 对严格的平衡做了取舍和引入红黑节点,解决了平衡二叉树旋转效率过低的问题,树依然太深在磁盘场景下IO次数太多不符合预期。

AVL树/红黑树

红黑树和AVL树都是最常用的平衡二叉搜索树,它们的查找、删除、修改都是O(lgn) time

AVL树和红黑树有几点比较和区别:

  1. AVL树是更加严格的平衡,因此可以提供更快的查找速度,一般读取查找密集型任务,适用AVL树。
  2. 红黑树更适合于插入修改密集型任务。
  3. 通常,AVL树的旋转比红黑树的旋转更加难以平衡和调试。

总结:

  1. AVL以及红黑树是高度平衡的树数据结构。它们非常相似,真正的区别在于在任何添加/删除操作时完成的旋转操作次数。
  2. 两种实现都缩放为a O(lg N),其中N是叶子的数量,但实际上AVL树在查找密集型任务上更快:利用更好的平衡,树遍历平均更短。另一方面,插入和删除方面,AVL树速度较慢:需要更高的旋转次数才能在修改时正确地重新平衡数据结构。
  3. 在AVL树中,从根到任何叶子的最短路径和最长路径之间的差异最多为1。在红黑树中,差异可以是2倍。
  4. 两个都给O(log n)查找,但平衡AVL树可能需要O(log n)旋转,而红黑树将需要最多两次旋转使其达到平衡(尽管可能需要检查O(log n)节点以确定旋转的位置)。旋转本身是O(1)操作,因为你只是移动指针。

索引失效

  1. 模糊匹配前边带百分号 %like
  2. 索引列参与计算,使用了函数
  3. 非最左前缀顺序
  4. 使用is not null 或者 is null
  5. 使用不等于(!= 或者<>) [<>走全表扫描一般会更快]
  6. or操作有至少一个字段没有索引
  7. 回表查询的结果集过大 [超过配置的最大范围]

explain命令

  1. id:选择标识符
  2. select_type:表示查询的类型
  3. table:输出结果集的表
  4. partitions:匹配的分区
  5. type:表示表的连接类型
  6. possible_keys:表示查询时,可能使用的索引
  7. key:表示实际使用的索引
  8. key_len:索引字段的长度
  9. ref:列与索引的比较
  10. rows:扫描出的行数(估算的行数)
  11. filtered:按表条件过滤的行百分比
  12. Extra:执行情况的描述和说明

select_type/查询类型

  1. SIMPLE(简单SELECT,不使用UNION或子查询等)
  2. PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
  3. UNION(UNION中的第二个或后面的SELECT语句)
  4. DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
  5. UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)
  6. SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)
  7. DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)
  8. DERIVED(派生表的SELECT, FROM子句的子查询)
  9. UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

type

表示这个查询访问数据的方式,或者说MySQL查找行的方式,MySQL手册中称为连接方式。
常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)

Extra

MySQL where语句的几种应用方式

从好到坏依次为:

  • 在索引中使用Where来过滤不匹配的记录 这是在存储引擎层完成的
  • 使用索引覆盖来扫描所需要的数据[Extra 中出现using index],直接从索引过滤不需要的记录并返回命中结果,这是在MySQL服务器层完成的事情.
  • 从数据表中返回数据,然后过滤不满足要求的记录[Extra列中出现 Using where],这是在MySQL服务器层完成的事情,MySQL需要先从数据表读出记录然后过滤。

where后可以使用聚合函数吗

不能,聚合函数也叫列函数,是基于确定的结果集的计算函数. where是对数据行进行过滤的。where的执行顺序在聚合函数的前面,处于确定结果集的过程中,聚合函数依赖where筛选的确定的结果集进行的计算。

查询索引explain的type中 all index和ref的区别

all和index都是全表扫描,但是all是硬盘中读取,index是索引中读取,ref是非唯一索引扫描,返回匹配到搜索值的所有行,可能会查找到多个行。在聚合索引中(a,b) 对a进行查找满足ref单独查询b满足index,对非索引字段c查找满足all。ref和index这种扫描方式中通常可能伴随着回表操作,对索引进行优化时候应该尽量避免回表操作,常常可以使用索引覆盖的方法【非唯一索引通常存储的是该索引字段和唯一索引也就是pk,若在索引查找中没有获得需要的全部数值,就会根据拿到的主键id去根据id获得需要的字段,这个操作称为回表格】相关问题列表

三星系统【three-star system】通常指的是优秀的索引需要满足的三个原则

  • 索引将相关记录放到一起则获得一星
  • 索引中数据的顺序和查找中的排列顺序一致则获得二星
  • 如果索引中的列包含了查询中需要的全部列则获得三星

三范式

第一范式(1NF):属性不可分割,即每个属性都是不可分割的原子项。(实体的属性即表中的列)

第二范式(2NF):满足第一范式;且不存在部分依赖,即非主属性必须完全依赖于主属性。(主属性即主键;完全依赖是针对于联合主键的情况,非主键列不能只依赖于主键的一部分)

第三范式(3NF):满足第二范式;且不存在传递依赖,即非主属性不能与非主属性之间有依赖关系,非主属性必须直接依赖于主属性,不能间接依赖主属性。(A -> B, B ->C, A -> C)

索引可以带来的优点:

  • 索引大大减少了服务器需要扫描的数据量
  • 索引可以帮助服务器避免排序和临时表
  • 索引可以将随机IO变为顺序IO

聚簇索引

新插入的表行所在的表页的索引是聚簇索引。
若索引行的顺序和表行的索引具有强关联性可说这个索引是聚集的。但是不一定是聚簇索引。
一个表只允许有一个聚簇索引。在某个特定时间可能会有多个索引是聚集的。

索引页和表页

表和索引行都被存储在页中。页的大小一般为4/8 KB. 缓冲池和IO的活动都是基于页的。
页的大小决定了一页可以存储多少个索引行,表行。

索引页和表页都是在页内存储数据,差异是一个存储的是data数据,一个存储的是索引数据。若索引页存储的是非聚簇索引,那么连续的索引页指向的是非连续的data数据页。此时全索引扫描是顺序IO,对指向的数据的扫描是随机Io.

聚簇索引页是连续的所指向的data数据页也是连续的。通过聚簇索引扫描表行是顺序IO.

缓冲区

内存缓存区,通常非常大,可以存储成千上万的页。MySQL缓冲区的目的是将常用的数据缓存起来避免频繁的磁盘IO带来的性能损耗。每一个DBMS会根据对象类型(表和索引)及页的情况拥有多个缓冲区。

磁盘IO

可以分为顺序IO和随机IO

顺序IO: 指读写操作的访问地址连续。在顺序IO访问中,HDD所需的磁道搜索时间显着减少,因为读/写磁头可以以最小的移动访问下一个块。数据备份和日志记录等业务是顺序IO业务。
随机IO:指读写操作时间连续,但访问地址不连续,随机分布在磁盘的地址空间中。
mysql在处理IO的过程中通常都会伴随着预读取,局部预读原理告诉我们,当计算机访问一个地址的数据时候,与他相邻的地址的数据也有较大几率访问到所以一次io会把相邻页的数据也加载到缓存区当中去。

随机IO耗时估算

对一页或者多个连续页一次数据读取我们认为是一次IO. 一次随机IO的耗时大概是10ms。
每次读取数据的时间大致可分为

  1. 排队等待时间:可能发生的排队时间
  2. 寻道时间: 是指磁盘 磁臂震动到指定磁道所需要的时间,一般在5ms内
  3. 半圈旋转:找到指定磁道后还需要旋转到达目标页数据。
  4. 数据传输耗时: ,将数据从磁盘传输到数据库缓冲区的时间,耗时相对较小 一般在1ms内。

其中寻道时间和旋转时间称为服务时间。同数据库缓冲区一样,磁盘也有缓冲区,若数据存在于磁盘缓冲区,寻道时间和旋转时间均可省略,IO时间将会降低在1ms左右。

顺序IO耗时估算

以下都是顺序IO

  1. 全表扫描:一般是按顺序读取数据页
  2. 全索引扫描: 按顺序扫描存储索引数据的页。但是索引页存储的数据地址指针,指向的页可能不连续,索引后对应的数据扫描是随机IO
  3. 索引片扫描:同2
  4. 通过聚簇索引扫描表行: 聚簇索引后直接指向数据,且聚簇索引的增长一般是连续的,聚簇索引所指向的地址页也是连续的,是顺序扫描。

一般DBMS会知道哪些索引和表页需要被顺序的读取,且能识别出不在缓冲区的页,然后发出多页的一次IO请求。对于平均4K的表页来说在40MB/s的读取速度下,顺序IO的耗时可能为0.1ms.
且通常伴随着预读,在需要所需数据前将一部分数据读取到缓冲区当中去。

增加索引的代价

响应耗时分析

前提:
假设在一个索引上添加一行需要耗时10ms当前情况不考虑异步写 那么索引的新增需要找到对应的索引页的插入位置,对于非聚簇索引这个位置通常不是最后一个索引页末尾,寻找对于的索引页是一个随机IO过程,可以认为是估算值10ms
问题:

  1. 在一个事务中向一张有10条索引的表中插入1行数据。
  2. 在一个事务中向一张有10条索引的表中插入20行数据。

分析以上情况下随机IO次数:

  1. 10条索引包含9非聚簇索引和1聚簇索引。需要10次随机读。顺序读的第一次也是随机读,需要寻道时间 旋转才能在后续开启顺序读。
  2. 9个非聚簇索引需要9*20=180次随机读。聚簇第一次随机后续都是顺序读。以供需要181次随机读。

磁盘负载分析

被修改的叶子页最终都会落到磁盘上去,由于数据库的写是异步的,所以写不会影响事务时间,但是写会增加磁盘的负载,如果一张表的插入较高的话,磁盘负载可能会变成限制索引数量的主要问题。

磁盘空间限制

如果一个表中有千万行以上的数据,索引磁盘空间的成本可能会成为一个限制因素,每一次数据的写入都需要增加对应索引的空间。

分区和分表的差异

在MySQL innodb中 表存储主要依赖2个文件 .frm和.idb文件

  • frm文件主要定义表结构信息
  • ibd 文件主要用来存储表数据
    分区表 主要是 一个frm文件和多个idb文件
    分表 是多个frm文件和多个idb文件。
    分区较轻 如果数据库功能只涉及部分表 或功能的改善,优先选用分区「因为轻量 且可以解决数据量过大问题」。但是分表后 实际是多个表 可以突破单表限制,比如单表事务限制,锁的阻塞问题。
posted @ 2020-11-21 18:54  刘三茶  阅读(164)  评论(0编辑  收藏  举报