【22】C++岗位求职面试八股文第二十二篇(数据库)
系列文章目录
第一篇:语言基础
第二篇:设计模式
第三篇:数据库
第四篇:计算机网络
第五篇:操作系统
第六篇:LInux
第七篇:数据结构
第八篇:智力题
[101]数据库优化的理解
MySQL数据库优化是多方面的,原则是减少系统的瓶颈,减少资源的占用,增加系统的反应速度。例如,通过优化文件系统,提高磁盘I\O的读写速度;通过优化操作系统调度策略,提高MySQL在高负荷情况下的负载能力;优化表结构、索引、查询语句等使查询响应更快。
针对查询,我们可以通过使用索引、使用连接代替子查询的方式来提高查询速度。针对慢查询,我们可以通过分析慢查询日志,来发现引起慢查询的原因,从而有针对性的进行优化。针对插入,我们可以通过禁用索引、禁用检查等方式来提高插入速度,在插入之后再启用索引和检查。针对数据库结构,我们可以通过将字段很多的表拆分成多张表、增加中间表、增加冗余字段等方式进行优化。
[102]如何优化MySQL的查询?
1.使用索引:如果查询时没有使用索引,查询语句将扫描表中的所有记录。在数据量大的情况下,这样查询的速度会很慢。如果使用索引进行查询,查询语句可以根据索引快速定位到待查询记录,从而减少查询的记录数,达到提高查询速度的目的。索引可以提高查询的速度,但并不是使用带有索引的字段查询时索引都会起作用。有几种特殊情况,在这些情况下有可能使用带有索引的字段查询时索引并没有起作用。使用LIKE关键字的查询语句在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置,索引才会起作用。使用多列索引的查询语句MySQL可以为多个字段创建索引。一个索引可以包括16个字段。对于多列索引,只有查询条件中使用了这些字段中的第1个字段时索引才会被使用。使用OR关键字的查询语句查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,查询中才使用索引。否则,查询将不使用索引。
2优化子查询:使用子查询可以进行SELECT语句的嵌套查询,即一个SELECT查询的结果作为另一个SELECT语句的条件。子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作。子查询虽然可以使查询语句很灵活,但执行效率不高。执行子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引,性能会更好。
[103]怎样插入数据才能更高效?
影响插入速度的主要是索引、唯一性校验、一次插入记录条数等。针对这些情况,可以分别进行优化。对于MyISAM引擎的表,常见的优化方法如下:
- 禁用索引 对于非空表,插入记录时,MySQL会根据表的索引对插入的记录建立索引。如果插入大量数据,建立索引会降低插入记录的速度。为了解决这种情况,可以在插入记录之前禁用索引,数据插入完毕后再开启索引。对于空表批量导入数据,则不需要进行此操作,因为MyISAM引擎的表是在导入数据之后才建立索引的。
- 禁用唯一性检查 插入数据时,MySQL会对插入的记录进行唯一性校验。这种唯一性校验也会降低插入记录的速度。为了降低这种情况对查询速度的影响,可以在插入记录之前禁用唯一性检查,等到记录插入完毕后再开启。
- 使用批量插入 插入多条记录时,可以使用一条INSERT语句插入一条记录,也可以使用一条INSERT语句插入多条记录。使用一条INSERT语句插入多条记录的情形如下,而这种方式的插入速度更快。 INSERT INTO fruits VALUES ('x1', '101', 'mongo2', '5.7'), ('x2', '101', 'mongo3', '5.7'), ('x3', '101', 'mongo4', '5.7');
- 使用LOAD DATA INFILE批量导入 当需要批量导入数据时,如果能用LOAD DATA INFILE语句,就尽量使用。因为LOAD DATA INFILE语句导入数据的速度比INSERT语句快。
对于InnoDB引擎的表,常见的优化方法如下:
- 禁用唯一性检查 插入数据之前执行set unique_checks=0来禁止对唯一索引的检查,数据导入完成之后再运行set unique_checks=1。这个和MyISAM引擎的使用方法一样。
- 禁用外键检查 插入数据之前执行禁止对外键的检查,数据插入完成之后再恢复对外键的检查。
- 禁用自动提交 插入数据之前禁止事务的自动提交,数据导入完成之后,执行恢复自动提交操作。
- 使用批量插入
[104]表中包含几千万条数据该怎么办?
建议按照如下顺序进行优化:
- 优化SQL和索引;
- 增加缓存,如memcached、redis;
- 读写分离,可以采用主从复制,也可以采用主主复制;
- 使用MySQL自带的分区表,这对应用是透明的,无需改代码,但SQL语句是要针对分区表做优化的;
- 做垂直拆分,即根据模块的耦合度,将一个大的系统分为多个小的系统;
- 做水平拆分,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表。
[105] MySQL的慢查询优化有了解吗?
优化MySQL的慢查询,可以按照如下步骤进行:
(1)开启慢查询日志:MySQL中慢查询日志默认是关闭的,可以通过配置文件my.ini或者my.cnf中的log-slow-queries选项打开,也可以在MySQL服务启动的时候使用--log-slow-queries[=file_name]启动慢查询日志。
(2)启动慢查询日志时,需要在my.ini或者my.cnf文件中配置long_query_time选项指定记录阈值,如果某条查询语句的查询时间超过了这个值,这个查询过程将被记录到慢查询日志文件中。
(3)分析慢查询日志:直接分析mysql慢查询日志,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句。
常见慢查询优化:
- 索引没起作用的情况 o 在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置,索引才会起作用。 o MySQL可以为多个字段创建索引。一个索引可以包括16个字段。对于多列索引,只有查询条件中使用了这些字段中的第1个字段时索引才会被使用。 o 查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,查询中才使用索引。否则,查询将不使用索引。
- 优化数据库结构 o 对于字段比较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。 o 对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。
- 分解关联查询 很多高性能的应用都会对关联查询进行分解,就是可以对每一个表进行一次单表查询,然后将查询结果在应用程序中进行关联,很多场景下这样会更高效。
- 优化LIMIT分页 当偏移量非常大的时候,例如可能是limit 10000,20这样的查询,这是mysql需要查询10020条然后只返回最后20条,前面的10000条记录都将被舍弃,这样的代价很高。优化此类查询的一个最简单的方法是尽可能的使用索引覆盖扫描,而不是查询所有的列。然后根据需要做一次关联操作再返回所需的列。对于偏移量很大的时候这样做的效率会得到很大提升。
[106] 说一说你对explain的了解
利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql语句。DESCRIBE语句的使用方法与EXPLAIN语句是一样的,分析结果也是一样的,并且可以缩写成DESC。

[107]说一说你对redo log、undo log、binlog的了解

Binlog:二进制日志文件就是常说的binlog,逻辑日志。二进制日志记录了MySQL所有修改数据库的操作(DDL、DML),然后以二进制的形式记录在日志文件;用于主从库的同步;⽤于数据库的基于时间点的还原;
redo log:持久性重做日志用来实现事务的持久性,即事务ACID中的D。它由两部分组成:一是内存中的重做日志缓冲(redo log buffer),其是易失的;二是重做日志文件(redo log file),它是持久的,即当事务提交(COMMIT)时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的COMMIT操作完成才算完成
᯿重做⽇志先将数据写⼊缓冲区;然后将缓冲区中的数据写⼊᯿做⽇志⽂件
undo log:用来帮助事务回滚及MVCC的功能 原子性回滚⽇志作⽤: 1. 能够在发⽣错误或者⽤户执⾏ ROLLBACK 时提供回滚相关的信息2. 在整个系统发⽣崩溃、数据库进程直接被杀死后,当⽤户再次启动数据库进程时,还能够 ⽴刻通过查询回滚⽇志将之前未完成的事务进⾏回滚,这也就需要回滚⽇志必须先于数据 持久化到磁盘上,是我们需要先写⽇志后写数据库的主要原因。
[108]对MVCC的了解
多版本并发控制:同一条记录在系统中可以有多个版本MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议,(维持一个数据的多个版本,使得读写操作没有冲突。它最大的优点是读写不冲突,并发性能好。InnoDB实现MVCC,多个版本的数据可以共存
为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。所以 MVCC 可以为数据库解决以下问题:
- 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
- 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,⽤户可以查看当前数据的前⼀个 或者前⼏个历史版本,保证了ACID中的隔离性,但不能解决更新丢失问题
[109]主从复制
概念:数据可以从⼀个MySQL数据库服务器主节点复制到⼀个或者多个从节点

基本过程

主从复制模式: 1. 异步模式 2. 半同步模式 3. 全同步模式 4. GTID复制模式
[110]lvs和Nginx的区别

Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强。一般都会将静态资源部署到Nginx中。
正向代理:客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
反向代理:用户直接访问反向代理服务器就可以获得目标服务器的资源,反向代理服务器负责将请求转发给目标服务器。用户不需要知道目标服务器的地址,也无须在用户端作任何设定
[111]⼀致性hash算法
目的是解决分布式缓存的问题

[112]MySQL主从同步是如何实现的?
复制(replication)是MySQL数据库提供的一种高可用高性能的解决方案,一般用来建立大型的应用。总体来说,replication的工作原理分为以下3个步骤:
- 主服务器(master)把数据更改记录到二进制日志(binlog)中。
- 从服务器(slave)把主服务器的二进制日志复制到自己的中继日志(relay log)中。
- 从服务器重做中继日志中的日志,把更改应用到自己的数据库上,以达到数据的最终一致性。
复制的工作原理并不复杂,其实就是一个完全备份加上二进制日志备份的还原。不同的是这个二进制日志的还原操作基本上实时在进行中。这里特别需要注意的是,复制不是完全实时地进行同步,而是异步实时。这中间存在主从服务器之间的执行延时,如果主服务器的压力很大,则可能导致主从服务器延时较大。复制的工作原理如下图所示,其中从服务器有2个线程,一个是I/O线程,负责读取主服务器的二进制日志,并将其保存为中继日志;另一个是SQL线程,复制执行中继日志。
[113]SQL语⾔四⼤类别
- 数据定义语⾔(DDL)
- 数据操纵语⾔(DML)
- 数据查询语⾔(DQL)
- 数据控制语⾔(DCL):授予或回收访问数据库的某种特权,并控制数据库操纵事务发⽣的时间及效果。

[114]垂直分表和水平分表
分表的⽬的:降低单次查询数据ᰁ,从⽽提⾼查询速度1、⽔平分表:概念:按照⾏拆分,将⼀张表拆分成多张表拆分的⽅法: 数据取模,按照模相同的放到同⼀张表中【随机分表】;时间维度分表【连续分表】
优点: 1. 表关联基本能够在数据库端全部完成; 2. 不会存在某些超⼤型数据ᰁ和⾼负载的表遇到瓶颈的问题; 3. 应⽤程序端整体架构改动相对较少; 4. 事物处理相对简单; 5. 只要切分规则能定义好,基本上较难遇到扩展性限制;
缺点: 1. 切分规则相对更为复杂,很难抽象出⼀个能满⾜整个数据库的切分规则; 2. 后期数据的维护难度有所增加,⼈为⼿⼯定位数据更为困难; 3. 应⽤系统各模块耦合度较⾼,可能会对后⾯数据的迁移拆分造成⼀定的困难
2、垂直分表:概念: 把常⽤的、不常⽤的字段很⻓的拆出来!是指表数据列的拆分,把⼀张列⽐较多的表拆分成多 张表。 表的记录并不多,但是字段却很⻓,表占⽤空间很⼤,检索表的时候需要执⾏⼤ᰁ的IO,严᯿ 降低了性能。 这时候需要把⼤的字段拆分到另外⼀个表,并且该表与原表是⼀对⼀的关系。
垂直拆分规则: 1. 把不常⽤的字段单独放在⼀个表; 2. 把text,blob等⼤字段拆分出来放在附表中; 3. 经常组合查询的列放在⼀张表中;
优点: 1. 数据库的拆分简单明了,拆分规则明确 2. 应⽤程序模块清晰明确,整合容易 3. 数据维护⽅便易⾏,容易定位
缺点: 1. 部分表关联⽆法在数据库级别完成,需要在程序中完成; 2. 对于访问极其频繁且数据ᰁ超⼤的表仍然存在性能瓶颈,不⼀定满⾜需求; 3. 事务处理相对更为复杂; 4. 切分达到⼀定程度后,扩展性会遇到限制; 5. 过度切分可能会带来系统过度复杂⽽难以维护;
数据库分库分表的缺点:

分库分表框架:jdbc应用层(shardingsphere)· proxy代理层

[115]事务

[116]MySQL中四种常用存储引擎
MyISAM、InnoDB,MEMORY,MERGE
[117]Innodb(事务,行锁,外键)和myisam

索引:InnoDB 聚簇索引关键字中存放的是数据,⽽MyISAM聚簇索引中存放的是数据对应的 地址。备份: InnoDB ⽀持在线热备份。
[118]索引和主键的区别
- 主键是为了标识数据库记录唯⼀性,不允许记录᯿复,且键值不能为空,主键也是⼀个特殊索 引
- 数据表中只允许有⼀个主键,但是可以有多个索引
- 使⽤主键的数据库会⾃动创建主索引,也可以在⾮主键上创建索引,⽅便查询效率
- 索引可以提⾼查询速度,它就相当于字典的⽬录,可以通过它很快查询到想要的结果,⽽不需 要进⾏全表扫描
- 主键索引外索引的值可以为空. 主键也可以由多个字段组成,组成复合主键,同时主键肯定也是唯⼀索引
- 唯⼀索引则表示该索引值唯⼀,可以由⼀个或⼏个字段组成,⼀个表可以有多个唯⼀索引
[119]索引的优点与缺点
优点: 1. 创建唯⼀性索引,保证数据库表中每⼀⾏数据的唯⼀性 2. ⼤⼤加快数据的检索速度,这也是创建索引的最主要的原因 3. 加速表和表之间的连接,特别是在实现数据的参考完整性⽅⾯特别有意义。 4. 在使⽤分组和排序⼦句进⾏数据检索时,同样可以显著减少查询中分组和排序的时间。 5. 通过使⽤索引,可以在查询的过程中使⽤优化隐藏器,提⾼系统的性能。
缺点: 1. 创建索引和维护索引要耗费时间,这种时间随着数据ᰁ的增加⽽增加 2. 索引需要占物理空间,除了数据表占数据空间之外,每⼀个索引还要占⼀定的物理空间, 如果要建⽴聚簇索引,那么需要的空间就会更⼤ 3. 当对表中的数据进⾏增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
[120]关系型数据库和非关系型数据库区别
1、数据存储方式不同:关系数据库为表格形式,非关系数据库为文档或图结构2、扩展方式不同:关系数据库可纵向扩展,可提高处理能力,非关系数据库为天然分布式,通过更多的数据服务器来分担负载3、事务处理支持不同:关系数据库善于处理事务原子性细粒度控制,方便事务回滚,非关系数据库着重于处理大数据
关系数据库:oracle、db2、sqlserver、sybase、mysql非关系数据库:Hbase mongodb redis
[续]C++岗位求职面试八股文第二十三篇(数据库)
更多关于算法题解、软件开发面经、机器学习算法面经、各企业面试问题记录,关注Fintech砖,持续更新中。https://www.nowcoder.com/users/873777317
企业面试记录专栏https://www.nowcoder.com/creation/manager/columnDetail/0YBWnm
机器学习面经专栏https://www.nowcoder.com/creation/manager/columnDetail/j8nNy0
软件开发面经专栏https://www.nowcoder.com/creation/manager/columnDetail/0aXKaM
更多校园招聘常见面试问题(开发、算法、编程题目)参见CSDN博客:http://t.csdn.cn/V4qbH
欢迎关注、收藏、点赞后进行问题咨询及秋招建议
#晒一晒我的offer##牛客解忧铺##牛客在线求职答疑中心##如何判断面试是否凉了##23届找工作求助阵地#包含C++、操作系统、数据库、计算机组成、计算机网络、设计模式、操作系统、牛客网服务器项目、综合智力题等