mysql数据库实⽤教程答案
前⾔
数据库相关的⾯试题早已成为了⼀线互联⽹⼤⼚⾯试的家常菜,如果你对数据库不太熟悉,我劝你不要轻易⾯试⼤⼚。那么,为什么数据库成了⼤⼚⾯试的家常菜呢?主要原因当然还是海量数据。
⽆论对于刚⼊⾏的⼩⽩还是有⼏年Java开发经验的从业⽽⾔,⾯试不仅是你必须要⾯对的事情,更是你升职加薪的⼀个途径。许多朋友⾯试了⼏家公司也没拿到⼀个满意的薪资,究其根还是在于⾃⼰的知识不够系统化,太凌乱。针对性的温故知新往往能达到事半功倍的效果。
在这⾥我总结⼀线互联⽹⼤⼚java⾯试中常问的“数据库”问题,由于过多答案⽂字仅以图⽚展⽰,所有内容已总结成⽂档在⽂末有领取⽅式!
为什么要分库分表?
⾸先回答⼀下为什么要分库分表,答案很简单:数据库出现性能瓶颈。⽤⼤⽩话来说就是数据库快扛不住了。
数据库出现性能瓶颈,对外表现有⼏个⽅⾯:
⼤量请求阻塞在⾼并发场景下,⼤量请求都需要操作数据库,导致连接数不够了,请求处于阻塞状态。
SQL 操作变慢如果数据库中存在⼀张上亿数据量的表,⼀条 SQL 没有命中索引会全表扫描,这个查询耗时会⾮常久。parameter1
存储出现问题业务量剧增,单库数据量越来越⼤,给存储造成巨⼤压⼒。
从机器的⾓度看,性能瓶颈⽆⾮就是CPU、内存、磁盘、⽹络这些,要解决性能瓶颈最简单粗暴的办法就是提升机器性能,但是通过这种⽅法成本和收益投⼊⽐往往⼜太⾼了,不划算,所以重点还是要从软件⾓度⼊⼿。
数据库相关优化⽅案
数据库优化⽅案很多,主要分为两⼤类:软件层⾯、硬件层⾯。
软件层⾯包括:SQL 调优、表结构优化、读写分离、数据库集、分库分表等;
硬件层⾯主要是增加机器性能。
SQL 调优
SQL 调优往往是解决数据库问题的第⼀步,往往投⼊少部分精⼒就能获得较⼤的收益。
SQL 调优主要⽬的是尽可能地让那些慢 SQL 变快,⼿段其实也很简单就是让 SQL 执⾏尽量命中索引。
开启慢 SQL 记录
如果你使⽤的是 Mysql,需要在 Mysql 配置⽂件中配置⼏个参数即可。
slow_query_log=on
long_query_time=1
slow_query_log_file=/path/to/logjava自学好还是培训
调优的⼯具
常常会⽤到 explain 这个命令来查看 SQL 语句的执⾏计划,通过观察执⾏结果很容易就知道该 SQL 语句是不是全表扫描、有没有命中索引。
select id, age, gender from  user where name = '爱笑的架构师';
返回有⼀列叫“type”,常见取值有:
ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
ALL 代表这条 SQL 语句全表扫描了,需要优化。⼀般来说需要达到range 级别及以上。
表结构优化
以⼀个场景举例说明:
“user”表中有 user_id、nickname 等字段,“order”表中有order_id、user_id等字段,如果想拿到⽤户昵称怎么办?⼀般情况是通过 join 关联表操作,在查询订单表时关联查询⽤户表,从⽽获取到⽤户昵称。
但是随着业务量增加,订单表和⽤户表肯定也是暴增,这时候通过两个表关联数据就⽐较费⼒了,为了取⼀个昵称字段⽽不得不关联查询⼏⼗上百万的⽤户表,其速度可想⽽知。
这个时候可以尝试将 nickname 这个字段加到 order 表中(order_id、user_id、nickname),这种做法通常叫做数据库表冗余字段。这样做的好处展⽰订单列表时不需要再关联查询⽤户表了。
冗余字段的做法也有⼀个弊端,如果这个字段更新会同时涉及到多个表的更新,因此在选择冗余字段时要尽量选择不经常更新的字段。
架构优化
当单台数据库实例扛不住,我们可以增加实例组成集对外服务。
当发现读请求明显多于写请求时,我们可以让主实例负责写,从实例对外提供读的能⼒;
如果读实例压⼒依然很⼤,可以在数据库前⾯加⼊缓存如 redis,让请求优先从缓存取数据减少数据库访问。
缓存分担了部分压⼒后,数据库依然是瓶颈,这个时候就可以考虑分库分表的⽅案了,后⾯会详细介绍。
硬件优化
硬件成本⾮常⾼,⼀般来说不可能遇到数据库性能瓶颈就去升级硬件。
在前期业务量⽐较⼩的时候,升级硬件数据库性能可以得到较⼤提升;但是在后期,升级硬件得到的收益就不那么明显了。
分库分表详解
下⾯我们以⼀个商城系统为例逐步讲解数据库是如何⼀步步演进。
单应⽤单数据库
在早期创业阶段想做⼀个商城系统,基本就是⼀个系统包含多个基础功能模块,最后打包成⼀个 war 包部署,这就是典型的单体架构应⽤。
如上图,商城系统包括主页 Portal 模板、⽤户模块、订单模块、库存模块等,所有的模块都共有⼀个数据库,通常数据库中有⾮常多的表。
因为⽤户量不⼤,这样的架构在早期完全适⽤,开发者可以拿着 demo到处(骗)投资⼈。
⼀旦拿到投资⼈的钱,业务就要开始⼤规模推⼴,同时系统架构也要匹配业务的快速发展。
多应⽤单数据库
在前期为了抢占市场,这⼀套系统不停地迭代更新,代码量越来越⼤,架构也变得越来越臃肿,现在随着系统访问压⼒逐渐增加,系统拆分就势在必⾏了。
为了保证业务平滑,系统架构重构也是分了⼏个阶段进⾏。
第⼀个阶段将商城系统单体架构按照功能模块拆分为⼦服务,⽐如:Portal 服务、⽤户服务、订单服务、库存服务等。
如上图,多个服务共享⼀个数据库,这样做的⽬的是底层数据库访问逻辑可以不⽤动,将影响降到最低。
多应⽤多数据库
随着业务推⼴⼒度加⼤,数据库终于成为了瓶颈,这个时候多个服务共享⼀个数据库基本不可⾏了。我们需要将每个服务相关的表拆出来单独建⽴⼀个数据库,这其实就是“分库”了。评论null表示什么
单数据库的能够⽀撑的并发量是有限的,拆成多个库可以使服务间不⽤竞争,提升服务的性能。
如上图,从⼀个⼤的数据中分出多个⼩的数据库,每个服务都对应⼀个数据库,这就是系统发展到⼀定阶段必要要做的“分库”操作。
现在⾮常⽕的微服务架构也是⼀样的,如果只拆分应⽤不拆分数据库,不能解决根本问题,整个系统也很容易达到瓶颈。
分表
说完了分库,那什么时候分表呢?
如果系统处于⾼速发展阶段,拿商城系统来说,⼀天下单量可能⼏⼗万,那数据库中的订单表增长就特别快,增长到⼀定阶段数据库查询效率就会出现明显下降。
因此,当单表数据增量过快,业界流传是超过500万的数据量就要考虑分表了。当然500万只是⼀个经验值,⼤家可以根据实际情况做出决策。
那如何分表呢?
分表有⼏个维度,⼀是⽔平切分和垂直切分,⼆是单库内分表和多库内分表。
⽔平拆分和垂直拆分
就拿⽤户表(user)来说,表中有7个字段:id,name,age,sex,nickname,description,如果 nickname 和 description 不常⽤,我们可以将其拆分为另外⼀张表:⽤户详细信息表,这样就由⼀张⽤户表拆分为了⽤户基本信息表+⽤户详细信息表,两张表结构不⼀样相互独⽴。但是从这个⾓度来看垂直拆分并没有从根本上解决单表数据量过⼤的问题,因此我们还是需要做⼀次⽔平拆分。
还有⼀种拆分⽅法,⽐如表中有⼀万条数据,我们拆分为两张表,id 为奇数的:1,3,5,7……放在 user1, id 为偶数的:
2,4,6,8……放在 user2中,这样的拆分办法就是⽔平拆分了。
⽔平拆分的⽅式也很多,除了上⾯说的按照 id 拆表,还可以按照时间维度去拆分,⽐如订单表,可以按每⽇、每⽉等进⾏拆分。
每⽇表:只存储当天的数据。
每⽉表:可以起⼀个定时任务将前⼀天的数据全部迁移到当⽉表。
历史表:同样可以⽤定时任务把时间超过 30 天的数据迁移到 history表。
总结⼀下⽔平拆分和垂直拆分的特点:
垂直切分:基于表或字段划分,表结构不同。
⽔平切分:基于数据划分,表结构相同,数据不同。
单库内拆分和多库拆分
拿⽔平拆分为例,每张表都拆分为了多个⼦表,多个⼦表存在于同⼀数据库中。⽐如下⾯⽤户表拆分为⽤户1表、⽤户2表。
在⼀个数据库中将⼀张表拆分为⼏个⼦表在⼀定程度上可以解决单表查询性能的问题,但是也会遇到⼀个问题:单数据库存储瓶颈。
所以在业界⽤的更多的还是将⼦表拆分到多个数据库中。⽐如下图中,⽤户表拆分为两个⼦表,两个⼦表分别存在于不同的数据库中。
多库拆分
⼀句话总结:分表主要是为了减少单张表的⼤⼩,解决单表数据量带来的性能问题。
分库分表带来的复杂性
既然分库分表这么好,那我们是不是在项⽬初期就应该采⽤这种⽅案呢?不要激动,冷静⼀下,分库分表的确解决了很多问题,但是也给系统带来了很多复杂性,下⾯简要说⼀说。
电脑彻底删除文件恢复
(1)跨库关联查询
在单库未拆分表之前,我们可以很⽅便使⽤ join 操作关联多张表查询数据,但是经过分库分表后两张表可能都不在⼀个数据库中,如何使⽤ join 呢?
有⼏种⽅案可以解决:
字段冗余:把需要关联的字段放⼊主表中,避免 join 操作;
数据抽象:通过ETL等将数据汇合聚集,⽣成新的表;
mysql入门基础教程全局表:⽐如⼀些基础表可以在每个数据库中都放⼀份;
应⽤层组装:将基础数据查出来,通过应⽤程序计算组装;
(2)分布式事务
单数据库可以⽤本地事务搞定,使⽤多数据库就只能通过分布式事务解决了。
常⽤解决⽅案有:基于可靠消息(MQ)的解决⽅案、两阶段事务提交、柔性事务等。
(3)排序、分页、函数计算问题
在使⽤ SQL 时 order by, limit 等关键字需要特殊处理,⼀般来说采⽤分⽚的思路:
数学的数有什么组词先在每个分⽚上执⾏相应的函数,然后将各个分⽚的结果集进⾏汇总和再次计算,最终得到结果。
(4)分布式 ID
如果使⽤ Mysql 数据库在单库单表可以使⽤ id ⾃增作为主键,分库分表了之后就不⾏了,会出现id 重复。
常⽤的分布式 ID 解决⽅案有:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。