当前位置: 首页 > 科技观察

美团面试官:把MySQL结构说清楚,马上发offer

时间:2023-03-18 22:47:16 科技观察

故事继续分享给大家。我去上海美团面试技术问题。嗯,反正没有给面试官爽的感觉。害,很多东西都是,平时觉得还好,但是到了面试的时候就什么都想不起来了。虽然,我从事Java开发快五年了(2017年),用过Oracle数据库(银行里的系统),但大部分时间用的是MySQL数据库,但还是面临这个问题。也拉了点头皮),以为面试官会问索引,慢查询,性能优化等等(因为这些都是网上找的面试题背下来的)。今天我们就来说说MySQL的架构。我们虽然是Java开发人员,但在日常的开发过程中,经常会和MySQL数据库打交道。如果公司有一个会做事的DBA就更好了。如果没有DBA或者DBA没用,我们了解整个MySQL系统还是很有必要的,也是面试遇到的加分项。如果你想知道一条SQL是怎么查询的,了解了整个MySQL系统就只能说123了。因此,我们有必要了解一下MySQL的架构。平时,我和朋友聊天的时候,常常把MySQL当成我们开发的一个软件系统。既然是软件系统,就有架构图,架构是怎么分层的,每一层的作用是什么。什么是MySQL?MySQL是瑞典MySQLAB公司开发的关系型数据库管理系统,目前属于Oracle。MySQL是一种关系型数据库管理系统,它将数据保存在不同的表中,而不是将所有数据放在一个大仓库中,这样可以提高速度和灵活性。MySQL是开源的,所以你不需要额外付费。MySQL支持大型数据库,可以处理数千万条记录的大型数据库。MySQL使用标准的SQL数据语言形式。MySQL可以在多个系统上使用,支持多种语言,包括C、C++、Python、Java、Ped、PHP、Eifel、Ruby和TCL。MySQL对PHP有很好的支持,PHP是目前最流行的Web开发语言。MySQL支持拥有5000万条记录的大型数据库和数据仓库。32位系统表文件最大支持4GB,64位系统最大支持表文件8TB。MySQL可以定制,使用GPL协议,可以修改源代码开发自己的MySQL系统。请注意MySQL的拼写。另外,很多人可能会有疑问,为什么MySQL的logo是一只海豚呢?下面我们来看一下MySQL的整体架构。MySQL架构图看一下我们开发的系统架构图:其实它们很相似,都有一个分层的概念。既然我们开发的软件系统是可以分层的,那MySQL也可以分层吗?答案是:有,下面说说MySQL的分层,以及每一层的功能。ArchitectureDiagramHierarchy我们可以把上面的架构图拆分开来,做一个简单的说明。连接层和客户端打交道,支持的语言上面已经写了。客户端链接支持的协议有很多,比如我们Java开发中的JDBC。这一层是不是有点像我们项目中的网关层?如果你对网关不熟悉,那么大家可以理解我的controller层。服务层相当于我们业务系统中的服务层,一个大杂烩,相关的业务操作、代码优化、缓存等都在里面。连接池主要负责存储和管理客户端与数据库之间的连接,一个线程负责管理一个连接。自从引入了连接池,官方报告:当数据库连接数达到128时,使用连接池和不使用连接池的性能提升了n倍(无论如何,性能都有很大提升)。建立连接后,就可以执行select语句了。执行逻辑会先到缓存模块。缓存MySQL在收到一个查询请求后,会先去查询缓存中查看这条语句之前是否执行过。以前执行的语句及其结果以键值对的形式存储在内存中。键是查询语句,值是查询结果。如果你的查询可以直接在这个缓存中找到key(hit),那么这个value就会直接返回给客户端。如果缓存中有未命中,则继续执行下一阶段。执行完成后,执行结果会保存在查询缓存中。这里可以看到,如果查询命中了缓存,MySQL可以直接返回结果,不需要进行后续的复杂操作,非常高效。但在大多数情况下,我会建议您不要使用查询缓存,为什么?因为查询缓存往往弊大于利。查询缓存的失效非常频繁。只要更新了表中的某条数据,就会清除该表上的所有查询缓存。因此,保存结果可能会很费力,在使用之前会被一次更新彻底清空。对于更新压力大的数据库,查询缓存的命中率会很低。除非你的业务是要静态表,否则会隔很长时间更新一次。比如:一个系统配置表,那么对这个表的查询就适合查询缓存。幸运的是,MySQL也提供了这种“按需使用”的方式。您可以将参数query_cache_type设置为DEMAND,这样查询缓存就不会被默认的SQL语句使用。【注意】:MySQL8.0直接删除了querycache的整个功能,也就是说MySQL8.0完全没有缓存的功能。如果解析器没有命中查询缓存,它将开始实际执行语句。首先,MySQL需要知道你要做什么,所以需要解析SQL语句。分析器首先会做“词法分析”。你输入的是一个由多个字符串和空格组成的SQL语句。MySQL需要识别其中的字符串是什么以及它们代表什么。完成词法分析之后,就要进行“语法分析”了。语法分析器根据词法分析的结果,根据语法规则判断你输入的SQL语句是否满足MySQL语法。如果我们在拼写SQL时遗漏或写错了某个字母,我们将收到“您的SQL语法有错误”的错误提示。例如,在下面的情况下:错误在于WHERE关键字中缺少一个E。同样,如果字段不存在,我们将使用SQL。一般的语法错误都会提示第一个错误位置,所以要注意“usenear”后面紧跟的内容,仅供参考,有时候这个提示不是很靠谱。SQL通过分析器分析,没有报错。然后此时进入优化器,对SQL进行优化。优化器如果我们的数据库表有多个索引,优化器主要决定使用哪个索引;或者当一个语句有多个表关联(join)时,决定每个表的连接顺序。例如:SELECTa.id,b.idFROMt_userajoint_user_detailbWHEREa.id=b.user_idanda.user_name='田伟昌'andb.id=10001会优化条件查询。优化器流程完成后,此时SQL执行计划已经确定。然后继续进入执行器。首先执行者要判断权限,即是否有权限执行这条SQL。某些客户在工作期间可能会受到权限控制。例如:在生产环境中,大部分开发者只有查询权限,没有增删改查权限(一些小公司除外)。如果有权限,打开表继续执行。打开表时,执行器会根据表的引擎定义使用引擎提供的接口。存储引擎层可以理解为我们业务系统中的持久层。存储引擎的概念只有MySQL才有,并不是所有的关系型数据库都有存储引擎的概念。数据库存储引擎是数据库的底层软件组织,数据库管理系统(DBMS)使用数据引擎来创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技术、锁定级别和其他功能。使用不同的存储引擎,还可以获得特定的功能。许多不同的数据库管理系统现在支持许多不同的数据引擎。因为在关系数据库中数据是以表的形式存储的,所以存储引擎也可以称为表类型(TableType,即存储和操作这张表的类型)。MySQL5.5之前(mysql版本<5.5版本),默认的存储引擎是MyISAM。MySQL5.5版本以后(mysql版本>=5.5版本),默认的存储引擎是InnoDB。下面是一些比较常用的引擎对比:在实际项目中,大部分使用InnoDB,其次是MyISAM。至于其他的存储引擎,至少用到了。我们可以通过命令查看MySQL提供了哪些存储引擎:showengies;我们也可以通过命令查看MySQL当前默认的存储引擎:showvariableslike'%storage_engine%';MyISAM和InnoDB引擎的区别是MySQL5.5之前默认的存储引擎是MyISAM存储引擎。MySQL中很多系统表都使用MyISAM存储引擎,系统临时表也使用MyISAM存储引擎。但是Mysql5.5之后,默认的存储引擎是InnoDB存储引擎。两种存储引擎如何选择?有交易操作吗?是的,InnoDB。您是否存储并发修改?是的,InnoDB。您是否追求数据修改少、查询快?是的,MyISAM。你使用全文索引吗?如果不使用第三方框架,可以选择MyISAM,但是选择第三方框架和InnDB效率会更高。InnoDB存储引擎主要有以下特点:支持事务支持4级事务隔离支持多版本读取支持行级锁读写阻塞与事务隔离级别相关支持缓存,不仅可以缓存索引,还可以缓存数据整表和主键Cluster存储,形成平衡树并不代表InnoDB就一定好。在实际开发中,还是需要根据具体场景选择使用InnoDB还是MyISAM。MyIASM(该引擎是MySQL数据库5.5之前的默认存储引擎)特点:MyISAM不提供对数据库事务的支持,不支持行级锁和外键。由于2,执行INSERT或UPDATE更新语句时,写操作需要锁住整张表,所以会降低效率。MyISAM保存表中的行数。执行SELECTCOUNT(*)FROMTABLE时,可以直接读取相关值,无需全表扫描,速度快。两者的区别:MyISAM是非事务安全的,而InnoDB是事务安全的。MyISAM锁的粒度是表级的,而InnoDB支持行级锁。MyISAM支持全文索引,而InnoDB在MySQL5.6之前不支持全文索引。MySQL5.6开始支持全文索引。使用场景对比:如果要进行大量的select操作,应该选择MyISAM如果要进行大量的insert和update操作,应该选择InnoDB。大型数据集倾向于选择InnoDB引擎,因为它支持事务处理和故障恢复。数据库的大小决定了故障恢复的时间长短。InnoDB可以使用事务日志进行数据恢复,速度会更快。主键查询在InnoDB引擎下也会相当快,但是需要注意的是,如果主键过长,也会造成性能问题。相对来说,InnoDB在互联网公司用得更多。系统文件存储层也可以理解为我们业务系统中的数据库。系统文件存储层主要负责将数据库数据和日志存储在系统文件中,同时完成与存储引擎的打交道,是文件的物理存储层。例如:数据文件、日志文件、pid文件、配置文件等。数据文件“db.opt文件”:记录本数据库使用的默认字符集和校验规则。“frm文件”:存储在edge中的元数据信息,包括表结构的定义信息等,每个表都会有一个frm文件与之对应。“MYD文件”:MyISAM存储引擎专用文件,存放MyISAM表的数据信息,每张MyISAM表都有一个.MYD文件。“MYI文件”:也是MyISAM存储引擎专用的文件,存放MyISAM表的索引相关信息,每张MyISAM表都有一个对应的.MYI文件。“ibd文件和ibdata文件”:存放InnoDB数据文件(包括索引)。InnoDB存储引擎有两种表空间模式:独立表空间和共享表空间。独占表空间使用ibd文件存储数据,每张InnoDB表都有一个对应的.ibd文件。共享表空间使用ibdata文件,所有表共享一个或多个.ibdata文件。“ibdata1file”:系统表空间数据文件,存放表元数据、Undologs等。“ib_logfile0、ib_logfile0files”:Redolog日志文件。日志文件错误日志:默认开启,可以通过命令查看:showvariableslike'%log_error%';binarylogbinarylog:记录对MySQL数据库进行的变更操作,记录语句的发生时间和执行时间;但不记录select、show等不修改数据的SQL查询。主要用于数据库恢复和数据库主从复制。也就是大家常说的binlog日志。showvariableslike'%log_log%';//查看binlog日志是否开启。showvariableslike'%binllog%';//查看参数showbinarylogs;//查看日志文件慢查询日志:记录所有查询数据库超时的SQL查询,默认10秒。showvariableslike'%slow_query%';//查看慢查询日志是否开启。showvariables'%long_query_time%';//查看时间通用查询日志:记录通用查询语句;showvariableslike'%general%';配置文件用于存放MySQL的所有配置信息,如:my.cnf、my.ini等。“pid文件”pid文件是Linux或Unix操作系统下mysqld应用程序的一个进程文件。与许多其他Linux或Unix服务器程序一样,该文件包含自己的进程ID。“套接字文件”套接字文件只在Linux和Unix操作系统下可用。用户在Linux和Unix操作系统下可以直接使用Unixsocket连接MySQL数据库,无需通过TCP/IP网络进行客户端连接。SQL查询流程图总结整个MySQL系统可以看做是我们日常开发的一个软件系统,还有一个访问层,专门连接外部客户端,这个很像我们系统的网关,而缓存类似于我们业务代码中使用的缓存。Cache和Parser可以理解为业务系统中的参数解析和参数校验。优化层可以作为我们开发代码优化的手段,那么存储引擎相当于我们的持久层,文件系统相当于整个业务系统中的数据库。也许这个比喻不是很恰当,但希望大家能够明白严厉的意思。目的只有一个,就是让大家轻松掌握MySQL的全局。本文转载自微信公众号《Java后端技术全栈》,可通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。