摘要: 无论在平时开发中还是面试中咱们都会遇到一些MySQL的问题, 最近也在梳理一些MySQL的一些问题和整顿了一些学习思维导图,心愿对你有帮忙, 也欢送大家一起交换。 本文首发于公众号: 散步coding

MySQL学习思维导图

该图以 Markdown 绘制思维导图的开源工具——markmap(https://markmap.js.org/repl)主动渲染进去的, 如果须要Markdown原稿(看的更加清晰), 关注公众号, 回复mysql 即可取得。

面试中MySQL一些常见的问题

1、CHAR、VARCHAR的区别是什么?

VARCHAR类型用于存储可变长度字符串,是最常见的字符串数据类型。它比固定长度类型更节俭空间,因为它仅应用必要的空间(依据理论字符串的长度扭转存储空间)。

VARCHAR节俭了存储空间,所以对性能也有帮忙。然而,因为行是变长的,在UPDATE时可能使行变得比原来更长,这就导致须要做额定的工作。如果一个行占用的空间增长,并且在页内没有更多的空间能够存储,在这种状况下,不同的存储引擎的解决形式是不一样的。例如,MylSAM会将行拆成不同的片段存储,InnoDB则须要决裂页来使行能够放进页内。

CHAR类型用于存储固定长度字符串:MySQL总是依据定义的字符串长度调配足够的空间。当存储CHAR值时,MySQL会删除字符串中的开端空格(在MySQL 4.1和更老版本中VARCHAR 也是这样实现的——也就是说这些版本中CHAR和VARCHAR在逻辑上是一样的,区别只是在存储格局上)。

同时,CHAR值会依据须要采纳空格进行残余空间填充,以不便比拟和检索。但正因为其长度固定,所以会占据多余的空间,也是一种空间换工夫的策略。

CHAR适宜存储很短或长度近似的字符串。例如,CHAR非常适合存储明码的MD5值,因为这是一个定长的值。对于常常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生碎片。对于十分短的列,CHAR比VARCHAR在存储空间上也更有效率。例如用CHAR(1)来存储只有Y和N的值,如果采纳单字节字符集只须要一个字节,然而VARCHAR(1)却须要两个字节,因为还有一个记录长度的额定字节。
  

2、TRUNCATE和DELETE的区别是什么?

DELETE命令从一个表中删除某一行,或多行,TRUNCATE命令永恒地从表中删除每一行。

3、什么是触发器,MySQL中都有哪些触发器?

触发器是指一段代码,当触发某个事件时,主动执行这些代码。在MySQL数据库中有如下六种触发器:1.Before Insert2.After Insert3.Before Update4.After Update5.Before Delete6.After Delete

4、FLOAT和DOUBLE的区别是什么?

  • FLOAT类型数据能够存储至少8位十进制数,并在内存中占4字节。
  • DOUBLE类型数据能够存储至少18位十进制数,并在内存中占8字节。

5、如何在MySQL种获取以后日期?

SELECT CURRENT_DATE()

6、如何查问第N高的分数?

这里有几个留神点:

  • 因为问题可能有一样的值,所以应用DISTINCT进行去重
  • 如果不存在第N高问题的分数,那么查问应返回 null
  • 把下方的N换成具体的数值查问
select ifNull(    (select distinct `score`        from students         order by score Desc        limit N-1,1),null) as target_score

7、请阐明InnoDB和MyISAM的区别

这个在面试过程中过的比拟多。

  • InnoDB反对事务,MyISAM不反对;
  • InnoDB数据存储在共享表空间,MyISAM数据存储在文件中;
  • InnoDB反对行级锁,MyISAM只反对表锁;
  • InnoDB反对解体后的复原,MyISAM不反对;
  • InnoDB反对外键,MyISAM不反对;
  • InnoDB不反对全文索引,MyISAM反对全文索引;

8、innodb引擎的个性

  • 1、插入缓冲(insert buffer)
  • 2、二次写(double write)
  • 3、自适应哈希索引(ahi)4、预读(read ahead)

9、请阐明varchar和text的区别

  • varchar可指定字符数,text不能指定,外部存储varchar是存入的理论字符数+1个字节(n<=255)或2个字节(n>255),text是理论字符数+2个字节。
  • text类型不能有默认值。
  • varchar可间接创立索引,text创立索引要指定前多少个字符。
  • varchar查问速度快于text,在都创立索引的状况下,text的索引简直不起作用。
  • 查问text须要创立长期表。

10、简略形容MySQL中,索引,主键,惟一索引,联结索引的区别,对数据库的性能有什么影响?

这个在面试过程中过的比拟多。

  • 一个表只能有一个主键索引,然而能够有多个惟一索引。
  • 主键索引肯定是惟一索引,惟一索引不是主键索引。
  • 主键能够与外键形成参照完整性束缚,避免数据不统一。
  • 联结索引:将多个列组合在一起创立索引,能够笼罩多个列。(也叫复合索引,组合索引)
  • 外键索引:只有InnoDB类型的表才能够应用外键索引,保证数据的一致性、完整性、和实现级联操作(根本不必)。
  • 全文索引:MySQL自带的全文索引只能用于MyISAM,并且只能对英文进行全文检索 (根本不必)

11、创立MySQL联结索引应该留神什么?

需遵循前缀准则

12、列值为NULL时,查问是否会用到索引?

在MySQL里NULL值的列也是走索引的。当然,如果打算对列进行索引,就要尽量避免把它设置为可空,MySQL难以优化援用了可空列的查问,它会使索引、索引统计和值更加简单。

13:以下语句是否会利用索引:SELECT FROM users WHERE YEAR(adddate) < 2019

不会,因为只有列波及到运算,MySQL就不会应用索引。

14、MyISAM索引实现?

MyISAM存储引擎应用B+Tree作为索引构造,叶节点的data域寄存的是数据记录的地址。MyISAM的索引形式也叫做非聚簇索引的,之所以这么称说是为了与InnoDB的聚簇索引辨别。

15、MyISAM索引与InnoDB索引的区别?

  • InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
  • InnoDB的主键索引的叶子节点存储着行数据,因而主键索引十分高效。
  • MyISAM索引的叶子节点存储的是行数据地址,须要再寻址一次能力失去数据。
  • InnoDB非主键索引的叶子节点存储的是主键和其余带索引的列数据,因而查问时做到笼罩索引会十分高效。

16、MySQL的关联查问语句你会那些?

六种关联查问

  • 1.穿插连贯(CROSS JOIN)
  • 2.内连贯(INNER JOIN)
  • 3.外连贯(LEFT JOIN/RIGHT JOIN)
  • 4.联结查问(UNION与UNION ALL)
  • 5.全连贯(FULL JOIN)
  • 6.穿插连贯(CROSS JOIN)

平时用到比拟多的是内连和外连, 以及联结查问

a)、内连贯分为三类:

等值连贯:ON A.id=B.id
不等值连贯:ON A.id > B.id
自连贯:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid

b)、外连贯 分为: 左外连贯、右外连贯

左外连贯:LEFT OUTER JOIN, 以左表为主,先查问出左表,依照ON后的关联条件匹配右表,没有匹配到的用NULL填充,能够简写成LEFT JOIN

右外连贯:RIGHT OUTER JOIN, 以右表为主,先查问出右表,依照ON后的关联条件匹配左表,没有匹配到的用NULL填充,能够简写成RIGHT JOIN

c)、联结查问(UNION与UNION ALL)

就是把多个后果集集中在一起,UNION前的后果为基准,须要留神的是联结查问的列数要相等,雷同的记录行会合并
如果应用UNION ALL,不会合并反复的记录行3.效率 UNION 高于 UNION ALL

d)、全连贯(FULL JOIN)

1.MySQL不反对全连贯
2.能够应用LEFT JOIN 和UNION和RIGHT JOIN联结应用

17、UNION与UNION ALL的区别?

如果应用UNION ALL,不会合并反复的记录行
效率 UNION 高于 UNION ALL

18、如何优化慢SQL

应用explain剖析单条SQL语句

优化查问过程中的数据拜访

  • 拜访数据太多导致查问性能降落
  • 确定应用程序是否在检索大量超过须要的数据,可能是太多行或列
  • 确认MySQL服务器是否在剖析大量不必要的数据行
  • 防止犯如下SQL语句谬误
  • 查问不须要的数据。解决办法:应用limit解决多表
  • 关联返回全部列。解决办法:指定列名
  • 总是返回全部列。解决办法:防止应用SELECT *反复
  • 查问雷同的数据。解决办法:能够缓存数据,下次间接读取缓存

是否在扫描额定的记录。解决办法:应用explain进行剖析,如果发现查问须要扫描大量的数据,但只返回多数的行,能够通过如下技巧去优化:

应用索引笼罩扫描,把所有的列都放到索引中,这样存储引擎不须要回表获取对应行就能够返回后果。
扭转数据库和表的构造,批改数据表范式
重写SQL语句,让优化器能够以更优的形式执行查问。

19、优化长难的查问语句

一个简单查问还是多个简略查问
MySQL外部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢得多应用尽可能小的查问是好的,然而有时将一个大的查问合成为多个小的查问是很有必要的。
切分查问: 将一个大的查问分为多个小的雷同的查问
一次性删除1000万的数据要比一次删除1万,暂停一会的计划更加损耗服务器开销。
合成关联查问,让缓存的效率更高。
执行单个查问能够缩小锁的竞争。
在应用层做关联更容易对数据库进行拆分。
查问效率会有大幅晋升。
较少冗余记录的查问。

20、优化特定类型的查问语句

count(*)会疏忽所有的列,间接统计所有列数,不要应用count(列名)
MyISAM中,没有任何where条件的count(*)十分快。
当有where条件时,MyISAM的count统计不肯定比其它引擎快。
能够应用explain查问近似值,用近似值代替count(*)
减少汇总表
应用缓存

21、优化关联查问

确定ON或者USING子句中是否有索引。
确保GROUP BY和ORDER BY只有一个表中的列,这样MySQL才有可能应用索引。

22、优化子查问

用关联查问代替
优化GROUP BY和DISTINCT
这两种查问据能够应用索引来优化,是最无效的优化办法
关联查问中,应用标识列分组的效率更高
如果不须要ORDER BY,进行GROUP BY时加ORDER BY NULL,MySQL不会再进行文件排序。
WITH ROLLUP超级聚合,能够挪到利用程序处理

23、优化LIMIT分页

LIMIT偏移量大的时候,查问效率较低

能够记录上次查问的最大ID,下次查问时间接依据该ID来查问

24、优化UNION查问

UNION ALL的效率高于UNION

25、优化WHERE子句

解题办法对于此类考题,先阐明如何定位低效SQL语句,而后依据SQL语句可能低效的起因做排查,先从索引着手,如果索引没有问题,思考以上几个方面,数据拜访的问题,长难查问句的问题还是一些特定类型优化的问题,逐个答复。

26、乐观锁和乐观锁

这个问题个别在面试中都会问到

乐观锁

总是假如最坏的状况,每次取数据时都认为其余线程会批改,所以都会加(乐观)锁。一旦加锁,不同线程同时执行时,只能有一个线程执行,其余的线程在入口处期待,直到锁被开释。

乐观锁

顾名思义就是在操作时很乐观,认为操作不会产生并发问题(不会有其余线程对数据进行批改),因而不会上锁。然而在更新时会判断其余线程在这之前有没有对数据进行批改,个别会应用版本号机制或CAS(compare and swap)算法实现。

小结

后续, 还会持续更新MySQL相干的内容, 如果对您有帮忙,能够珍藏本文或者关注我的公众号: 散步coding, 一起交换,一起学习。