作者:empty 出版社:empty |
前言
今互联网行业用的最多就是MySQL, 然而对于高级Web面试者, 尤其对于寻找30k下工作的求职者, 很多MySQL相关知识点基本都会涉及, 并且由于是讲解面试题, 可能会比较由浅入深,问答互动的方式,穿插讲解知识点。所以我尽量详细透彻讲解涉及的知识点,希望对大家有点帮助哈。废话不多说,开启问答面试之旅。1、MySQL相关存储引擎因为目前大多互联网公司, 用的最多的存储引擎就是myisam和innodb。大多问MySQL有哪些存储引擎啊?都有什么区别?请详细说明一下,基本都是想面试者回答关于myisam和innodb引擎, l11)、面试题分析ritCh atmysql支持的存储引擎有很多种, innodb、myisam、memory等, 但是面试官可能想问就2种, 其实经常用的就一种, innodb, myisam以前可能还有一些场景会用, 现在用的已经非常少了, 尤其在oltp业务中, 一旦涉及事务、高并发等场景。1.1.1) 、myisammyisam:不支持事务, 不支持外键约束, 索引文件和数据文件分开, 这样在内存里可以缓存更多的索引,对查询的性能会更好,适用于那种少量的插入,大量查询的场景。最经典的就是报表系统, 比如大数据的报表系统, 常见的就是走had oop生态来搞, hdfs来存储数据, 然后基于hive来进行数仓建模, 每次hive跑出来的数据都用sq oop从hive中导出到mysql中去。然后基于mysql的在线查询, 就接上php写个简单的web系统,每个报表开发一套代码,写5ql查数据,组织数据,按照前端要求的格式返回数据,展现出来一个报表,这种报表系统, 是最适合mysql的myisam存储引擎的, 不需要事务, 就是一次性批量导入,接下来一天之内就是纯查询了,1.1.2) 、innodb现在一般用mysql都是innodb, 很少用其他的存储引擎, 而且国内用其他存储引擎的场景和公司也不多, 所以用innodb就可以了, 而且这个也是mysql 5.5之后的默认官方存储引擎.主要特点就是支持事务,走聚簇索引,强制有主键,支持外键约束,并且高并发、大数据量、高可用等有相关成熟的数据库架构,分库分表、读写分离、主备切换,全部都可以基于innodb存储引擎的, 稍微要求高点的面试官, 可能会问你innodb存储引擎怎么玩支撑大数据量和高并发,如何用读写分离支撑高可用和高可用读,如何分摊db压力,支撑更高OPS, 基本就是涉及更深入的innodb原理的东西, 可以建议看下一本书:innodb技术内幕。1.2)、总结基本关于mysql存储引擎, 可能开始面试官只是想问myisam和innodb简单的事务、数据存储原理等区别, 再深入问可能就想知道innodb在高并发、大数据量、高可用架构下的优势。关于本题,只是大致的抛砖引玉,要是去讲解高并发、大数据量等,那涉及的知识太多了哈.2、My SL索引实现原理ChatMy SQ索引的原理和数据结构能介绍一下吗、MySQL聚簇索引和非聚簇索引的区别是什么、他们分别是如何存储的?使用MySQL索引都有哪些原则、MySQL复合索引如何使用。基本会涉及这些知识点,稍微好点公司的面试官哈.2.1)、索引存储结构其实大多面试官问你mysql的索引底层是什么数据结构实现的, 可能还会现场让你优化sql, 为什么如此优化呢; 还可能问你数据库常见的使用规则呢。mysql的索引就是用一个数据结构组织某一列的数据, 然后如果你要根据那一列的数据查询的时候,就可以不用全表扫描,只要根据那个特定的数据结构去找到那一列的值,然后找到对应的行的物理地址即可。mysql的索引实现是基于B+树, 这样查找数据的高度就算数据量很大, 也很低, 关于B+树原理和实现,可以参考任何一本数据结构的书籍了解下哈。myisam存储引擎的索引中, 每个叶子节点的data存放的是数据行的物理地址, 比如0x07之类的东西,一行一行的,每行对应一个物理地址。
innodb存储引擎的索引实现, 跟myisam最大的区别在于, innodb的数据文件本身就是个索引文件, 就是key就是主键, 然后叶子节点的data就是那个数据行。innodb存储引擎, 必须有主键, 可以默认内置的就会根据主键(6字节的rowid) 建立一个索引, 叫做聚簇索引, innodb的数据文件本身同时也是个索引文件, 这个索引就是默认根据主键建立的叫做聚簇索引.innodb这种原生的数据文件就是索引文件的组织结构, 就叫默认的主键索引为聚簇索引。就是因为这个原因, innodb表是要求必须有主键的, 但是myisam表不要求必须有主键。另外一个是, innodb存储引擎下, 如果对某个非主键的字段创建个索引, 那么最后那个叶子节点的值就是主键的值,因为可以用主键的值到聚簇索引里根据主键值再次查找到数据。一般innodb表里, 建议统一用auto_increment自增值作为主键值, 因为这样可以保持聚簇索引直接加记录就可以,如果用那种不是单调递增的主键值,可能会导致b+树分裂后重新组织, 会浪费时间。这也就是为啥innodb下不要用UUID生成的超长字符串作为主键?因为这么玩儿会导致所有的索引的data都是那个主键值, 最终导致索引会变得过大,浪费很多磁盘空间.
一般myisam会加表锁, 就是myisam引擎下, 执行查询的时候, 会默认加个表共享锁,也就是表读锁, 这个时候别人只能来查, 不能写数据的; 然后myisam写的时候, 也会加个表独占锁,也就是表写锁,别人不能读也不能写。1这个myisam因为很少用了, 面试的时候大致说下就可以啦。其实很多人也发现了,myisam其实在实际生产中, 也就新闻资讯、报表系统等, 也就是纯粹读写比, 读超级多的系统在用了, 压根不涉及事务, 可以简单理解为olap业务.innodb的行锁有共享锁(S) 和排他锁(X) , 两种, 其实说白了呢, 共享锁就是, 多个事务都可以加共享锁读同一行数据,但是别的事务不能写这行数据;排他锁,就是就一个事务可以写这行数据,别的事务只能读,不能写,innodb的表锁, 分成意向共享锁, 就是说加共享行锁的时候, 必须先加这个共享表锁;还有一个意向排他锁,就是说,给某行加排他锁的时候,必须先给表加排他锁,这个表锁, 是innodb引擎自动加的, 不用你自己去加。insert、update、delete, innodb会自动给那一行加行级排他锁,select, innodb啥锁都不加, 因为innodb默认实现了可重复读, 也就是mvcc机制, 所以多个事务随便读一个数据,一般不会有冲突,大家就读自己那个快照就可以了,不涉及到什么锁的问题。