做电影网站的工具,遵义网页制作招聘,外贸网站建设 惠州,美工做图片网站系列文章目录
2024年java面试#xff08;一#xff09;–spring篇2024年java面试#xff08;二#xff09;–spring篇2024年java面试#xff08;三#xff09;–spring篇2024年java面试#xff08;四#xff09;–spring篇2024年java面试–集合篇2024年java面试–redi…系列文章目录
2024年java面试一–spring篇2024年java面试二–spring篇2024年java面试三–spring篇2024年java面试四–spring篇2024年java面试–集合篇2024年java面试–redis(1)2024年java面试–redis(2) 文章目录 系列文章目录MVCC聚簇索引和非聚簇索引 聚集索引和二级索引哈希索引为什么用B树索引而不用哈希索引为什么InnoDB推荐用整型自增主键而不是uuid索引失效场景有哪些事务4大特性事务隔离级别默认隔离级别-RRRR和RC使用场景并发事务带来哪些问题应该如何解决InnoDB 如何开启手动提交事务 MVCC
全称Multi-Version Concurrency Control多版本并发控制。指维护一个数据的多个版本使得读写操作没有冲突快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。
三个隐式字段 undo log日志
回滚日志在insert、update、delete的时候产生的便于数据回滚的日志。
当insert的时候产生的undo log日志只在回滚时需要在事务提交后可被立即删除。
而update、delete的时候产生的undo log日志不仅在回滚时需要在快照读时也需要不会立即被删除。 readView
ReadView读视图是快照读SQL执行时MVCC提取数据的依据记录并维护系统当前活跃的事务未提交的id。
ReadView中包含了四个核心字段 不同的隔离级别生成ReadView的时机不同:
READ COMMITTED:在事务中每一次执行快照读时生成Readview。
REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView后续复用该ReadView
聚簇索引和非聚簇索引 聚集索引和二级索引
聚簇索引 将数据存储与索引放到了一块索引结构的叶子节点保存了行数据主键索引
非聚簇索引 将数据与索引分开存储索引结构的叶子节点指向了数据对应的位置辅助索引
聚簇索引的叶子节点就是数据节点而非聚簇索引的叶子节点仍然是索引节点只不过有指向对应数据块的指针。
聚集索引选取规则
如果存在主键主键索引就是聚集索引。如果不存在主键将使用第一个唯一UNIQUE索引作为聚集索引。如果表没有主键或没有合适的唯一索引则InnoDB会自动生成一个rowid作为隐藏的聚集索引。
哈希索引
哈希索引用索引列的值计算该值的hashCode然后在hashCode相应的位置存执该值所在行数据的物理位置因为使用散列算法因此访问速度非常快但是一个值只能对应一个hashCode而且是散列的分布方式因此哈希索引不支持范围查找和排序的功能
为什么用B树索引而不用哈希索引
哈希索引建立的是索引值的哈希值和物理磁盘地址之间的映射
1哈希冲突多的时候性能也不一定就比B树好
2哈希索引不支持范围查询只能点对点查询哈希运算前的索引值和哈希运算后的哈希值顺序并不一定一样
3哈希索引不能利用部分索引键查询哈希索引在计算哈希值的时候是组合索引键合并后再一起计算哈希值而不是单独计算哈希值所以通过组合索引的前面一个或几个索引键进行查询的时候哈希索引也无法被利用
为什么InnoDB推荐用整型自增主键而不是uuid
1uuid占用空间更多。uuid是随机字符串占用空间更多整型更少。
2uuid排序不如整型容易。uuid是字符串而节点中的索引值需要排序显然整型排序更容易。
3整型自增插入时可避免节点频繁分裂。插入数据时自增主键对B树结构影响很小由于是递增往后加就行而uuid是随机的可能插到中间如果前面节点已经满了会导致节点分裂页分裂、树结构调整等大量耗费性能的操作。
索引失效场景有哪些
1当联合索引不满足最左匹配原则相当于创建多列索引没有最左优先那么联合查询也就失效如果使用了或者右边的索引将会失效改成或者就正常
2在查询时使用错误的模糊查询如果仅仅是尾部模糊匹配索引不会失效。如果是头部模糊匹配索引失效。
3当列使用运算操作和函数时索引就失效了
4列使用了类型转换也会导致索引失效例如字符串类型不加引号进行查询
5使用了is not null那么索引就会失效不固定取决于当前数据库表中的数据分布如果表中都有数据或者极少数没有数据使用is null走索引 使用is not null不走索引因为根据表中数据的量来决定如果量多就走全局扫描
6or连接如果or前的条件中的列有索引而后面的列中没有索引那么涉及的索引都不会被用到。
事务4大特性
事务4大特性 原子性、一致性、隔离性、持久性
原⼦性 事务是最⼩的执⾏单位不允许分割。事务的原⼦性确保动作要么全部完成要么全不执行
一致性 执⾏事务前后数据保持⼀致多个事务对同⼀个数据读取的结果是相同的
隔离性 并发访问数据库时⼀个⽤户的事务不被其他事务所⼲扰各并发事务之间数据库是独⽴的
持久性 ⼀个事务被提交之后。它对数据库中数据的改变是持久的即使数据库发⽣故障也不应该对其有任何影响。
事务靠什么保证 原子性由undolog日志保证他记录了需要回滚的日志信息回滚时撤销已执行的sql 一致性由其他三大特性共同保证是事务的目的 隔离性由MVCC保证 持久性由redolog日志和内存保证mysql修改数据时内存和redolog会记录操作宕机时可恢复
事务隔离级别
读未提交 最低的隔离级别允许读取尚未提交的数据变更可能会导致脏读、幻读或不可重复读。
读已提交 允许读取并发事务已经提交的数据可以阻⽌脏读但是幻读或不可重复读仍有可能发⽣。
可重复读 同⼀字段的多次读取结果都是⼀致的除⾮数据是被本身事务⾃⼰所修改可以阻⽌脏读和不可重复读会有幻读。
串行化 最⾼的隔离级别完全服从ACID的隔离级别。所有的事务依次逐个执⾏这样事务之间就完全不可能产⽣⼲扰。
隔离级别并发问题读未提交可能会导致脏读、幻读或不可重复读读已提交可能会导致幻读或不可重复读可重复读可能会导致幻读可串行化不会产⽣⼲扰
隔离级别脏读不可重复读幻读读取未提交√√√读取已提交×√√可重复读××√可串行化×××
1、脏读脏读就是指当一个事务正在访问数据并且对数据进行了修改而这种修改还没有提交到数据库中这时另外一个事务也访问这个数据然后使用了这个数据。
例如 张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。 与此同时 事务B正在读取张三的工资读取到张三的工资为8000。 随后 事务A发生异常而回滚了事务。张三的工资又回滚为5000。 最后 事务B读取到的张三工资为8000的数据即为脏数据事务B做了一次脏读。
2、不可重复读是指在一个事务内多次读同一数据。在这个事务还没有结束时另外一个事务也访问该同一数据。那么在第一个事务中的两次读数据之间由于第二个事务的修改那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的因此称为是不可重复读。
例如 在事务A中读取到张三的工资为5000操作没有完成事务还没提交。 与此同时 事务B把张三的工资改为8000并提交了事务。 随后 在事务A中再次读取张三的工资此时工资变为8000。在一个事务中前后两次读取的结果并不致导致了不可重复读。
3、幻读是指当事务不是独立执行时发生的一种现象例如第一个事务对一个表中的数据进行了修改这种修改涉及到表中的全部数据行。同时第二个事务也修改这个表中的数据这种修改是向表中插入一行新数据。那么以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行就好象发生了幻觉一样。
例如 两个cmd窗口开启事务 在第一个窗口中进行查询id3没有数据此时在第二个窗口进行插入id3在第一个窗口中也进行插入id3的操作显示已经存在但是再查询id3也还是没有数据
默认隔离级别-RR
默认隔离级别 可重复读
同⼀字段的多次读取结果都是⼀致的除⾮数据是被本身事务⾃⼰所修改
可重复读是有可能出现幻读的如果要保证绝对的安全只能把隔离级别设置成SERIALIZABLE这样所有事务都只能顺序执行自然不会因为并发有什么影响了但是性能会下降许多。
第二种方式使用MVCC解决快照读幻读问题如简单select读取的不是最新的数据。维护一个字段作为version这样可以控制到每次只能有一个人更新一个版本。
select id from table_xx where id ? and version V
update id from table_xx where id ? and version V1第三种方式如果需要读最新的数据可以通过GapLockNext-KeyLock可以解决当前读幻读问题
select id from table_xx where id 100 for update;
select id from table_xx where id 100 lock in share mode;RR和RC使用场景
事务隔离级别RC(read commit)和RRrepeatable read两种事务隔离级别基于多版本并发控制MVCC(multi-version concurrency control来实现。
RCRR实现多条查询语句会创建多个不同的ReadView仅需要一个版本的ReadView粒度语句级读一致性事务级读一致性准确性每次语句执行时间点的数据第一条语句执行时间点的数据
并发事务带来哪些问题
脏读 当一个事务正在访问数据并且对数据进行了修改而这种修改还没提交到数据库中这时另外一个事务也访问了这个数据然后使用了这个数据。因为这个数据是没有被提交的那么事务读到的这个数据是“脏数据”
丢失修改 一个事务修改一个数据的时另外一个事务也读取到这个数据当第一个事务对他进行修改后第二个事务也进行了修改这样第一个事务的修改结果就丢失了因此被称为丢失修改
不可重复读: 指一个事务内多次读同一个事务在这个事务还没有结束的时候另外一个事务也访问该数据。那么第一事务的两次读取数据之间由于第二个事务的修改导致一个事务内两次读到的数据是不太一样的情况因此称为不可重复读。
幻读: 幻读与不可重复读类似。它发生在一个事务T1读取了几行数据接着另一个并发事务T2插入了一些数据时。在随后的查询中第一个事务T1就会发现多了一些原本不存在的记录就好像发生了幻卷一样所以称为幻读。
应该如何解决
并发事务可能造成脏读、不可重复读和幻读等问题 这些问题其实都是数据库读一致性问题必须由数据库提供一定的事务隔离机制来解决解决方案如下
加锁在读取数据前对其加锁阻止其他事务对数据进行修改。例如读的时候加共享锁此时其他事物无法修改相应的数据写的时候加排他锁禁止其他事物读写操作但是这种做法性能较差。基于性能考虑MySQL提供了数据多版本并发控制(MVCC)也称为多版本数据库不用加任何锁 通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot) 并用这个快照来提供一定级别 (语句级或事务级) 的一致性读取从用户的角度来看好象是数据库可以提供同一数据的多个版本。
不可重复读和幻读的区别
不可重复读的重点是修改比如多次读取一条记录发现其中某列的值被修改幻读的重点在于新增或者删除比如多次读取一条记录发现记录增多或减少了。
InnoDB 如何开启手动提交事务
InnoDB 默认是自动提交事务的每一次 SQL 操作(非 select 操作)都会自动提交一个事务如果要手动开启事务需要设置set autocommit0禁止自动提交事务相当于开启手动提交事务。
在 InnoDB 中设置了 autocommit0添加一条信息之后没有手动执行提交操作请问这条信息可以被查到吗
autocommit0 表示禁止自动事务提交在添加操作之后没有进行手动提交默认情况下其他连接客户端是查询不到此条新增数据的。