1. mybatisplus和mysql的区别
【头一个是啥。。直接说没用过吧】
2. Innodb索引,说原理,如何创建索引
【todo放link】见其他文章
3. ACID特性
4. sql注入原理,防止sql注入
【todo】
5. 删除表中所有的数据保留表结构
6. mysql联合索引能否命中
【todo】
7. 索引是什么,索引底层
- 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
在MySQL中,存储引擎现在索引中查找对应的值,然后根据匹配的索引记录找到对应的数据行,最后将数据结果集返回给客户端。- 优点:
- 在查询过程中提高系统的性能
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
- 在使用分组和排序子句进行数据检索时,可以减少查询中分组和排序的时间。
- 缺点:
- 创建所有和维护索引要耗费时间,而且随着数据量的增大而增大。
- 索引需要占用物理空间,如果要建立聚类索引,所需要的空间会更大。
- 在对表中的数据进行增删改时需要耗费较多的时间,因为索引也要动态地维护。
- 分类:
- 单例索引(主键索引、唯一索引、普通索引):
一个索引只包含一个列,一个表可以有多个单例索引。- 组合索引:
一个组合索引包含两个或两个以上的列。2.1 单例索引
普通索引
最常见的索引,没有任何限制
唯一索引
与普通索引类似,但是要求所有的列的值都是唯一的,允许有空值
主键索引
要求所有的列的值是唯一的,且不允许有空值
2.2 组合索引
如果建立了组合索引,那么它实际建立了多层单例索引。
在使用查询的时候,遵循最左匹配原则。
- 如果不按索引最左列开始查询则不能使用组合索引。
- 如果查询的某个列有范围查询,则其右边的所有列都无法使用该组合索引。
- 不能跳过某个字段进行查询,这样利用不到组合索引。
【todo, b+树】
8. 事务是什么,事务的特性,具体的事务例子
- 事务就是用户定义的一系列执行SQL语句的操作, 这些操作要么完全地执行,要么完全地都不执行, 它是一个不可分割的工作执行单元。
- 事务的使用场景:
在日常生活中,有时我们需要进行银行转账,这个银行转账操作背后就是需要执行多个SQL语句,假
如这些SQL执行到一半突然停电了,那么就会导致这个功能只完成了一半,这种情况是不允许出现,
要想解决这个问题就需要通过事务来完成。
9. mysql死锁
【todo】
10. 慢查询
- 慢查询,执行很慢的查询。超过 long_query_time 参数设定的时间阈值(默认10s),就被认为是慢的,是需要优化的。慢查询被记录在慢查询日志里。
- 慢查询日志默认是不开启的,也就是说一般人没玩过这功能。如果你需要优化SQL语句,就可以开启这个功能,它可以让你很容易地知道哪些语句是需要优化的
11. mysql连接
【todo】
12. 数据库中的存储过程
【todo】
13. 分布式事务
【todo】
14. 为什么线上常用可重复度隔离级别
【todo】
15. 聚类索引
【todo】
16. 主键和外键
- 主键用来唯一标识一条记录,不能有重复,不允许为空,而外键可以重复,可以为空。
- 如果公共关系字在一个关系中是主键,那么这个公共关键字被称为另一个关系的外键。
- 主键用来保证实例完整性,外键用来建立与其他表的联系,需要保证参照完整性。
- 主键在一个关系里只能有一个,外键可以有多个。
17. 查询语句中:先分组还是先排序,为什么?
先进行分组处理。
- Group By 和 Having, Where ,Order by这些关键字是按照如下顺序进行执行的:Where, Group By, Having, Order by。
- 首先where将最原始记录中不满足条件的记录删除(所以应该在where语句中尽量的将不符合条件的记录筛选掉,这样可以减少分组的次数)
- 然后通过Group By关键字后面指定的分组条件将筛选得到的视图进行分组
- 接着系统根据Having关键字后面指定的筛选条件,将分组视图后不满足条件的记录筛选掉
- 最后按照Order By语句对视图进行排序
18. order by 和group by 是什么,区别是什么,order by 和group by 同时使用的时候是什么顺序,为什么。
不筛选直接先进行排序会增大无谓的资源消耗。
19. 范式
- 符合高一级范式的设计必定符合低一级范式。
- 规范化:一个低一级的关系模式通过模式分解可以转化为若干个高一级范式的关系模式的集合,这个过程叫做规范化。
- 候选键:若关系中的某一属性组的值能唯一标识一个元组,而其子集不能,则称该属性组为候选键。若一个关系中有多个候选键,则选定其中一个为主键。
- 第一范式1NF:
属于第一范式关系的所有属性都不可再分,即数据项不可分。 - 第二范式2NF:
若某关系R属于第一范式,且每一个非主属性完全依赖于任何一个候选键,则关系R属于第二范式 - 第三范式3NF
在第二范式基础上,任何非主属性不依赖于其他非主属性。 - 巴斯-科德范式BCNF
在第三范式基础上,任何非主属性不能对主键子集依赖。
20. 左连接、右连接和内连接的区别
- 左连接返回包括左表中的所有记录和右表中连接字段相等的记录;
- 右连接返回包括右表中的所有记录和左表中连接字段相等的记录;
- 内连接只返回两个表中连接字段相等的行;
- 全外连接返回左右表中所有的记录和左右表中连接字段相等的记录。
21. mysql的范围查找
【todo】
22. innodb和myisam
- InnoDB支持事务,MyISAM不支持。
- InnoDB支持外键,而MyISAM不支持。
- InnoDB是聚类索引,使用B+树作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+树组织的一个索引结构),必须有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。
MyISAM是非聚类索引,也是使用B+树作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。 - InnoDB不保存表的具体行数,执行count(*)时需要进行全表扫描,而MyISAM用一个变量保存了整个表的行数
因为InnoDB的事务特性,在同一时刻表中的行数对于不同的事务而言是不一样的,因此count(*)统计会计算对于当前事务而言可以统计到的行数。 - InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁。
InnoDB的行级锁是实现在索引上的,而不是锁在物理行记录上。 - InnoDB表必须有唯一索引(如主键),用户没有指定的话,会找/生成一个隐藏列Row_id来充当默认主键,而MyISAM可以没有。
23. 数据库sql优化
- 尽可能使用覆盖索引
简单来说就是我们的列数据只需要通过索引就可以获得数据,不需要从数据表中去遍历数据,这种索引就已经覆盖了需要查询的列数据情况称为覆盖索引。
所有通过辅助索引查询数据其实都是先从辅助索引查询到聚集索引的索引key,然后用聚集索引的key从聚集索引里面查找数据,通常也称这个过程为回表,按我们上面理解的覆盖索引,当我们查询的字段已经包含在索引里面时,那么我们就不需要从聚集索引里面去查询数据了,因为你所查询的列本身就是索引的key,那么直接返回当前索引的Key就行了,这就个过程就减少了一次从聚集索引查询表数据的过程,当我们查询的数据越多那么这个效率显而易见会得到巨大的提升,所以这也是覆盖索引的好处。 - 最左匹配原则
最左匹配原则是指,索引在进行模糊匹配时,必须最左边开始匹配
它会直接影响到你的like语句,组合索引是否命中。 - 避免隐式转换
凡是经过了隐式转换的列是无法用到索引的
因为索引的类型和匹配的条件类型不配,所以无法使用条件来与索引进行匹配,必须先把数据查询出来之后,再进行类型转换,才能与条件进行条件匹配。 - 只获取必要的列
禁止使用select * - 控制事务的粒度
控制事务的粒度核心思想就是减少对数据加锁的时间。 这样可以大大提升对数据修改的并发性能,这方面我们我们可以从两个方向来入手从而减少锁的影响。
- 减少锁的范围:
innodb引擎锁的最小粒度为行锁,所以我们在修改数据的时候尽量保证只锁定相关的行,而我们知道只有条件命中了索引才会使用行锁,否则就是使用表锁,那么我们在修改数据的时候就要尽量保证条件是使用的索引字段。 - 减小事务的粒度。
当我们在进行事务操作时,加锁是从语句执行开始,但是语句执行完后并不会马上释放对应的锁,而是等整个事务提交之后才会释放所有的锁。
- 尽量保证join、oder by、group by的字段使用索引
- 如果join 的字段使用了索引,就会使用Index Nested-Loop Join 算法,这种算法是最高效的。
- sort、group by 里都涉及到要对数据排序,如果使用了索引,因为Mysql的索引是B+树天然具备顺序的特性,所以可以避免把数据放到sort buffer排序的过程,提升SQL效率。
- 用小结果集驱动大结果集
在Join中的体现:
Join的过程就是先查询出两个表数据,然后通过一个双层循环来遍历外层表 与内层表匹配的过程,如果关联的表有索引,那么Join的过程就类似于下图,左边的就是驱动表、右边的为被驱动表。
假如左边的表数据为5000条,右边的表数据为10000条,以左表为驱动表的话,那么驱动的扫描次数为5000次,数据匹配次数为5000 x 索引的高度。那么 如果换成右表为驱动表,驱动表被扫描的次数就会变成10000次,而数据匹配次数会变成10000 x 索引高度。
通过上面的逻辑,我们可以在进行SQL优化的时候,在保证业务的情况下尽量使用数据量小的那张表作为驱动表可以减少很多CPU计算次数,提升SQL的性能。
24. 数据库满了如何处理
【todo】
25. 表格非常大的情况下怎么加快搜索
- 分页
- 数据量较小:limit查询
- 数据量达到了万级或百万级:建立主键或者唯一索引
【todo】
26. 数据库里的视图
- 概念:
- 视图是从一个或几个基本表(或视图)导出的表。
- 它与基本表不同,是一个虚表。数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。
- 所以基本表中的数据发生变化,从视图中查询出的数据也就随之改变了。从这个意义上讲,视图就像一个窗口,透过它可以看到数据库中自己感兴趣的数据及其变化。
- 视图只供查询,数据不可更改
- 作用:
- 视图隐藏了底层的表结构,简化了数据访问操作,客户端不再需要知道底层表的结构及其之间的关系。
- 视图提供了一个统一访问数据的接口。(即可以允许用户通过视图访问数据的安全机制,而不授予用户直接访问底层表的权限)
- 从而加强了安全性,使用户只能看到视图所显示的数据。
- 视图还可以被嵌套,一个视图中可以嵌套另一个视图。
27. 索引的优缺点
【见第7题】
28. 如何查看一张表的表结构?有哪些命令可以实现?
【todo】
29. 隔离级别
- 读未提交
允许读取另一个事务尚未提交的数据,可能会造成脏读、不可重复读、幻读 - 读已提交
允许读取并发事务已经提交了的数据,可以阻止脏读,但是不能避免不可重复读和幻读 - 可重复读
在一个事务的操作过程中,不能读取到别的事务对该数据库的修改增删操作,可以阻止脏读和不可重复读,但是不能避免幻读(mysql默认级别) - 串行化
所有的事务依次逐个执行,当表被一个事务操作时,其他事务的操作不可以进行,进入排队状态,等待当前操作事务提交后才能继续执行操作。
在并发状态下,事务会出现一些问题,主要有三种问题:
- 脏读 一个事务能读到另外一个事务没有提交的数据。(举例:A给B转了100块,但是A转完并没有提交该事务,B读到了自己的账户多了100块,此时A发现转账错误之后就回滚了该操作,此时就称为脏读)
- 不可重复读 一个事务的两次查询操作数据不一致,可能是两次查询过程中插入了一个事务更新了原有的数据(举例:两个并发事务A和B,A首先查询自己的账户是100块,B此时提走了A账户的50块,A再次查询发现此时账户只剩下了50块,两次查询操作结果不同)
- 幻读 在一个事务的两次查询中数据不一致,发现了原来没有的数据或者原有的数据不见了
不可重复读与幻读相似,不可重复读侧重于另一个事务对数据库的修改操作,而幻读则侧重于另一个事务对数据库的增加和删除操作
30. B树和B+树
-
B树
- 描述:类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。
- 特点:
- 所有键值分布在整颗树中(索引值和具体data都在每个节点里);
- 任何一个关键字出现且只出现在一个结点中;
- 搜索有可能在非叶子结点结束(最好情况O(1)就能找到数据);
- 在关键字全集内做一次查找,性能逼近二分查找;
-
B+树
- 描述:B树的变体。所有关键字存储在叶子节点出,内部节点(非叶子节点)并不存储真正的 data。为所有叶子结点增加了一个链指针
- 描述:B树的变体。所有关键字存储在叶子节点出,内部节点(非叶子节点)并不存储真正的 data。为所有叶子结点增加了一个链指针
-
区别
- 因为内节点并不存储 data,所以一般B+树的叶节点和内节点大小不同,而B树的每个节点大小一般是相同的,为一页。
- B+树内节点不存储数据,所有 data 存储在叶节点导致查询时间复杂度固定为 log n。而B-树查询时间复杂度不固定,与 key 在树中的位置有关。
- B+树叶节点两两相连可大大增加区间访问性,可使用在范围查询等,而B-树每个节点 key 和 data 在一起,则无法区间查找。
- B+树更适合外部存储。由于内节点无 data 域,每个节点能索引的范围更大更精确。
由于B-树节点内部每个 key 都带着 data 域,而B+树节点只存储 key 的副本,真实的 key 和 data 域都在叶子节点存储。前面说过磁盘是分 block 的,一次磁盘 IO 会读取若干个 block,具体和操作系统有关,那么由于磁盘 IO 数据大小是固定的,在一次 IO 中,单个元素越小,量就越大。这就意味着B+树单次磁盘 IO 的信息量大于B-树,从这点来看B+树相对B-树磁盘 IO 次数少。
31. sql语句顺序
32. 什么是关系数据库
【todo】
33. SQL题:查看表的结构 表的结构
【todo】
34. Mysql主从库之间的数据同步
【todo】
35. 过滤条件是索引的字段,update操作的时候是锁住一整行还是整个表
【todo】