QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2490|回复: 0
打印 上一主题 下一主题

[参考文献] 拼多多面试问了数据库基础知识,今天分享出来

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-28 15:19 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    拼多多面试问了数据库基础知识,今天分享出来
    8 ~& `; v, j& I! V7 p. P( M
    5 ~! S8 ?; a9 F; `$ K! [1 b+ b# z: _前言
    7 R1 [4 ^9 ^  z9 p. c! R' a, ?1 [9 V5 j2 x  b& O9 c' w* S9 X
    我是个标题党,所有文章的名字只是我的噱头,我们应该有一颗谦逊的心,所以希望大家怀着空杯心态好好学,一起进步。
    * ?6 X# f  X# |! b# T+ V$ C& w+ _9 X! k$ C! {
    数据库我想大家应该一点都不陌生吧,我想不管你写啥的,数据库就算没用过也听过了,是我们项目体系里面不可或缺的一环。( X' x4 ?! P( y

    ( n* y6 U5 t# M1 B3 W3 u5 }4 s问了一圈,身边朋友公司要么用自研,要么就清一色的MySQL,所以想看Oracle的朋友可能要失望了,但是不影响你了解数据库的通用知识。- N% c: C3 L6 J: P+ w* Z6 i7 I
    " ~! E2 W- w1 E8 l8 X# J( V+ @) c
    正文0 E8 m8 i7 _6 j
    $ \( w+ g, s( x- V& Y2 P
    你知道MySQL的基本架构么?你能在纸上给我大致画出这个示意图么?
    ! t' ]. g4 S' V1 D8 C) v- O2 A 1.jpg
    + B; a: ?, j5 R好的那我们按照顺序了解下,连接器是啥?$ A5 G2 S( m2 y& L+ j! H$ E
    我们要进行查询,第一步就是先去链接数据库,那这个时候就是连接器跟我们对接。
    / z( f$ N! S' M
    0 b. {. s. t- i8 r, I: b& b4 G' f他负责跟客户端建立链接、获取权限、维持和管理连接。% `  R. w8 L2 ^
    5 u) Q# s" E" h; _( X6 l* V- o0 i
    链接的时候会经过TCP握手,然后身份验证,然后我们输入用户名密码就好了。; A1 ]; L8 A2 b+ b9 x
    ! M% G% x; a' l! e
    验证ok后,我们就连上了这个MySQL服务了,但是这个时候我们处于空闲状态。* z* F7 p, W5 |' O3 a. b" |+ r
    & M9 u- M  c" F4 Y3 r9 U% t
    怎么查看空闲连接列表?
    0 k+ E7 C5 @9 [show processlist,下图就是我在自己的数据库表执行命令的结果,其中的Command列显示为Sleep的这一行,就表示现在系统里面有一个空闲连接。2 C' j' ^2 U& `3 s) z" X9 H
    2.jpg 4 v9 E' Z  N+ d4 z' W$ r
    这里需要注意的是,我们数据库的客户端太久没响应,连接器就会自动断开了,这个时间参数是wait_timeout控制住的,默认时长为8小时。9 p+ J. b$ O+ P6 R( Z
    ! B$ V( P$ W$ |4 t- ^
    断开后重连的时候会报错,如果你想再继续操作,你就需要重连了。
    * t1 R4 O3 t) Q; t0 D0 z, N5 P
    . N" E- J8 A5 m, \6 d这个有个我看过的书本的案例:; q( L, `# ]: Q# f) Y2 |2 F: P8 U
    6 a% J# y# S: s# Z6 S  ^
    一个在政府里的朋友说,他们的系统很奇怪,每天早上都得重启一下应用程序,否则就提示连接数据库失败,他们都不知道该怎么办。
    9 E2 o0 h! \4 p+ e9 p2 c我分析说,按照这个错误提示,应该就是连接时间过长了,断开了连接。数据库默认的超时时间是8小时,而你们平时六点下班,下班之后系统就没有人用了,等到第二天早上九点甚至十点才上班,这中间的时间已经超过10个小时了,数据库的连接肯定就会断开了。2 K. Q2 P  w' t  f) D  B4 U9 i
    是的,就是超出了超时时间,然后写代码的人也没注意到这个细节,所以才会出现这个问题。
    2 L& f$ c, X- f4 O( ^3 V+ m
    . j1 h  O/ O* w) v把超时时间改得长一点,问题就解决了。, L; c1 G0 A% ]. m( V" X5 |( q1 n

    . q$ q0 ]+ X6 k* p8 S! x. ~这种参数其实我们平时不一定能接触到,但是真的遇到问题的时候,知道每个参数的大概用法,不至于让你变成无头苍蝇。* ?; ]' s7 s3 T: w/ ^8 S- {6 u
    6 d! n7 E0 }2 Y( ^5 f* O
    那除了重新链接,还有别的方式么?因为建立链接还是比较麻烦的。
    0 y6 u& x6 T( Z- r9 [+ o- S4 }使用长连接。% W0 q! x% \, c( e+ \8 R
    2 s5 P2 \* G; F- I- z0 W8 L- w
    但是这里有个缺点,使用长连接之后,内存会飙得很快,我们知道MySQL在执行过程中临时使用的内存是管理在连接对象里面的。4 v' Y" o5 G* P7 G% m0 C

    ' l% Y( n" ?- v7 h# ]- s& @1 n只有在链接断开的时候才能得到释放,那如果一直使用长连接,那就会导致OOM(Out Of Memory),会导致MySQL重启,在JVM里面就会导致频繁的Full GC。% S4 q/ p' j2 \- g1 e% m+ p, F
    * Z: D; ]) T4 J" D
    那你会怎么解决?
      S/ S* d- K8 ], X( Z) J' {我一般会定期断开长连接,使用一段时间后,或者程序里面判断执行过一个占用内存比较大的查询后就断开连接,需要的时候重连就好了。
    * g! `7 f$ k! C) S3 x5 @, ~* S5 Y
    & O4 K9 D6 b- H" B; g( t: z还有别的方法么?你这种感觉不优雅呀小老弟。) \% @9 N1 {) M
    执行比较大的一个查询后,执行mysql_reset_connection可以重新初始化连接资源。这个过程相比上面一种会好点,不需要重连,但是会初始化连接的状态。8 {% s; n+ j3 P% o( w, ^% O

    $ G, }0 P3 q1 O7 O8 N+ S你了解MySQL的查询缓存么?' N2 R5 D, p% A7 F. I
    MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。4 _  r+ C( a8 _- a3 p" d% }

    ) P5 \: i; |/ A  A% _( c3 i( L大家是不是好奇同一条语句在MySQL执行两次,第一次和后面的时间是不一样的,后者明显快一些,这就是因为缓存的存在。& `8 }. `& u  E

    " b3 f7 P+ V2 F: c他跟Redis一样,只要是你之前执行过的语句,都会在内存里面用key-value形式存储着。8 n' i6 Y& b$ f4 z6 J

    8 E$ E5 ?* z7 T0 R) H  J( ^查询的时候就会拿着语句先去缓存中查询,如果能够命中就返回缓存的value,如果不命中就执行后面的阶段。) d7 R' I6 `% F4 ?9 Q
    3 K$ E; q7 w- E; H9 B* p, ^: A
    但是我还是不喜欢用缓存,因为缓存弊大于利。- h% s/ N* W8 V8 N
    3 c! @  A; C' M7 e8 H: n$ K
    哦?此话怎讲?
    5 \- Y) a; l; U: `缓存的失效很容易,只要对表有任何的更新,这个表的所有查询缓存就会全部被清空,就会出现缓存还没使用,就直接被清空了,或者积累了很多缓存准备用来着,但是一个更新打回原形。% |. y, Z1 Z. Q0 H& x' ~
    4 z9 M& k& }" E$ ]) a" W  K- @
    这就导致查询的命中率低的可怕,只有那种只查询不更新的表适用缓存,但是这样的表往往很少存在,一般都是什么配置表之类的。6 H1 ]! R2 d% w0 L' u# j

    , M% ?0 k; K3 ?8 L% X那我们查询的时候不想用缓存一般都是怎么操作的,或者是用缓存又怎么操作?
    3 ~4 \! ]) s6 B# t' l可以显示调用,把query_cache_type设置成为DEMAND,这样SQL默认不适用缓存,想用缓存就用SQL_CACHE。8 ?9 ?4 l  d9 ~2 t# O  [

    4 U$ V) B! x: E5 t& U9 d有个小技巧就是,我们之前开发的时候,都会去库里看看sql执行时间,但是可能是有缓存的,一般我们就在sql前面使用SQL_NO_CACHE就可以知道真正的查询时间了。
      v3 Y. D1 k9 M# @5 q, u% Y
    6 P2 i5 K+ [3 n7 t3 ]. ] select SQL_NO_CACHE * from B8 W' Z5 x' D4 N8 g
    缓存在MySQL8.0之后就取消了,所以大家现在应该不需要太关注这个问题,主要是我之前用的版本都不高,所以缓存一直有,在《高性能MySQL》书中也看到了一些关于缓存的介绍,就想起来给大家也提一下了。( H. M# \2 l6 |2 t: W% e

    , q* {# g, h9 g) k) |, A1 t  ]缓存查询完了应该做啥呢?* L7 _% Y6 k; ?- r6 R+ s4 f
    在缓存没有命中的情况下,就开始执行语句了,你写的语句有没有语法错误,这是接下来MySQL比较关心的点。
    " }; I7 F, v/ E6 f& m% v
    ( {2 Y6 u6 z& f$ h7 [2 q3 a那他会怎么做呢?会先做词法分析,你的语句有这么多单词、空格,MySQL就需要识别每个字符串所代表的是什么,是关键字,还是表名,还是列名等等。
    " X* [  S& k- E. }3 @  A4 j3 Q: \2 A
    然后就开始语法分析,根据词法分析的结果,语法分析会判断你sql的对错,错了会提醒你的,并且会提示你哪里错了。
    2 E9 X# n. z7 v% o5 v0 Z+ W1 Z 3.jpg
    , P  I2 l/ U4 O5 }  l% w4 P分析没错之后就进入下一步,优化器。
    ; ^9 Z7 N  L$ L# c. q7 ~) }$ V& t. J
    4 L& I( u" X9 p! s8 C% Y主要是优化什么呢?! r- F7 ^7 U) }/ z
    优化就比较简单了,因为我们建立表可能会建立很多索引,优化有一步就是要确认使用哪个索引,比如使用你的主键索引,联合索引还是什么索引更好。
      w% G& \7 _2 ], G0 V
    1 g2 T2 d3 i+ r# |' u3 D还有就是对执行顺序进行优化,条件那么多,先查哪个表,还是先关联,会出现很多方案,最后由优化器决定选用哪种方案。" `, b# [* W* ]8 v2 |
    $ m. V4 ]; N, m: K. i# J
    最后就是执行了,执行就交给执行器去做。
    2 i9 j8 z. h# Q6 |
    7 m, S' M0 B! _2 n, v第一步可能就是权限的判断,其实这里我不确定的一个点就是,我接触的公司很多都是自研的线上查询系统,我们是不能用Navicat直连线上库,只能去网页操作,那表的权限是在MySQL层做的,还是系统做的,我猜应该是系统层做的,MySQL可能默认就全开放了,只是我们 不知道ip。! B% S4 B6 A& N+ t2 t0 ^  B$ p9 I+ a
    / I/ V: L1 w& u9 ]- P6 c0 \4 w
    有知道的小伙伴也可以在公众号【三太子敖丙】去加我微信跟我说。+ R. ]( I: ]3 p& W/ U' \
    ! R; b) r3 \8 ^$ h/ W+ B
    执行的时候,就一行一行的去判断是否满足条件,有索引的执行起来可能就好点,一行行的判断就像是接口都提前在引擎定义好了,所以他比较快。
    ' n% e( V5 D# d! i( e5 C/ A0 F- P
    数据库的慢日志有个rows_examined字段,扫描多少行可以看到,还有explain也可以看到执行计划,我们扫描了多少行。& X0 b& x5 T( u( \5 G

    + M) t7 b' i" Y; q可以小伙子,基础大致框架还是了解得很清楚的,我们下次深入了解下,索引和部分机制。
    # d6 Q; K5 R4 T  ?  [8 v, P% O好的,我们下次见。. a; ~5 z; w$ n3 K

    7 h; u  W' B7 v: e8 e* r% L总结6 r6 c$ M( ?& m4 X
    ' b: O: k8 D, [
    基本上我把MySQL的逻辑架构的东西都简单聊了一遍,当然你去自信了解的话,你会发现其实里面还有很多细节的,我只是说了一些常见的问题,这还是阿里丁奇学长的《MySQL实战》的思路。
    ( V2 e! v0 P7 Y& G) }- X3 y) k" Q2 @, H8 O! t4 ?6 {. z
    我自己在MySQL方面更多的可能就是理论知识了,还做不到深入了解的地步,大家如果有机会一定要深入的去学习一下。
    7 q, o7 \) O; Z+ d————————————————. s5 ]/ X- L! Z% [4 X! A. E5 g
    版权声明:本文为CSDN博主「敖 丙」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。$ D6 p( d, E$ L; \9 \/ `  p! A
    原文链接:https://blog.csdn.net/qq_35190492/article/details/104203466
    3 t2 l) G7 Y! r' M/ G; O# L6 Q! I/ i( ?$ U4 r% F6 C

    ( }# c+ ]! k) M( \
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-18 14:00 , Processed in 0.474390 second(s), 54 queries .

    回顶部