关系型数据库-MySQL-知识图谱
2018-12-21 10:07:48 18 举报
AI智能生成
登录查看完整内容
MySQL知识体系
作者其他创作
大纲/内容
功能应该由程序实现,数据库仅仅负责数据的存储,以达到最低的耦合。
降低对数据库功能的依赖
1、每一列属性都是不可再分的属性值,确保每一列的原子性
2、两列的属性相近或相似或一样,尽量合并属性一样的列,确保不产生冗余数据。
第一范式1NF:每列数据的原子性
1. 需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
2. 一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
第二范式2NF:确保表中的每列都和主键相关
第三范式3NF:确保每列都和主键列直接相关,而不是间接相关
第二范式要把包含多个实体的不同属性分成多张表,而第三范式是分表之后,每张表中都只能含有另一张表的id,不能包含另一张表的其他属性。
三大范式
位图(例如用途、用户中的管理员和vip)
逻辑齿解决稀疏矩阵 行列值
主要是针对第一范式
反范式设计
数据库(关系型)设计原则
系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一磁盘块中的数据会被一次性读取出来,而不是按需读取。
InnoDB 存储引擎使用页作为数据读取单位,页是其磁盘管理的最小单位,默认 page 大小是 16k。
系统的一个磁盘块的存储空间往往没有这么大,因此 InnoDB 每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小 16KB。
背景知识
数据结构图
1. 根据根节点找到磁盘块 1,读入内存。【磁盘 I/O 操作第 1 次】
3. 根据 P2 指针找到磁盘块 3,读入内存。【磁盘 I/O 操作第 2 次】
5. 根据 P2 指针找到磁盘块 8,读入内存。【磁盘 I/O 操作第 3 次】
6. 在磁盘块 8 中的关键字列表中找到关键字 29。
模拟查找关键字 29 的过程:
1、关键字集合分布在整颗树中;
2、任何一个关键字出现且只出现在一个节点中;
3、每个节点存储data和key;
4、搜索有可能在非叶子节点结束;
5、一个节点中的key从左到右非递减排列;
6、所有叶节点具有相同的深度,等于树高h。
每个节点占用一个盘块的磁盘空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。
特性
BTree
InnoDB 存储引擎在设计时是将根节点常驻内存的,力求达到树的深度不超过 3,也就是说 I/O 不需要超过 3 次。
分析B-Tree的查找过程,发现需要3次磁盘 I/O 操作,和3次内存查找操作。由于内存中的关键字是一个有序表结构,可以利用二分法查找提高效率。
在 B-Tree 中,每个节点中有 key,也有 data,而每一个页的存储空间是有限的,如果 data 数据较大时将会导致每个节点(即一个页)能存储的 key 的数量很小,会导致 B-Tree 的深度较大,增大查询时的磁盘 I/O 次数,进而影响查询效率。。
设计初衷
B+Tree的检索过程
数据是存在叶子节点中的;
数据节点之间是有指针指向的。
B+Tree尺度示意
扁平的B+Tree
在B-Tree的基础上有两点变化:
B+Tree(InnoDB举例)
数据页(B-tree Node)
Undo页(Undo Log Page)
系统页(System Page)
事务数据页(Transaction System Page)等。
Page常见页类型
单个Page的大小是16K(编译宏UNIV_PAGE_SIZE控制),每个Page使用一个32位的int值来唯一标识,这也正好对应InnoDB最大64TB的存储容量(16Kib * 2^32 = 64Tib)。
Page是整个InnoDB存储的最基本构件,也是InnoDB磁盘管理的最小单位,与数据库相关的所有内容都存储在这种Page结构里。
Page的头部保存了两个指针,分别指向前一个Page和后一个Page,Page链接起来就是一个双向链表的结构。
头部结构示意图
User Records占据Page的大部分空间,User Records由一条一条的Record组成,每条记录代表索引树上的一个节点(非叶子节点和叶子节点)。
单链表的头尾由固定内容的两条记录来表示,字符串形式的\"Infimum\"代表开头,\"Supremum\"代表结尾。这两个用来代表开头结尾的Record存储在System Records的段里,这个System Records和User Records是两个平行的段。
Page的主体内容中主要关注行数据和索引的存储,都位于Page的User Records部分在一个Page内部
InnoDB存在4种不同的Record,它们分别是1主键索引树非叶节点 2主键索引树叶子节点 3辅助键索引树非叶节点 4辅助键索引树叶子节点。
UserRecord示意图
User Record在Page内以单链表的形式存在,最初数据是按照插入的先后顺序排列的,但是随着新数据的插入和旧数据的删除,数据物理顺序会变得混乱,但他们依然保持着逻辑上的先后顺序。
主体内容
Page的基本结构
https://www.cnblogs.com/shijingxiang/articles/4743324.html
Page结构
底层结构
主键索引
常规索引(非主键)
唯一索引
由多列创建的索引称为符合索引
复合索引
当索引的字符串列很大时,创建的索引也就变得很大,为了减小索引体积,提高索引的扫描速度,就用索引的前部分字串索引,这样索引占用的空间就会大大减少,并且索引的选择性也不会降低很多。而且是对BLOB和TEXT列进行索引,或者非常长的VARCHAR列,就必须使用前缀索引,因为MySQL不允许索引它们的全部长度。
前缀索引
InnoDB引擎对FULLTEXT索引的支持是MySQL5.6新引入的特性,之前只有MyISAM引擎支持FULLTEXT索引。对于FULLTEXT索引的内容可以使用MATCH()…AGAINST语法进行查询。
仅MyISAM引擎支持FULL TEXT索引,可以使用MATCH()...AGAINST语法进行查询
只支持英文。缘由是他从来都使用空格来作为分词的分隔符,而对于中文来讲,显然用空格就不合适,需要针对中文语义进行分词。
MySQL 5.6以前版本
InnoDB支持FULL TEXT索引
MySQL 5.6
MyISAM、InnoDB均支持FULL TEXT索引
支持中文索引
MySQL 5.7以后版本
全文索引
它可以提高查询效率,外键会自动和对应的其他表的主键关联。外键的主要作用是保证记录的一致性和完整性。
不推荐使用外键,在应用层使用外键的思想来保证数据的一致性和完整性。
外键索引
使用覆盖索引扫描的查询可以直接使用节点页中的主键值。(具体参照下图中的索引数据结构)
覆盖索引
常见索引类型(逻辑分类)
叶子节点中存放的是索引和数据记录行
聚簇索引的每一个叶子节点都包含了主键值、事务ID、用于事务和MVCC(多版本控制)的回滚指针以及所有的剩余列。
提高数据访问性能:聚簇索引把索引和数据都保存到同一棵B+树数据结构中,并且同时将索引列与相关数据行保存在一起。这意味着,当你访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。
不同于MyISAM引擎(非聚簇索引),它将索引和数据没有放在一块,放在不同的物理文件中,索引文件是缓存在key_buffer中,索引对应的是磁盘位置,不得不通过磁盘位置访问磁盘数据。
优点
建议在大量插入新行后,选在负载较低的时间段,通过OPTIMIZE TABLE优化表,因为必须被移动的行数据可能造成碎片。使用独享表空间可以弱化碎片
基于聚簇索引的表在插入新行,或者主键被更新,导致需要移动行的时候,可能面临“页分裂(page split)”的问题。页分裂会导致表占用更多的磁盘空间。
建议使用int的auto_increment作为主键
表如果使用UUId作为主键,使数据存储稀疏,这就会出现聚簇索引有可能有比全表扫面更新
如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值;过长的主键值,会导致非叶子节点占用更多的物理空间
缺点
聚簇索引
叶子节点中存放的是索引以及对应的数据记录指针(或主键)
非聚簇索引(辅助索引)
索引类型-叶子节点数据分类
为了定位数据需要做权表扫描,为了提高扫描速度,把索引键值单独放在独立的数据的数据块里,并且每个键值都有个指向原数据块的指针,因为索引比较小,扫描索引的速度就比扫描全表快,这种需要扫描所有键值的方式就称为紧凑索引扫描
紧凑索引扫描(dense index)
为了提高紧凑索引扫描效率,通过把索引排序和查找算法(B+trre),发现只需要和每个数据块的第一行键值匹配,就可以判断下一个数据块的位置或方向,因此有效数据就是每个数据块的第一行数据,如果把每个数据块的第一行数据创建索引,这样在这个新创建的索引上折半查找,数据定位速度将更快。这种索引扫描方式就称为松散索引扫描。
松散索引扫描(sparse index)
包含所有满足查询需要的数据的索引称为覆盖索引,即利用索引返回select列表中的字段,而不必根据索引再次读取数据文件
针对某种sql覆盖掉了某种操作
覆盖索引扫描(covering index)
索引扫描方式
数据结构
聚簇索引中的每个叶子节点包含主键值、事务ID、回滚指针(rollback pointer用于事务和MVCC)和余下的列(如col2)。
1) 有主键时,根据主键创建聚簇索引
2) 没有主键时,会用一个唯一且不为空的索引列做为主键,成为此表的聚簇索引
3) 如果以上两个都不满足那innodb自己创建一个虚拟的聚集索引
InnoDB默认创建聚簇索引
一级索引/主键索引/聚簇索引
InnoDB的二级索引(非聚簇索引)的叶子节点中存储的不是“行指针”,而是主键值。
故通过二级索引查找数据时,会进行两次索引查找。存储引擎需要先查找二级索引的叶子节点来获得对应的主键值,然后根据这个主键值到聚簇索引中查找对应的数据行。
二级索引/非主键索引/非聚簇索引
InnoDB
分支主题
MyISAM的二级索引叶子节点存放的还是列值与行号的组合,叶子节点中保存的是数据的物理地址。
MYISAM的主键索引和二级索引没有任何区别,主键索引仅仅只是一个叫做PRIMARY的唯一、非空的索引,且MYISAM引擎中可以不设主键。
同InnoDB数据结构比较
MYISAM
索引
https://blog.csdn.net/u011277123/article/details/78359016
自增主键有利于缩小二级索引所占空间
合适的主键
个人理解:宽表如果数据分布在多页,需要跨页加载
表宽度适度,避免宽表
避免太多关联
大字段读取会导致:overflow跨页加载
大字段建议分表存储,主键关联
索引列设置为非NULL
对比时需要实现转换为小写进行比较
避免设置大小写不敏感
由于CHAR是固定长度的,所以它的处理速度比VARCHAR快得多,但是其缺点是浪费存储空间,程序需要对行尾空格进行处理,所以对于那些长度变化不大并且对查询速度有较高要求的数据可以考虑使用CHAR类型来存储。
InnoDB存储引擎:建议使用VARCHAR类型。对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
varchar vs. char
表设计
数据库提供的日期函数
字符大小写转换
数字同字符的对比方式不同
数字<->字符串转换、对比
数字<->字符转换、对比
常见运算包括
不要在列上做运算
索引可以按照升序或者降序进行扫描,以满足精确符合列顺序的ORDER BY、GROUP BY和DISTINCT等子句的查询需求。但要注意最左原则(参照字典查询单词的例子)
一个多列B-Tree索引中,索引列的顺序意味着索引首先按照最左列进行排序,其次是第二列...
索引的最左原则
SQL优化
explain
执行计划
最佳实践
character set
collation
字符集
存储过程(stored procedure)
函数(function)
触发器(trigger)
时间调度器(event)
show create …
stored program
视图
partition
audit
高级特性
事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
1、原子性(Atomicity):
事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
2、一致性(Consistency)
同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
3、隔离性(Isolation)
事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
4、持久性(Durability)
事务的基本要素(ACID)
1. 张三的工资为5000,事务A中获取工资为5000;
2. 事务B获取工资为5000,汇入100,并提交数据库,工资变为5100;
3. 事务A发生异常,回滚了,恢复张三的工资为5000;
END: 导致事务B的更新丢失。
第一类丢失更新:在没有事务隔离的情况下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 导致对数据的两个修改都失效了。
1. 事务A中,读取到张三的存款为5000,操作没有完成,事务还没提交。
2. 事务B,存储1000,把张三的存款改为6000,并提交了事务。
3. 在事务A中,存储500,把张三的存款改为5500,并提交了事务。
END:事务A的更新覆盖了事务B的更新。
第二类丢失更新:不可重复读的特例。有两个并发事务同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就会造成第一次写操作失效。
更新丢失:当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题
1. 张三的工资为5000;事务A中把他的工资改为8000,但事务A尚未提交。
2. 事务B正在读取张三的工资,读取到张三的工资为8000。
3. 事务A发生异常,而回滚了事务。张三的工资又回滚为5000。
END: 事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。
脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
1. 事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。
2. 事务B把张三的工资改为8000,并提交了事务。
3. 事务A中,再次读取张三的工资,此时工资变为8000。
END:在一个事务中前后两次读取的结果并不致,导致了不可重复读。
不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。
1. 目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。
2. 事务B插入一条工资也为5000的记录。
END:事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。
不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
幻读:当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后第一个事务的用户再次读取时会发现表中还有没有修改的数据行,就好象发生了幻觉一样。
事务的并发问题
mysql中默认事务隔离级别是可重复读时并不会锁住读取到的行
事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。
写数据会锁住相应行
解决第一类丢失更新的问题,但仍存在脏读、不可重复读、第二类丢失更新的问题、幻读 。
读未提交
保证一个事务修改的数据提交后才能被另外一个事务读取,即另外一个事务不能读取该事务未提交的数据。
解决第一类丢失更新和脏读的问题,但会出现不可重复读、第二类丢失更新的问题、幻读问题
不可重复读
保证一个事务相同条件下前后两次获取的数据是一致的
解决第一类丢失更新,脏读、不可重复读、第二类丢失更新的问题,但会出幻读
事务隔离级别为可重复读时,如果有索引(包括主键索引)的时候,以索引列为条件更新数据,会存在间隙锁间隙锁、行锁、下一键锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表。
可重复读
读写数据都会锁住整张表
事务被处理为顺序执行。
串行化
事务隔离级别
6字节的DATA_TRX_ID 标记了最新更新这条行记录的transaction id,每处理一个事务,其值自动+1
DATA_TRX_ID
7字节的DATA_ROLL_PTR 指向当前记录项的rollback segment的undo log记录,找之前版本的数据就是通过这个指针
DATA_ROLL_PTR
6字节的DB_ROW_ID,当由innodb自动产生聚集索引时,聚集索引包括这个DB_ROW_ID的值,否则聚集索引中不包括这个值,这个用于索引当中
DB_ROW_ID
DELETE BIT位用于标识该记录是否被删除,这里的不是真正的删除数据,而是标志出来的删除。真正意义的删除是在commit的时候
DELETE BIT
innodb存储的最基本row中包含一些额外的存储信息
begin->用排他锁锁定该行->记录redo log->记录undo log->修改当前行的值,写事务编号,回滚指针指向undo log中的修改前的行
UPDATE的事务过程
undo log分insert和update undo log,因为insert时,原始的数据并不存在,所以回滚时把insert undo log丢弃即可,而update undo log则必须遵守上述过程
insert的事务过程
具体的执行过程
insert操作时 “创建时间”=DB_ROW_ID,这时,“删除时间 ”是未定义的;
update时,复制新增行的“创建时间”=DB_ROW_ID,删除时间未定义,旧数据行“创建时间”不变,删除时间=该事务的DB_ROW_ID;
delete操作,相应数据行的“创建时间”不变,删除时间=该事务的DB_ROW_ID;
select操作对两者都不修改,只读相应的数据
依照事务的版本来检查每行的版本号
1.InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务 读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行
2.行的删除操作的版本一定是未定义的或者大于当前事务的版本号。确定了当前事务开始之前,行没有被删除
Innodb检查每行数据,确保他们符合两个标准:
符合了以上两点则返回查询结果。
SELECT
InnoDB为每个新增行记录当前系统版本号作为创建ID。
INSERT
InnoDB为每个删除行的记录当前系统版本号作为行的删除ID。
DELETE
InnoDB复制了一行。这个新行的版本号使用了系统版本号。它也把系统版本号作为了删除行的版本。
UPDATE
REPEATABLE READ 可重复读下的MVCC
每行数据都存在一个版本,每次数据更新时都更新该版本
修改时Copy出当前版本随意修改,各个事务之间无干扰
保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)
就是每行都有版本号,保存时根据版本号决定是否成功,有点类似乐观锁
如果Transaciton1执行理想的MVCC,修改Row1成功,而修改Row2失败,此时需要回滚Row1,但因为Row1没有被锁定,其数据可能又被Transaction2所修改,如果此时回滚Row1的内容,则会破坏Transaction2的修改结果,导致Transaction2违反ACID。
修改两行数据,但为了保证其一致性,与修改两个分布式系统中的数据并无区别,而二提交是目前这种场景保证一致性的唯一手段。
理想的MVCC是难以实现的,当事务仅修改一行记录使用理想的MVCC模式是没有问题的,可以通过比较版本号进行回滚;但当事务影响到多行数据时,理想的MVCC据无能为力了。
理想的MVCC特点
事务以排他锁的形式修改原始数据
把修改前的数据存放于undo log,通过回滚指针与主数据关联
修改成功(commit)啥都不做,失败则恢复undo log中的数据(rollback)
同一般理解的MVCC特点的差别:当修改数据时是否要排他锁定
Innodb的实现方式
InnoDB每个事务在开始的时候,会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),然后一致性读去比较记录的tx id的时候,并不是根据当前事务的tx id,而是根据read view最早一个事务的tx id(read view->up_limit_id)来做比较的,这样就能确保在事务B之前没有提交的所有事务的变更,B事务都是看不到的。
这里还有个小问题要处理一下,就是当前事务自身的变更还是需要看到的。
如果根据事务DB_TRX_ID去比较获取事务的话,按道理在一个事务B(在事务A后,但A还没commit)select的话 B.DB_TRX_ID>A.DB_TRX_ID则应该能返回A事务对数据的操作以及修改。那不是和前面矛盾?其实不然。
MVCC深入
InnoDB实现MVCC
多版本并发控制(MVCC)
即多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
共享锁(S)读锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
排他锁(X)写锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。
锁关系
InnoDB使用共享锁,可以提高读读并发
为了保证数据强一致,InnoDB使用强互斥锁,保证同一行记录修改与删除的串行性;
目的
共享锁/排它锁
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
意向锁
select * from t where id =1 for update
比如where条件出的记录
封锁指定的索引记录
记录锁(Record Locks)
select * from t where id between 8 and 15 for update
当用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓 的间隙锁(Next-Key锁)。
InnoDB除了通过范围条件加锁时使用间隙锁外,如果使用相等条件请求给一个不存在的记录加锁,InnoDB也会使用间隙锁!
为了防止幻读,以满足相关隔离级别的要求,对于上面的例子,要是不使用间隙锁,如果其他事务插入了empid大于100的任何记录,那么本事务如果再次执行上述语句,就会发生幻读;
为了防止其他事务在间隔中插入数据,以导致“不可重复读”。
间隙锁(Gap Locks)
记录锁与间隙锁的组合
封锁范围既包含索引记录又包含索引区间
概念
临键锁会封锁索引记录本身,以及索引记录之前的区间。
如果一个会话占有了索引记录R的共享/排他锁,其他会话不能立刻在R之前的区间插入新的索引记录。
引申
临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。
临键锁(Next-key Locks)
是间隙锁(Gap Locks)的一种(所以,也是实施在索引上的),它是专门针对insert操作的。
多个事务,在同一个索引,同一个范围区间插入记录时,如果插入的位置不冲突,不会阻塞彼此。
用法
InnoDB使用插入意向锁,可以提高插入并发
插入意向锁(Insert Intention Locks)
https://blog.csdn.net/wufaliang003/article/details/81937410
自增锁是一种特殊的表级别锁(table-level lock),专门针对事务插入AUTO_INCREMENT类型的列。
自增锁(Auto-inc Locks)
对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X)
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE。
对于普通SELECT语句,InnoDB不会加任何锁,事务可以通过以下语句显示给记录集加共享锁或排他锁。
SQL语句加锁
因此只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。
当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。
InnoDB行锁是通过给索引上的索引项加锁来实现的
行锁的实现方式
https://www.cnblogs.com/aipiaoborensheng/p/5767459.html
相关文章
InnoDB引擎的锁机制
事务
主从复制流程图
主从复制
https://www.cnblogs.com/zhoubaojian/articles/7866212.html
复制
IO模型
IO
1. Connectors指的是不同语言中与SQL的交互。
2. Management Serveices & Utilities: 系统管理和控制工具。
3. Connection Pool: 连接池。管理缓冲用户连接,线程处理等需要缓存的需求。
4. SQL Interface: SQL接口。接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface。
将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。
如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的。
5. Parser:解析器。SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的,是一个很长的脚本。
这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤。这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤,将这两个查询条件联接起来生成最终查询结果。
6. Optimizer: 查询优化器。
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等。
7. Cache和Buffer: 查询缓存。
存储引擎是MySql中具体的与文件打交道的子系统。
8. Engine :存储引擎。
MySQL体系结构
内存结构示意
global_buffers ( 全局内存分配总和 )
all_thread_buffers (会话/线程级内存分配总和)
https://www.cnblogs.com/zhoubaojian/articles/7866292.html
mysql 内存结构
体系结构
MySQL
收藏
0 条评论
回复 删除
下一页