MySQL

记得背这个!!
https://blog.csdn.net/weixin_45325628/article/details/122930369?spm=1001.2014.3001.5506

数据库的三范式

1、第⼀范式:强调的是列的原⼦性,即数据库表的每⼀列都是不可分割的原⼦数据项。
2、第⼆范式:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字⼀部分的属性。
3、第三范式:任何⾮主属性不依赖于其它⾮主属性。

⼀张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启mysql 数据库,又插⼊了⼀条数据,此时 id 是⼏?

表类型如果是 MyISAM ,那 id 就是 8。
表类型如果是 InnoDB,那 id 就是 6。

InnoDB 表只会把⾃增主键的最⼤ id 记录在内存中,所以重启之后会导致最⼤ id 丢失。

如何获取当前数据库版本?

使⽤ select version() 获取当前 mysql 数据库版本。

说⼀下 ACID 是什么?

1、Atomicity(原⼦性):⼀个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执⾏过程中发⽣错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执⾏过⼀样。即,事务不可分割、不可约简。

2、Consistency(⼀致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写⼊的资料必须完全符合所有的预设约束、触发器、级联回滚等。

3、Isolation(隔离性):数据库允许多个并发事务同时对其数据进⾏读写和修改的能⼒,隔离性可以防⽌多个事务并发执⾏时由于交叉执⾏⽽导致数据的不⼀致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串⾏化
(Serializable)。
4、Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

Mysql存在的并发事务问题

1、读-读:不存在任何问题,也不需要并发控制。
2.、读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、不可重复读、幻读。
3. 写-写:有线程安全问题,可能会存在更新丢失问题。

说⼀下数据库的事务隔离?

mysql 的事务隔离是在 mysql.ini 配置⽂件⾥添加的,在⽂件的最后添加:
transaction-isolation = REPEATABLE-READ
可⽤的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。

READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻
读、脏读、不可重复读)。

READ-COMMITTED:提交读,⼀个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)。

REPEATABLE-READ:可重复读,默认级别,保证多次读取同⼀个数据时,其值都和事务开始时候的内容是⼀致,禁⽌读取到别的事务未提交的数据(会造成幻读)。(mysql默认可重复读,因为主从复制存在大量不一致)

SERIALIZABLE:序列化,代价最⾼最可靠的隔离级别,该隔离级别能防⽌脏读、不可重复读、幻读。

脏读 :表示⼀个事务能够读取另⼀个事务中还未提交的数据。⽐如,某个事务尝试插⼊记录 A,此时该事务还未提交,然后另⼀个事务尝试读取到了记录 A。

不可重复读 :一个事物先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。

幻读 :一个事物按照条件查询数据时,没有对应的数据行,但是在插入数据时又发现这行数据已经存在,好像出现了“幻影”。

char 和 varchar 的区别是什么?

1、 char的长度是不可变的,用空格填充到指定长度大小,而varchar的长度是可变的。
char优点:效率⾼;缺点:占⽤空间;适⽤场景:存储密码的 md5 值,固定⻓度的,使⽤ char ⾮常合适。
2、 char的存储方式是:对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节。
3、varchar的存储方式是:对每个英文字符占用2个字节,汉字也占用2个字节,存储的值是每个值占⽤的字节再加上⼀个⽤来记录其⻓度的字节的⻓度。
4、char的存取速度比varchar要快得多,所以,从空间上考虑 varcahr ⽐较合适;从效率上考虑 char ⽐较合适,⼆者使⽤需要权衡。

float 和 double 的区别是什么?

float 最多可以存储 8 位的⼗进制数,并在内存中占 4 字节。
double 最可可以存储 16 位的⼗进制数,并在内存中占 8 字节。

Mysql 如何实现多表查询

MYSQL多表查询主要使用连接查询 , 连接查询的方式主要有 :

-内连接

  • 隐式内连接 : Select 字段 From 表A , 表B where 连接条件
  • 显式内连接 : Select 字段 From 表A inner join 表B on 连接条件

外连接

  • 左外连接 : Select 字段 From 表A left join 表B on 连接条件
  • 右外连接 : Select 字段 From 表A right join 表B on 连接条件
  • 全外连接:(很少用)

MYSQL内连接和外连接的区别 ?

1、 内连接:只有两个元素表相匹配的才能在结果集中显示。

2、 外连接:
左外连接: 左边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。
右外连接:右边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。

3、 全外连接:连接的表中不匹配的数据全部会显示出来。

4、交叉连接:笛卡尔效应,显示的结果是链接表数的乘积。

mysql 索引是怎么实现的?

索引是满⾜某种特定查找算法的数据结构,⽽这些数据结构会以某种⽅式指向数据,从⽽实现⾼效查找数据。具体来说 mysql 中的索引,不同的数据引擎实现有所不同,但⽬前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达⼆分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。

索引的底层数据结构

索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引。
1、MyISAM和InnoDB存储引擎:只⽀持B+ TREE索引, 也就是说默认使用BTREE,不能够更换。
2、MEMORY/HEAP存储引擎:支持HASH和BTREE索引

索引的结构有哪些?

索引是在存储引擎城实现了不同的存储引擎有不同的结构,主要包括:
1、B+Tree索引:是最常见的索引类型,大部分引擎都支持B+树索引。
2、Hash索引:底层数据结构适用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询。
3、R-Tree(空间索引):是Myisam引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少。
4、Full-Text(全文索引):是一种通过建立倒排索引快速匹配文档的方式。
在这里插入图片描述

B-Tree是什么?

也称多路平衡查找树。
在这里插入图片描述### B+Tree是什么?
在这里插入图片描述
(1)有n棵子树的节点含有n个关键字,每个关键字都不会保存数据,只会用来索引,并且数据都会保存在叶子节点中。
(2)所有的叶子节点包含所有关键字信息以及指向关键字记录的指针,关键字从小到大顺序连接。

Mysql索引数据结构对经典的B+Tree进行了优化,在原有B+Tree的基础上增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。
在这里插入图片描述

Hash索引是什么?

Hash索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
如果两个或多个键值映射到一个相同的槽位上,他们就产生了hash冲突,也称为hash碰撞,可以通过链表来解决。
在这里插入图片描述特点
1、hash索引只能用于对等比较(=、in),不支持范围查询(between,<,>…)。
2、无法利用索引完成排序操作,因为它的索引结果是无序的。
3、查询效率高,通常只需要一次检索就可以了(不发生hash碰撞的情况下),效率通常要高于B+Tree索引。

索引的分类

在这里插入图片描述主要有 : 单列索引 , 组合索引空间索引 , 用的比较多的就是单列索引和组合索引 。

1、单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 :

  • 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。

  • 唯一索引:索引列中的值必须是唯一的,但是允许为空值。

  • 主键索引:是一种特殊的唯一索引,不允许有空值。

  • 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。

2、组合索引 : 在MYSQL数据库表的多个字段组合上创建的索引 , 称为组合索引也叫联合索引,组合索引的使用,需要遵循左前缀原则
一般情况下,建议使用组合索引代替单列索引(主键索引除外)

什么是最左前缀原则?

索引可以简单如一个列(a),也可以复杂如多个列(a, b, c, d),即联合索引。
如果是联合索引,那么key也由多个列组成,同时,索引只能用于查找key是否存在(相等),遇到范围查询(>、<、between、like左匹配)等就不能进一步匹配了,后续退化为线性查找。因此,列的排列顺序决定了可命中索引的列数。
例子:
如有索引(a, b, c, d),查询条件a = 1 and b = 2 and c > 3 and d = 4,则会在每个节点依次命中a、b、c,无法命中d。(很简单:索引命中只能是相等的情况,不能是范围匹配)

InnoDB有什么索引?

在这里插入图片描述

什么是聚簇索引和非聚簇索引?

聚簇索引

在使用InnoDB存储引擎的时候, 主键索引B+树叶子节点会存储数据行记录,简单来说数据和索引在一起存储 , 这就是聚簇索引。

非聚簇索引

在使用MyISAM存储引擎的时候, B+树叶子节点只会存储数据行的指针,简单来说数据和索引不在一起 , 这就是非聚簇索引。
在这里插入图片描述在这里插入图片描述

索引的优缺点

优点:
1、因为数据库的数据是存放在磁盘中的,如果要对磁盘进行操作的话,会涉及到IO,通过索引可以提高数据检索的效率,降低数据库的IO成本。
2、通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。

缺点:
1、 创建和维护索引组要耗费时间,并且随着数据量的增加所耗费的时间也会增加,降低更新表的速度。
2、索引需要占磁盘空间,除了数据表占数据空间以外,每一个索引还要占一定的物理空间。如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
3、当对表中的数据进行增加、删除和修改的时候,索引也要动态维护,这样就降低了数据的维护速度。

怎么验证 mysql 的索引是否满足需求?

使⽤ explain 查看 sql 是如何执⾏查询语句的,从⽽分析你的索引是否满⾜需求。
explain 语法:explain select * from table where type=1。

说⼀下 mysql 常用的存储引擎?

存储引擎就是存储数据,建立索引/更新/查询数据等技术的实现方式,它是基于表的,不是基于库的,所以存储引擎也可被称为表类型。

1、InnoDB 引擎:mysql 5.5 之后默认引擎,提供了对数据库 acid 事务的⽀持,并且还提供了⾏级锁和外键的约束,它的设计的⽬标就是处理⼤数据容量的数据库系统。mysql 运⾏的时候,InnoDB 会在内存中建⽴缓冲池,⽤于缓冲数据和索引。但是该引擎是不⽀持全⽂搜索,同时启动也⽐较的慢,它是不会保存表的⾏数的,所以当进⾏ select count(*) from table 指令的时候,需要进⾏扫描全表。由于锁的粒度⼩,写操作是不会锁定全表的,所以在并发度较⾼的场景下使⽤会提升效率的。

InnoDB 支持数据恢复,InnoDB引擎会记录日志,通过redolog重做日志操作可以恢复数据。并且支持并发控制,如果需要对事物的完整性要求比较高,要求实现并发控制,那么选择InnoDB存储引擎。如果需要频繁的进行更新删除操作的数据库也可以选择InnoDB存储引擎,因为该类存储引擎可以实现事务的提交和回滚。

2、MyIASM 引擎:不提供事务的⽀持,也不⽀持⾏级锁和外键。因此当执⾏插⼊和更新语句时,即执⾏写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的⾏数,于是当进⾏ select count(*) from table 语句时,可以直接的读取已经保存的值⽽不需要进⾏扫描全表。MyISAM不支持数据恢复。
它管理非事务表,提供高速存储和检索以及全文搜索能力,MyIsam存储引擎插入数据快,空间和内存使用比较低,如果表主要是用于插入新记录和读书记录,那么选择它能实现处理的高效率。
MyISAM支持256TB的数据存储 , InnerDB只支持64TB的数据存储。
MyISAM不支持MVCC,InnoDB支持MVCC。

所以,如果表的读操作远远多于写操作时,并且不需要事务的⽀持的,可以将MyIASM 作为数据库引擎的⾸选。

3、MEMORY存储引擎:它是一类特殊的存储引擎,使用存储在内存中的内容来创建表,并且数据也放在内存中,每个基于memory存储引擎的表实际对应一个磁盘文件,该文件的文件名和表明相同类型为frm,这个文件只存储表的结构,但是数据文件都是存储在内存中的,有利于数据的快速处理。并且它对表的大小有要求,无法建立太大的表,它默认使用哈希索引速度比b数索引快,同时它很少用到,是因为它的存储周期较短,因为所有数据是存储在内存中的,如果内存出现异常,就会影响数据的完整性,如果重启机器或者关机,表中的所有数据都会消失,基本是一次性的。如果目标数据只是临时需要在其生命周期中必须立即可用,或者是存储在表中的数据,如果突然丢失不对对应用服务产生实际的负面影响,也不会对数据完整性有长期影响的话,就可以考虑使用。

硬盘存储结构

1、MyISAM:3个文件(表定义文件、索引文件、数据文件)
2、 InnoDB:2个文件
(1) Frm文件:表定义文件
(2) Idb文件:数据和索引存储的文件

索引结构不同

1、MyISAM(非聚集索引):B+树的叶子节点存放的是物理地址,指向数据文件的数据。
2、InnoDB(聚集索引)
聚集索引:B+树的叶子节点直接存放真实数据的
辅助索引:B+树叶子节点存放的是主键Id值

mysql 的行锁和表锁

MyISAM 只⽀持表锁,InnoDB ⽀持表锁和⾏锁,默认为⾏锁。
1、表级锁:开销⼩,加锁快,不会出现死锁。锁定粒度⼤,发⽣锁冲突的概率最⾼,并发量最低。
2、⾏级锁:开销⼤,加锁慢,会出现死锁。锁⼒度⼩,发⽣锁冲突的概率⼩,并发度最⾼。

##慢查询日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time,默认十秒)的所有sql语句的日志,他默认没有开启,需要在配置文件中进行配置开启(slow_query_time=1)。

什么是MVCC(多版本并发控制)

关键字:快照读、事务的隔离性(ACID)、trx_id、roll_pointer、undolog、版本链、readView、判断逻辑、判断顺序

MVCC其实就是一个多版本并发控制,即多个不同版本的数据实现并发控制的技术,其基本思想是为每次事务生成一个新版本的数据,在读数据时选择不同版本的数据即可以实现对事务结果的完整性读取。

当前读和快照读

1、当前读(行锁 + 间隙锁)

就是读取当前数据的最新记录,会加锁,为了保证其他事务不能修改记录(如select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁))

当前读由行锁+间隙锁实现

2、 快照读(mvcc + undolog)

不加锁的select操作就是快照读(隔离级别不能是串行化,如果是串行化快照读就变成了当前读)

快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本。

MVCC的组成要素

1、 每条记录有三个隐藏列
(1)事务ID(trx_id):记录创建这条记录/最后一次修改该记录的事务ID。
(2) 回滚指针(roll_pointer):指向undolog日志的上一个版本。
(3) 隐藏主键(row_id):隐含的自增ID。

2、 undolog日志

每次update操作都会生成一条undo_log日志,分为insert undo log和update undo log
(1)分类
insert undo_log(insert操作,给自己事务看的):如insert操作,只针对当前事务,在insert操作后产生undo_log记录,在事务提交后删除undo_log记录,说白了就是给当前事务自己看的。
update undo_log(update、delete操作):update 和 delete操作,会根据隔离级别不同事务版本的数据可见性不同

注意:update操作生成undolog日志,
select操作生成readView读视图对象!
两个生成时机要区分开。

3、版本链
通过回滚指针将undolog日志连接起来,形成的就叫做版本链。

readView(读视图)

1.、组成
(1) m_ids(存活的事务id列表):表示生成readView时,当前系统中活跃的读写事务的事务id列表。

白话文:存活、活跃,指的就是未commit

(2)min_trx_id(m_ids中的最小事务id):表示生成readView时,当前系统中活跃的读写事务中最小的事务id。

(3)max_trx_id(新的事务id值):表示生readView时,系统中应该分配给下一个事务的id值
(4) creator_trx_id(生成这个readView的事务id):表示生成这个readView的事务id。

2、作用:
让我知道 我在这个版本链中选择哪一条undolog记录。

3、readView是如何判断版本链中的那个版本可用的
每一个undolog有自己的事务id,叫做trx_id。

4、什么时候生成Read-View?
要看数据库的隔离级别:

可重复读:返回的是第一次查询生成的【read-view】
读已提交每次select时都会重新生成一个新的【read-view】

MVCC实现原理

查询的时候会读取出【read-view】,并根据read-view从undo_log日志中最新的记录依次往下找
https://www.cnblogs.com/boluopabo/p/13111961.html

MVCC主要有什么作用

1. 非阻塞的并发读写

提高并发读写性能,操作时会生成事务id,能够更好地解决读-写冲突,不加锁、非阻塞的并发读

2. 实现读已提交和可重复读

MVCC只能实现读已提交和可重复读;如果是读未提交,那么每次查询都能获取最新的修改值。

(1)问:MVCC如何实现RC(以select为单位的)?

读已提交生成readView是以select为单位的,每次select时都会重新生成一个新的【read-view】,然后去【undo】日志中寻找符合结果的一条数据。

(2)问:MVCC如何实现RR(以事务为单位的)?

可重复读生成readView是以事务为单位的,第一次查询的时候生成一个新的【read-view】,后面的查询会继续沿用第一次的【read-view】,然后找出一个可读的数据。

说⼀下乐观锁和悲观锁?

乐观锁:每次去拿数据的时候都认为别⼈不会修改,所以不会上锁,但是在提交更新的时候会判断⼀
下在此期间别⼈有没有去更新这个数据。
悲观锁:每次去拿数据的时候都认为别⼈会修改,所以每次在拿数据的时候都会上锁,这样别⼈想拿
这个数据就会阻⽌,直到这个锁被释放。
数据库的乐观锁需要⾃⼰实现,在表⾥⾯添加⼀个 version 字段,每次修改成功值加 1,这样每次修改的时候先对⽐⼀下,⾃⼰拥有的 version 和数据库现在的 version 是否⼀致,如果不⼀致就不修改,这样就实现了乐观锁。

mysql 问题排查都有哪些⼿段?

1、使⽤ show processlist 命令查看当前所有连接信息。
2、使⽤ explain 命令查询 sql 语句执⾏计划。
3、开启慢查询⽇志,查看慢查询的 sql。

如何做 mysql 的性能优化?

1、为搜索字段创建索引。
2、避免使⽤ select *,列出需要查询的字段。
3、垂直分割分表。
4、选择正确的存储引擎。

三大日志(undo log、redo log、bin log)

在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值