本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1. 关系型数据库和非关系型数据库的区别
什么是关系型数据库?
关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。
优点
(1)易于维护:都是使用表结构,格式一致; (2)使用方便:SQL语言通用,可用于复杂查询; (3)复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
缺点
(1)读写性能比较差,尤其是海量数据的高效率读写; (2)固定的表结构,灵活度稍差; (3)高并发读写需求,对传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
什么是非关系型数据库?
简称NoSQL,是基于键值对的对应关系,并且不需要经过SQL层的解析,所以性能非常高。但是不适合用在多表联合查询和一些较复杂的查询中。NoSQL用于超大规模数据的存储。
优点
(1)格式灵活,存储数据的格式可以是键值对形式,文档形式、图片形式等等,文档形式、图片形式等等、使用灵活、应用场景广泛,而关系型数据库只支持基础类型。 (2)速度快,NoSQL可以使用硬盘或者随机存储器作为载体,而非关系型数据库只能使用硬盘。 (3)高拓展性。 (4)成本低,NoSQL数据库部署简单,基本都是开源软件。
缺点
(1)不提供SQL支持,学习和使用成本较高; (2)无事务处理; (3)数据结构相对复杂,复杂查询方面稍逊。
2. 详细说一下一条MySQL语句执行的步骤
Server层按顺序执行SQL的步骤为: (1)客户端请求->连接器(验证用户身份,给予权限) (2)查询缓存(存在缓存则直接返回,不存在则执行后续操作) (3)分析器(对SQL进行词法分析和语法分析操作) (4)优化器(主要对执行的SQL优化选择最优的执行方案) (5)执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)->去引擎层获取数据返回(如果开启查询缓存会缓存查询结果)
3. MySQL使用索引的原因
根本原因
索引的出现,就是为了提高数据查询的效率,类似书的目录(对于数据库的表来说,索引就是它的目录)。
扩展
(1)创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 (2)帮助引擎层避免排序和临时表。 (3)将随机IO变成顺序IO,加速了表和表之间的连接。
4. 索引的三种常见底层数据结构以及优缺点
三种常见的索引底层数据结构:分别是哈希表、有序数组和搜索树。 (1)哈希表适用于等值查询的场景,比如说memcached以及其他一些NoSQL引擎,不适合范围查询。
(2)有序数组索引只适用于静态存储引擎,等值和范围查询性能好,但更新数据成本高。
(3)N叉树由于读写上的性能优势以及适配磁盘访问模式被广泛应用于数据库引擎中。
扩展:以InnoDB的一个整数字段索引为例,这个N差不多是1200。棵树高是4的时候,就可以存1200的三次方个值,这已经是17亿了。考虑到树根的数据块总是在内存中,一个十亿行的表上一个整数字段的索引,查找一个值最多需要访问三次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。
5. 索引的常见类型以及它如何发挥作用
根据叶子结点的内容,索引类型分为主键索引和非主键索引。 (1)主键索引的叶子结点存的整行数据,在InnoDB里也被成为聚簇索引。
(2)非主键索引叶子结点存的主键的值,在InnoDB里也被称为二级索引。
6. MyISAM和InnoDB实现B+树索引方式的区别是什么?
InnoDB存储引擎:B+树索引的叶子结点保存数据本身,其数据文件本身就是索引文件。
MyISAM存储引擎:B+树索引的叶子结点保存数据的物理地址,叶子结点的data域存放的是数据记录的地址,索引文件和数据文件是分离的。
7. InnoDB为什么设计B+树索引?
两个考虑因素: (1)InnoDB需要执行的场景和功能需要在特定查询上拥有较强的性能。 (2)CPU将磁盘上的数据加载到内存中需要花费大量时间。
为什么选择B+树: (1)哈希索引虽然能提供O(1)的时间复杂度查询,但对范围查询和排序却不能很好地支持,最终会导致全表扫描。
(2)B树能够在非叶子结点存储数据,但会导致在查询连续数据上带来更多的随机IO。
(3)B+树的所有叶子节点可以通过指针来相互连接,减少顺序遍历带来的随机IO。
普通索引还是唯一索引? 由于唯一索引用不上change buffer的优化机制,因此如果业务可以接受,从性能角度出发,建议你优先考虑非唯一索引。
8. 什么是覆盖索引和索引下推?
覆盖索引
在某个查询里面,索引k已经“覆盖了”我们的查询需求,成为覆盖索引。
覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
索引下推
MySQL5.6引入的索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
9. 哪些操作会导致索引失效?
(1)对索引使用左匹配或者左右模糊匹配,也就是like %xx 或者 like %xx% 这两种方式都会造成索引失效。原因在于查询的结果可能是多个,不知道从哪个索引值开始比较,于是就只能通过全表扫描的方式来查询。
(2)对索引进行函数/对索引进行表达式计算,因为索引保持的是索引字段的原始值,而不是经过函数计算得知,自然没办法走索引。
(3)对索引进行隐式转换相当于使用了新函数。
(4)WHERE子句中的OR语句,只要有条件列不是索引列,就会进行全表扫描。
10. 字符串怎么加索引?
(1)直接创建完整索引,这样可能会比较占用空间。
(2)创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引。
(3)倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题。
(4)创建 hash 字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。