diff --git a/404.html b/404.html index 184d60e..0d6a441 100644 --- a/404.html +++ b/404.html @@ -16,13 +16,13 @@ - + -

404

There's nothing here.
+ - + diff --git a/assets/js/23.3b91481f.js b/assets/js/23.3b91481f.js new file mode 100644 index 0000000..0e96fb4 --- /dev/null +++ b/assets/js/23.3b91481f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{265:function(s,t,a){"use strict";a.r(t);var r=a(2),e=Object(r.a)({},(function(){var s=this,t=s.$createElement,a=s._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"mysql"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mysql"}},[s._v("#")]),s._v(" MySQL")]),s._v(" "),a("p",[s._v("MySQL是一个关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性")]),s._v(" "),a("h2",{attrs:{id:"基础架构"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#基础架构"}},[s._v("#")]),s._v(" 基础架构")]),s._v(" "),a("img",{attrs:{src:s.$withBase("/db/mysql/mysql-01.png"),alt:"foo"}}),s._v(" "),a("h3",{attrs:{id:"连接器管理"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#连接器管理"}},[s._v("#")]),s._v(" 连接器管理")]),s._v(" "),a("ul",[a("li",[s._v("长连接:连接成功后,如果客户端持续有请求,则一直使用同一个连接")]),s._v(" "),a("li",[s._v("短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个")])]),s._v(" "),a("p",[s._v("链接的建立过程复杂,操作中如果需要大量长时间的存取数据,使用长链接\n使用长链接的缺点:\n容易占用内存, 因为MySQL在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM)")]),s._v(" "),a("p",[s._v("解决长连接占用内存,短链接繁琐的问题")]),s._v(" "),a("ol",[a("li",[s._v("定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。")]),s._v(" "),a("li",[s._v("如果你用的是MySQL 5.7或更新版本,可以在每次执行一个比较大的操作后,通过执行"),a("code",[s._v("mysql_reset_connection")]),s._v("来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。")])]),s._v(" "),a("h3",{attrs:{id:"mysql缓存"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mysql缓存"}},[s._v("#")]),s._v(" Mysql缓存")]),s._v(" "),a("p",[s._v("Mysql通过在内存中建立"),a("code",[s._v("缓冲区[buffer]")]),s._v("和"),a("code",[s._v("缓寸[cache]")]),s._v("来提高Mysql性能,key是查询的语句,value是查询的结果,对于InnoDB引擎,Mysql采用"),a("code",[s._v("缓冲池[buffer pool]")]),s._v("的方式来缓存数据和索引,对于MyISAM引擎,Mysql采用缓存的方式来缓存数据和索引,先看缓存数据,如果存在则直接返回。如果没有则直接往下走")]),s._v(" "),a("ul",[a("li",[s._v("关键字缓存(key cache)\n"),a("ul",[a("li",[s._v("当Mysql收到传入的sql语句时,它首先和先前已经解析过的sql语句进行比较,如果发现相同,则返回已缓存数据。一定是完全相同,因此MySQL的查询缓存命中率很低")])])]),s._v(" "),a("li",[s._v("查询缓存(query cache)")])]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SHOW")]),s._v(" variables "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("LIKE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'have_query_cache'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查询mysql缓存配置信息")]),s._v("\n")])])]),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),a("p",[s._v("对于一些不常改变的数据且有大量相同sql查询的表,查询缓存会节约很大的性能,对于频繁更改的表,查询缓存是不合适的")])]),s._v(" "),a("h3",{attrs:{id:"分析器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#分析器"}},[s._v("#")]),s._v(" 分析器")]),s._v(" "),a("p",[s._v("分析器对你执行的sql语句进行解析,首先是词法分析包括一些关键字识别,然后语法分析,查看这条语句是否符合mysql语句")]),s._v(" "),a("p",[s._v("分析器分析识别")]),s._v(" "),a("ul",[a("li",[a("strong",[s._v("词法分析")]),s._v("(识别关键字):\n输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别出里面的字符串分别是什么,代表什么。\nMySQL从你输入的"),a("code",[s._v("SELECT")]),s._v('这个关键字识别出来,这是一个查询语句。它也要把字符串"T"识别成"表名T",把字符串"ID"识别成"列ID"')]),s._v(" "),a("li",[a("strong",[s._v("语法分析")]),s._v(" (判断语法):\n根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法\n如果语法不对,就会收到报错提醒,一般语法错误会提示第一个出现错误的位置\n即关注报错中的 "),a("code",[s._v("user near")])])]),s._v(" "),a("h3",{attrs:{id:"优化器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#优化器"}},[s._v("#")]),s._v(" 优化器")]),s._v(" "),a("p",[s._v("经过分析器的分析,Mysql就知道你要做的事情是什么了,但是,在开始执行之前,需要经过优化器的处理。发现那些查询命中索引,还有表之间的连接顺序等")]),s._v(" "),a("p",[s._v("优化器是在表里面有多个索引的时候,决定使用哪个索引。或者在一个语句有多表关联"),a("code",[s._v("JOIN")]),s._v("的时候,决定各个表的连接顺序。比如你执行下面这样的语句,这个语句是执行两个表的"),a("code",[s._v("JOIN")]),s._v(":")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" T1 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("JOIN")]),s._v(" T2 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("USING")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" T1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("c"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("10")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("AND")]),s._v(" T2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("d"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("20")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("ul",[a("li",[s._v("既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面d的值是否等于20。")]),s._v(" "),a("li",[s._v("也可以先从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面c的值是否等于10。\n这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案")])]),s._v(" "),a("h3",{attrs:{id:"执行器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#执行器"}},[s._v("#")]),s._v(" 执行器")]),s._v(" "),a("p",[s._v("通过上面一系列的验证,使用引擎提供的接口。经过不断的执行将查询的结果存放在结果集中,通过"),a("code",[s._v("EXPLAIN")]),s._v("可以看到执行器具体扫描了多少行。")]),s._v(" "),a("p",[s._v("经过优化器筛选优化的查询语句后,就进入执行器阶段,开始执行语句")]),s._v(" "),a("p",[s._v("开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示。")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" T "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" ID"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'")]),s._v("\n")])])]),a("p",[s._v("如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。")]),s._v(" "),a("p",[s._v("比如我们这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:")]),s._v(" "),a("ol",[a("li",[s._v("调用InnoDB引擎接口取这个表的第一行,判断ID值是不是10,如果不是则跳过,如果是则将这行存在结果集中;")]),s._v(" "),a("li",[s._v("调用引擎接口取"),a("code",[s._v("下一行")]),s._v(",重复相同的判断逻辑,直到取到这个表的最后一行。")]),s._v(" "),a("li",[s._v("执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。")])]),s._v(" "),a("p",[s._v("至此,这个语句就执行完成了")]),s._v(" "),a("p",[s._v('对于有索引的表,执行的逻辑也差不多第一次调用的是"取满足条件的第一行"这个接口,之后循环取"满足条件的下一行"这个接口,这些接口都是引擎中已经定义好的。\n你会在数据库的慢查询日志中看到一个'),a("code",[s._v("rows_examined")]),s._v("的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。")]),s._v(" "),a("p",[s._v("在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟"),a("code",[s._v("rows_examined")]),s._v("并不是完全相同的")]),s._v(" "),a("h3",{attrs:{id:"日志系统"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#日志系统"}},[s._v("#")]),s._v(" 日志系统")]),s._v(" "),a("p",[s._v("首先要清楚redolog和binlog两个日志模块")]),s._v(" "),a("ol",[a("li",[s._v("redolog(InnoDB特有的日志模块,起初InnoDB是另一个公司以插件的方式加到mysql的,拥有"),a("strong",[s._v("crash-safe")]),s._v("故障恢复能力) 重做日志文件,用于记录事务操作的变化,记录修改后的值,不管事务是否提交。保证数据的完整性。其中redolog是固定大小的,是从头开始写,写到末尾在从头开始。同时会有两个指针,一个记录写入的位置,一个标记,当前擦除的位置,不断的循环。整个过程称为crash-safe。即时数据库异常,也会有记录")]),s._v(" "),a("li",[s._v("binlog 归档日志文件,用于记录对mysql数据库执行更改的所有操作。binlog是追加写,不会覆盖之前的。")])]),s._v(" "),a("p",[s._v("MySQL InnoDB 更新一条语句的流程")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("UPDATE")]),s._v(" user_info "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SET")]),s._v(" name "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"marco"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" id "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("ol",[a("li",[s._v("执行器先找引擎取出ID=1这一行,ID是主键,引擎直接用树搜索找到这一行,如果本来这一行所在的数据页就在内存中,就直接返回给执行器")]),s._v(" "),a("li",[s._v("执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新一行数据,再调用引擎接口写入这行新数据")]),s._v(" "),a("li",[s._v("引擎将这行新数据更新到内存中,同时将这个更新记录到redolog里面,此时redolog处于prepare状态,然后告知执行器执行任务完成了,随时可以提交事务")]),s._v(" "),a("li",[s._v("执行器生成这个操作的binlog,并把binlog卸乳磁盘")]),s._v(" "),a("li",[s._v("执行器调用引擎的提交事务接口,引擎把刚刚卸乳的redolog改为提交commit状态,更新完成")])]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),a("p",[s._v("注意:Mysql的redolog模块写入拆成2步走,prepare和commit,称为两阶段提交。\n"),a("strong",[s._v("1.redolog的prepare状态 2. binlog的写入")])])]),s._v(" "),a("p",[s._v("如果binlog没有写入并没有提交事务回滚\n如果binlog写入事务没提交,数据库回复后自动完成commit")]),s._v(" "),a("h2",{attrs:{id:"基础拓扑"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#基础拓扑"}},[s._v("#")]),s._v(" 基础拓扑")]),s._v(" "),a("center",[a("img",{staticStyle:{display:"left"},attrs:{src:s.$withBase("/db/mysql/mysql-09.png"),alt:"foo"}})]),s._v(" "),a("h2",{attrs:{id:"数据结构"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#数据结构"}},[s._v("#")]),s._v(" 数据结构")]),s._v(" "),a("p",[s._v("数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优,MySQL官方对索引的定义为:"),a("u",[a("b",[s._v("索引(Index)")]),s._v("是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构")])]),s._v(" "),a("h3",{attrs:{id:"b树、b-树、b-树"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#b树、b-树、b-树"}},[s._v("#")]),s._v(" B树、B-树、B+树")]),s._v(" "),a("p",[s._v("目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构")]),s._v(" "),a("h4",{attrs:{id:"b-树-即二叉搜索树"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#b-树-即二叉搜索树"}},[s._v("#")]),s._v(" B 树 "),a("code",[s._v("即二叉搜索树")])]),s._v(" "),a("center",[a("img",{staticStyle:{display:"left"},attrs:{src:s.$withBase("/db/mysql/mysql-03.jpg"),alt:"foo"}})]),s._v(" "),a("ol",[a("li",[s._v("所有非叶子结点至多拥有两个儿子(Left和Right)")]),s._v(" "),a("li",[s._v("所有结点存储一个关键字;")]),s._v(" "),a("li",[s._v("非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;\n"),a("center",[a("img",{attrs:{src:s.$withBase("/db/mysql/mysql-04.jpg"),alt:"foo"}})])],1)]),s._v(" "),a("p",[s._v("B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;")]),s._v(" "),a("p",[s._v("如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;")]),s._v(" "),a("center",[a("img",{attrs:{src:s.$withBase("/db/mysql/mysql-05.jpg"),alt:"foo"}}),s._v(" "),a("p",[s._v(" 但B树在经过多次插入与删除后,有可能导致不同的结构")])]),s._v(" "),a("p",[s._v("右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题;"),a("br"),s._v("\n实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略;")]),s._v(" "),a("h4",{attrs:{id:"b-tree-一种多路搜索树(并不是二叉的)"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#b-tree-一种多路搜索树(并不是二叉的)"}},[s._v("#")]),s._v(" B- Tree "),a("code",[s._v("一种多路搜索树(并不是二叉的)")])]),s._v(" "),a("center",[a("img",{attrs:{src:s.$withBase("/db/mysql/mysql-06.jpg"),alt:"foo"}})]),s._v(" "),a("p",[s._v("B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;")]),s._v(" "),a("ol",[a("li",[s._v("关键字集合分布在整颗树中;")]),s._v(" "),a("li",[s._v("任何一个关键字出现且只出现在一个结点中;")]),s._v(" "),a("li",[s._v("搜索有可能在非叶子结点结束;")]),s._v(" "),a("li",[s._v("其搜索性能等价于在关键字全集内做一次二分查找;")]),s._v(" "),a("li",[s._v("自动层次控制;")])]),s._v(" "),a("p",[s._v("由于B-Tree的特性,在B-Tree中按key检索数据的算法非常直观:"),a("strong",[s._v("首先从根节点进行二分查找,如果找到则返回对应节点的data,否则对相应区间的指针指向的节点递归进行查找,直到找到节点或找到null指针,前者查找成功,后者查找失败")])]),s._v(" "),a("h4",{attrs:{id:"b-tree-b-树的变体,也是一种多路搜索树"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#b-tree-b-树的变体,也是一种多路搜索树"}},[s._v("#")]),s._v(" B+ Tree "),a("code",[s._v("B-树的变体,也是一种多路搜索树")])]),s._v(" "),a("center",[a("img",{attrs:{src:s.$withBase("/db/mysql/mysql-07.jpg"),alt:"foo"}})]),s._v(" "),a("p",[s._v("B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找")]),s._v(" "),a("ol",[a("li",[s._v("其定义基本与B-树同,除了:")]),s._v(" "),a("li",[s._v("非叶子结点的子树指针与关键字个数相同;")]),s._v(" "),a("li",[s._v("非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);")]),s._v(" "),a("li",[s._v("为所有叶子结点增加一个链指针;")]),s._v(" "),a("li",[s._v("所有关键字都在叶子结点出现;")])]),s._v(" "),a("p",[s._v("一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。")]),s._v(" "),a("h3",{attrs:{id:"磁盘存取原理"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#磁盘存取原理"}},[s._v("#")]),s._v(" 磁盘存取原理")]),s._v(" "),a("div",{staticStyle:{float:"left"}},[a("img",{attrs:{src:s.$withBase("/db/mysql/mysql-02.jpg"),alt:"foo"}})]),s._v(" "),a("p",[s._v("一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动(各个磁盘必须同步转动)。在磁盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不能转动,但是可以沿磁盘半径方向运动(实际是斜切向运动),每个磁头同一时刻也必须是同轴的,即从正上方向下看,所有磁头任何时候都是重叠的(不过目前已经有多磁头独立技术,可不受此限制)。")]),s._v(" "),a("p",[s._v("盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存\n储单元。")]),s._v(" "),a("p",[s._v("当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做"),a("strong",[s._v("寻道时间")]),s._v(",然后磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做"),a("strong",[s._v("旋转时间")]),s._v("。")]),s._v(" "),a("p",[s._v("局部性原理与磁盘预读\n由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。")]),s._v(" "),a("p",[s._v("这样做的理论依据是计算机科学中著名的"),a("strong",[s._v("局部性原理")]),s._v(":当一个数据被用到时,其附近的数据也通常会马上被使用。\n程序运行期间所需要的数据通常比较集中。")]),s._v(" "),a("p",[a("u",[s._v("由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。")])]),s._v(" "),a("p",[s._v("预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。")]),s._v(" "),a("p",[s._v("数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:\n每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。\nB-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为"),a("code",[s._v("O(h)=O(logdN)")])]),s._v(" "),a("p",[s._v("一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。综上所述,用B-Tree作为索引结构效率是非常高的。而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。")]),s._v(" "),a("h3",{attrs:{id:"myisam-索引实现"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#myisam-索引实现"}},[s._v("#")]),s._v(" MyISAM 索引实现")]),s._v(" "),a("p",[s._v("MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。")]),s._v(" "),a("p",[s._v("MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分")]),s._v(" "),a("h3",{attrs:{id:"innodb-索引实现"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#innodb-索引实现"}},[s._v("#")]),s._v(" InnoDB 索引实现")]),s._v(" "),a("p",[s._v("虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。")]),s._v(" "),a("ol",[a("li",[s._v("InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。")]),s._v(" "),a("li",[s._v("与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域\nInnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择")])]),s._v(" "),a("p",[s._v("InnoDB支持以下几种索引:")]),s._v(" "),a("ul",[a("li",[a("strong",[s._v("全文索引")]),s._v(":全文索引是将存在数据库的整本书的任意内容信息查找出来的技术,InnoDB从1.2.x版本支持。每张表只能有一个全文检索的索引")]),s._v(" "),a("li",[a("strong",[s._v("哈希索引")]),s._v(":哈希索引是自适应的,也就是说这个不能人为干预在一张表生成哈希索引,InnoDB会根据这张表的使用情况来自动生成。")]),s._v(" "),a("li",[a("strong",[s._v("B+树索引")]),s._v(":B+树索引是传统意义上的索引,B+树索引并不能根据键值找到具体的行数据,B+树索引只能找到行数据所在的页,然后通过把页读到内存,再在内存中查找到行数据。B+树索引也是最常用的最为频繁使用的索引。")])]),s._v(" "),a("h4",{attrs:{id:"聚集索引"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#聚集索引"}},[s._v("#")]),s._v(" 聚集索引")]),s._v(" "),a("p",[s._v("聚集索引是按表的主键构造的B+树,叶子节点存放的为整张表的行记录数据,每张表只能有一个聚集索引。优化器更倾向采用聚集索引。因为直接就能获取行数据。\n请选择自增id来做主键,不要非空UK列。避免大量分页碎片。下面来看一个聚集索引的图:\n那么很简单了,每个叶子节点,都存有完整的行记录。对于主键的查找速度那是相当的快,美滋滋")]),s._v(" "),a("h4",{attrs:{id:"辅助索引"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#辅助索引"}},[s._v("#")]),s._v(" 辅助索引")]),s._v(" "),a("p",[s._v("辅助索引也叫非聚集索引,叶子节点除了键值以外还包含了一个bookmark,用来告诉InnoDB在哪里可以找到对应的行数据,InnoDB的辅助索引的bookmark就是相对应行数据的聚集索引键。也就是"),a("strong",[s._v("先获取指向主键索引的主键,然后通过主键索引来找到一个完整的行")]),s._v("。如果辅助索引的树和聚集索引的树的高度都是3,如果不是走主键索引走辅助索引的话,那么需要6次逻辑IO访问得到最终的数据页")]),s._v(" "),a("h4",{attrs:{id:"一颗聚集索引b-树可以放多少行数据?"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#一颗聚集索引b-树可以放多少行数据?"}},[s._v("#")]),s._v(" 一颗聚集索引B+树可以放多少行数据?")]),s._v(" "),a("p",[s._v("这里我们先假设B+树高为2,即存在一个根节点和若干个叶子节点,那么这棵B+树的存放总记录数为:根节点指针数*单个叶子节点记录行数。假设一行记录的数据大小为1k,那么单个叶子节点(页)中的记录数=16K/1K=16。")]),s._v(" "),a("p",[s._v("那么现在我们需要计算出非叶子节点能存放多少指针,我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,即16kb/14b=1170。那么可以算出一棵高度为2的B+树,大概能存放1170*16=18720条这样的数据记录。")]),s._v(" "),a("p",[s._v("根据同样的原理我们可以算出一个高度为3的B+树大概可以存放:1170"),a("em",[s._v("1170")]),s._v("16=21902400行数据。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次逻辑IO操作即可查找到数据。")]),s._v(" "),a("h2",{attrs:{id:"锁机制"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#锁机制"}},[s._v("#")]),s._v(" 锁机制")]),s._v(" "),a("h2",{attrs:{id:"隔离级别"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#隔离级别"}},[s._v("#")]),s._v(" 隔离级别")]),s._v(" "),a("h2",{attrs:{id:"mvcc"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mvcc"}},[s._v("#")]),s._v(" MVCC")]),s._v(" "),a("h2",{attrs:{id:"innodb"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#innodb"}},[s._v("#")]),s._v(" InnoDB")]),s._v(" "),a("h2",{attrs:{id:"explain"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#explain"}},[s._v("#")]),s._v(" Explain")]),s._v(" "),a("h2",{attrs:{id:"查询优化"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#查询优化"}},[s._v("#")]),s._v(" 查询优化")]),s._v(" "),a("center",[a("img",{staticStyle:{display:"left"},attrs:{src:s.$withBase("/db/mysql/mysql-08.png"),alt:"foo"}})]),s._v(" "),a("h3",{attrs:{id:"查找分析查询速度慢点原因"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#查找分析查询速度慢点原因"}},[s._v("#")]),s._v(" 查找分析查询速度慢点原因")]),s._v(" "),a("ol",[a("li",[s._v("分析SQL查询慢的方法")]),s._v(" "),a("li",[s._v("记录慢查询日志")])]),s._v(" "),a("h3",{attrs:{id:"优化手段"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#优化手段"}},[s._v("#")]),s._v(" 优化手段")]),s._v(" "),a("h4",{attrs:{id:"分区"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#分区"}},[s._v("#")]),s._v(" 分区")]),s._v(" "),a("p",[s._v("分区表后,提高了MySql性能。如果一张表的话,那就只有一个.ibd文件,一颗大的B+树。如果分表后,将按分区规则,分成不同的区,也就是一个大的B+树,分成多个小的树。\n读的效率肯定提升了,如果走分区键索引的话,先走对应分区的辅助索引B+树,再走对应分区的聚集索引B+树。\n如果没有走分区键,将会在所有分区都会执行一次。会造成多次逻辑IO!平时开发如果想查看sql语句的分区查询可以使用explain partitons select xxxxx语句。可以看到一句select语句走了几个分区。")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[s._v("mysql"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("explain")]),s._v(" partitions "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("select")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("from")]),s._v(" TxnList "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("where")]),s._v(" startTime"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'2016-08-25 00:00:00'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("and")]),s._v(" startTime"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'2016-08-25 23:59:00'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" id "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" select_type "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("table")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" partitions "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("type")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" possible_keys "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("key")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" key_len "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" ref "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("rows")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" Extra "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SIMPLE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" ClientActionTrack "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" p20160825 "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ALL")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("33868")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("Using")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("where")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("row")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("set")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0.00")]),s._v(" sec"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])])]),a("ol",[a("li",[s._v("查看MySQL是否支持分区")])]),s._v(" "),a("p",[s._v("a. MySQL5.6以及之前版本")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SHOW")]),s._v(" variables "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("LIKE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'%partition%'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("p",[s._v("b. MySQL5.7")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SHOW")]),s._v(" PLUGINS"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("ol",{attrs:{start:"2"}},[a("li",[s._v("分区表的分类与限制")])]),s._v(" "),a("ul",[a("li",[s._v("a. 分区表分类\n"),a("ul",[a("li",[s._v("RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。")]),s._v(" "),a("li",[s._v("LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。")]),s._v(" "),a("li",[s._v("HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。")]),s._v(" "),a("li",[s._v("KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。")]),s._v(" "),a("li",[s._v("复合分区:在MySQL 5.6版本中,只支持RANGE和LIST的子分区,且子分区的类型只能为HASH和KEY。")])])]),s._v(" "),a("li",[s._v("b. 分区表限制\n"),a("ul",[a("li",[s._v("分区键必须包含在表的所有主键、唯一键中。")]),s._v(" "),a("li",[s._v("MYSQL只能在使用分区函数的列本身进行比较时才能过滤分区,而不能根据表达式的值去过滤分区,即使这个表达式就是分区函数也不行。")]),s._v(" "),a("li",[s._v("最大分区数: 不使用NDB存储引擎的给定表的最大可能分区数为8192(包括子分区)。如果当分区数很大,但是未达到8192时提示 Got error … from storage engine: Out of resources when opening file,可以通过增加open_files_limit系统变量的值来解决问题,当然同时打开文件的数量也可能由操作系统限制。")]),s._v(" "),a("li",[s._v("不支持查询缓存: 分区表不支持查询缓存,对于涉及分区表的查询,它自动禁用。 查询缓存无法启用此类查询。")]),s._v(" "),a("li",[s._v("分区的innodb表不支持外键。")]),s._v(" "),a("li",[s._v("服务器SQL_mode影响分区表的同步复制。 主机和从机上的不同SQL_mode可能会导致sql语句; 这可能导致分区之间的数据分配给定主从位置不同,甚至可能导致插入主机上成功的分区表在从库上失败。 为了获得最佳效果,您应该始终在主机和从机上使用相同的服务器SQL模式。")]),s._v(" "),a("li",[s._v("ALTER TABLE … ORDER BY: 对分区表运行的ALTER TABLE … ORDER BY列语句只会导致每个分区中的行排序。")]),s._v(" "),a("li",[s._v("全文索引。 分区表不支持全文索引,即使是使用InnoDB或MyISAM存储引擎的分区表。")]),s._v(" "),a("li",[s._v("分区表无法使用外键约束。")]),s._v(" "),a("li",[s._v("Spatial columns: 具有空间数据类型(如POINT或GEOMETRY)的列不能在分区表中使用。")]),s._v(" "),a("li",[s._v("临时表: 临时表不能分区。")]),s._v(" "),a("li",[s._v("subpartition问题: subpartition必须使用HASH或KEY分区。 只有RANGE和LIST分区可能被分区; HASH和KEY分区不能被子分区。")]),s._v(" "),a("li",[s._v("分区表不支持mysqlcheck,myisamchk和myisampack。")])])])]),s._v(" "),a("ol",{attrs:{start:"3"}},[a("li",[s._v("创建分区表")])]),s._v(" "),a("ul",[a("li",[s._v("a. range分区")])]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("CREATE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TABLE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v("test_range"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("11")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("NOT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v("t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("date")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("NOT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PRIMARY")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("KEY")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),s._v("t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("`")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ENGINE")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("InnoDB")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("DEFAULT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("CHARSET")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("utf8\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("BY")]),s._v(" RANGE "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("to_days"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" p20170801 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" LESS THAN "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("736907")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ENGINE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("InnoDB")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" p20170901 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" LESS THAN "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("736938")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ENGINE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("InnoDB")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" pmax "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" LESS THAN maxvalue "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ENGINE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("InnoDB")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("123456789")]),s._v("\n")])])]),a("p",[s._v("然后查看分区状态")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("insert")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("into")]),s._v(" test_range "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("values")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"20170722"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"20170822"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("3")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"20170823"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"20170824"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" PARTITION_NAME "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("AS")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"分区"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("TABLE_ROWS "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("AS")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"行数"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" information_schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("partitions "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" TABLE_NAME"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"test_range"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("table",[a("thead",[a("tr",[a("th",[s._v("分区")]),s._v(" "),a("th",[s._v("行数")])])]),s._v(" "),a("tbody",[a("tr",[a("td",[s._v("p20170801")]),s._v(" "),a("td",[s._v("1")])]),s._v(" "),a("tr",[a("td",[s._v("p20170901")]),s._v(" "),a("td",[s._v("3")])]),s._v(" "),a("tr",[a("td",[s._v("pmax")]),s._v(" "),a("td",[s._v("0")])])])]),s._v(" "),a("p",[s._v("可以看出分区p20170801插入1行数据,p20170901插入的3行数据。\n可以是用year、to_days、unix_timestamp等函数对相应的时间字段进行转换,然后分区。")]),s._v(" "),a("ul",[a("li",[s._v("b. list分区")])]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("CREATE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TABLE")]),s._v(" test_list "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n c1 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INT")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n c2 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INT")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("BY")]),s._v(" LIST"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("c1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" p0 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("IN")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("7")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" p1 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("IN")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INSERT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INTO")]),s._v(" test_list "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" PARTITION_NAME "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("AS")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"分区"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("TABLE_ROWS "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("AS")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"行数"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" information_schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("partitions "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" TABLE_NAME"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"test_list"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("p",[s._v("和range分区一样,只是list分区面向的是离散的值, 与RANGE分区的情况不同,没有"),a("code",[s._v("catch-all")]),s._v(",如MAXVALUE; 分区表达式的所有预期值应在"),a("code",[s._v("PARTITION VALUES IN()")]),s._v("子句中涵盖。 包含不匹配的分区列值的INSERT语句失败并显示错误,插入的数字必须在这个范围内")]),s._v(" "),a("ul",[a("li",[s._v("c. hash分区")])]),s._v(" "),a("p",[s._v("根据用户自定义表达式的返回值来进行分区,返回值不能为负数")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("CREATE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TABLE")]),s._v(" test_hash "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("col1 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INT")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" col2 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("CHAR")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" col3 "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("DATE")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("BY")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("HASH")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("YEAR")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("col3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n PARTITIONS "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INSERT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INTO")]),s._v(" test_hash "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'2'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'2020-03-08'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" PARTITION_NAME "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("AS")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"分区"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("TABLE_ROWS "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("AS")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"行数"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" information_schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("partitions "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" TABLE_NAME"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"test_hash"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("ul",[a("li",[s._v("d. key分区")])]),s._v(" "),a("p",[s._v("根据MySQL数据库提供的散列函数进行分区")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("CREATE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TABLE")]),s._v(" test_key "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n id "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("NOT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("NULL")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n name "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VARCHAR")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("20")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("UNIQUE")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("KEY")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("BY")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("KEY")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\nPARTITIONS "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("p",[s._v("KEY仅列出零个或多个列名称。 用作分区键的任何列必须包含表的主键的一部分或全部,如果该表具有一个。如果没有列名称作为分区键,则使用表的主键(如果有)。如果没有主键,但是有一个唯一的键,那么唯一键用于分区键。但是,如果唯一键列未定义为NOT NULL,则上一条语句将失败。与其他分区类型不同,KEY使用的分区不限于整数或空值")]),s._v(" "),a("ul",[a("li",[s._v("e. column分区")]),s._v(" "),a("li",[s._v("f. 子分区(组合分区)")])]),s._v(" "),a("ol",{attrs:{start:"4"}},[a("li",[s._v("普通表转换为分区表")])]),s._v(" "),a("p",[s._v("用"),a("code",[s._v("alter table table_name partition by")]),s._v("命令重建分区表")]),s._v(" "),a("div",{staticClass:"language-sql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ALTER")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TABLE")]),s._v(" jxfp_data_bak "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("PARTITION")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("BY")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("KEY")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("SH"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" PARTITIONS "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("h4",{attrs:{id:"分库分表"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#分库分表"}},[s._v("#")]),s._v(" 分库分表")]),s._v(" "),a("p",[s._v("当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。")]),s._v(" "),a("p",[s._v("mysql中有一种机制是表锁定和行锁定,是为了保证数据的完整性。表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行。行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作。")]),s._v(" "),a("p",[a("strong",[s._v("垂直拆分")])]),s._v(" "),a("p",[s._v("垂直分库(根据业务不同与微服务类似单独服务对应单独库)\n垂直分表\n垂直分表是基于数据库中的”列”进行,某个表字段较多,可以新建一张扩展表,将不经常用或字段长度较大的字段拆分出去到扩展表中。在字段很多的情况下(例如一个大表有100多个字段),通过”大表拆小表”,更便于开发与维护,也能避免跨页问题,MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。\n拆分字段的操作建议在数据库设计阶段就做好。如果是在发展过程中拆分,则需要改写以前的查询语句,会额外带来一定的成本和风险,建议谨慎")]),s._v(" "),a("ul",[a("li",[s._v("优点:\n"),a("ul",[a("li",[s._v("解决业务系统层面的耦合,业务清晰")]),s._v(" "),a("li",[s._v("与微服务的治理类似,也能对不同业务的数据进行分级管理、维护、监控、扩展等")]),s._v(" "),a("li",[s._v("高并发场景下,垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈")])])]),s._v(" "),a("li",[s._v("缺点:\n"),a("ul",[a("li",[s._v("部分表无法join,只能通过接口聚合方式解决,提升了开发的复杂度")]),s._v(" "),a("li",[s._v("依然存在单表数据量过大的问题(需要水平切分)")]),s._v(" "),a("li",[s._v("分布式事务处理复杂")])])])]),s._v(" "),a("p",[a("strong",[s._v("水平拆分")])]),s._v(" "),a("p",[s._v("根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个数据库或多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小,达到分布式的效果")]),s._v(" "),a("ul",[a("li",[s._v("优点:\n"),a("ul",[a("li",[s._v("不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力")]),s._v(" "),a("li",[s._v("应用端改造较小,不需要拆分业务模块")])])])]),s._v(" "),a("p",[a("strong",[s._v("“冷热数据分离”实现方案")])]),s._v(" "),a("ul",[a("li",[s._v("缺点:\n"),a("ul",[a("li",[s._v("跨分片事务难以保证")]),s._v(" "),a("li",[s._v("跨分片的复杂查询如join关联查询")]),s._v(" "),a("li",[s._v("数据多次扩展难度和维护量极大")])])])]),s._v(" "),a("p",[a("strong",[s._v("数据分片规则")])]),s._v(" "),a("ol",[a("li",[s._v("冷热数据隔离(近6个月或者1年的数据作为热数据,历史数据作为冷数据再进行时间维度拆分)")]),s._v(" "),a("li",[s._v("地域区域或者其他拆分方式")]),s._v(" "),a("li",[s._v("userNo范围分表,比如0~500w用户在user1表,501w-1000w在user2表等")])]),s._v(" "),a("ul",[a("li",[s._v("优点:\n"),a("ul",[a("li",[s._v("单表大小可控")]),s._v(" "),a("li",[s._v("天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数 据进行迁移")]),s._v(" "),a("li",[s._v("使用分片字段进行范围查找时,连续分片可快速定位分片进行快速查询,有效避免跨分片查询的问题")])])]),s._v(" "),a("li",[s._v("缺点:\n"),a("ul",[a("li",[s._v("热点数据成为性能瓶颈。连续分片可能存在数据热点")])])])]),s._v(" "),a("p",[a("strong",[s._v("HASH取模MOD的切分方式")])]),s._v(" "),a("ul",[a("li",[s._v("优点:根据主键id进行数据切分,达到数据均匀分布,使用一致性hash算法可以避免后期扩展问题")]),s._v(" "),a("li",[s._v("缺点:跨分片聚合操")])]),s._v(" "),a("h3",{attrs:{id:"参考文献"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#参考文献"}},[s._v("#")]),s._v(" 参考文献")]),s._v(" "),a("ul",[a("li",[a("strong",[a("a",{attrs:{href:"http://blog.codinglabs.org/articles/theory-of-mysql-index.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("MySQL索引的数据结构以及算法原理"),a("OutboundLink")],1)])]),s._v(" "),a("li",[a("strong",[a("a",{attrs:{href:"https://blog.csdn.net/codingtu/article/details/84038530",target:"_blank",rel:"noopener noreferrer"}},[s._v("MySQL基本原理和使用技巧"),a("OutboundLink")],1)])]),s._v(" "),a("li",[a("strong",[a("a",{attrs:{href:"http://dev.mysql.com/doc/refman/5.1/zh/index.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("MySQL5.1参考手册"),a("OutboundLink")],1)])])])],1)}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/23.d22a11cb.js b/assets/js/23.d22a11cb.js deleted file mode 100644 index 990affc..0000000 --- a/assets/js/23.d22a11cb.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{265:function(t,a,s){"use strict";s.r(a);var e=s(2),r=Object(e.a)({},(function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"mysql"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mysql"}},[t._v("#")]),t._v(" MySQL")]),t._v(" "),s("p",[t._v("MySQL是一个关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性")]),t._v(" "),s("h2",{attrs:{id:"基础架构"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#基础架构"}},[t._v("#")]),t._v(" 基础架构")]),t._v(" "),s("img",{attrs:{src:t.$withBase("/db/mysql/mysql-01.png"),alt:"foo"}}),t._v(" "),s("h3",{attrs:{id:"连接器管理"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#连接器管理"}},[t._v("#")]),t._v(" 连接器管理")]),t._v(" "),s("ul",[s("li",[t._v("长连接:连接成功后,如果客户端持续有请求,则一直使用同一个连接")]),t._v(" "),s("li",[t._v("短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个")])]),t._v(" "),s("p",[t._v("链接的建立过程复杂,操作中如果需要大量长时间的存取数据,使用长链接\n使用长链接的缺点:\n容易占用内存, 因为MySQL在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM)")]),t._v(" "),s("p",[t._v("解决长连接占用内存,短链接繁琐的问题")]),t._v(" "),s("ol",[s("li",[t._v("定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。")]),t._v(" "),s("li",[t._v("如果你用的是MySQL 5.7或更新版本,可以在每次执行一个比较大的操作后,通过执行"),s("code",[t._v("mysql_reset_connection")]),t._v("来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。")])]),t._v(" "),s("h3",{attrs:{id:"mysql缓存"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mysql缓存"}},[t._v("#")]),t._v(" Mysql缓存")]),t._v(" "),s("p",[t._v("Mysql通过在内存中建立"),s("code",[t._v("缓冲区[buffer]")]),t._v("和"),s("code",[t._v("缓寸[cache]")]),t._v("来提高Mysql性能,key是查询的语句,value是查询的结果,对于InnoDB引擎,Mysql采用"),s("code",[t._v("缓冲池[buffer pool]")]),t._v("的方式来缓存数据和索引,对于MyISAM引擎,Mysql采用缓存的方式来缓存数据和索引,先看缓存数据,如果存在则直接返回。如果没有则直接往下走")]),t._v(" "),s("ul",[s("li",[t._v("关键字缓存(key cache)\n"),s("ul",[s("li",[t._v("当Mysql收到传入的sql语句时,它首先和先前已经解析过的sql语句进行比较,如果发现相同,则返回已缓存数据。一定是完全相同,因此MySQL的查询缓存命中率很低")])])]),t._v(" "),s("li",[t._v("查询缓存(query cache)")])]),t._v(" "),s("div",{staticClass:"language-sql extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sql"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("SHOW")]),t._v(" variables "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("LIKE")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'have_query_cache'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 查询mysql缓存配置信息")]),t._v("\n")])])]),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),s("p",[t._v("对于一些不常改变的数据且有大量相同sql查询的表,查询缓存会节约很大的性能,对于频繁更改的表,查询缓存是不合适的")])]),t._v(" "),s("h3",{attrs:{id:"分析器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#分析器"}},[t._v("#")]),t._v(" 分析器")]),t._v(" "),s("p",[t._v("分析器对你执行的sql语句进行解析,首先是词法分析包括一些关键字识别,然后语法分析,查看这条语句是否符合mysql语句")]),t._v(" "),s("p",[t._v("分析器分析识别")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("词法分析")]),t._v("(识别关键字):\n输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别出里面的字符串分别是什么,代表什么。\nMySQL从你输入的"),s("code",[t._v("SELECT")]),t._v('这个关键字识别出来,这是一个查询语句。它也要把字符串"T"识别成"表名T",把字符串"ID"识别成"列ID"')]),t._v(" "),s("li",[s("strong",[t._v("语法分析")]),t._v(" (判断语法):\n根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法\n如果语法不对,就会收到报错提醒,一般语法错误会提示第一个出现错误的位置\n即关注报错中的 "),s("code",[t._v("user near")])])]),t._v(" "),s("h3",{attrs:{id:"优化器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#优化器"}},[t._v("#")]),t._v(" 优化器")]),t._v(" "),s("p",[t._v("经过分析器的分析,Mysql就知道你要做的事情是什么了,但是,在开始执行之前,需要经过优化器的处理。发现那些查询命中索引,还有表之间的连接顺序等")]),t._v(" "),s("p",[t._v("优化器是在表里面有多个索引的时候,决定使用哪个索引。或者在一个语句有多表关联"),s("code",[t._v("JOIN")]),t._v("的时候,决定各个表的连接顺序。比如你执行下面这样的语句,这个语句是执行两个表的"),s("code",[t._v("JOIN")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-sql extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sql"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("SELECT")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("FROM")]),t._v(" T1 "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("JOIN")]),t._v(" T2 "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("USING")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("WHERE")]),t._v(" T1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("AND")]),t._v(" T2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("d"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面d的值是否等于20。")]),t._v(" "),s("li",[t._v("也可以先从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面c的值是否等于10。\n这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案")])]),t._v(" "),s("h3",{attrs:{id:"执行器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#执行器"}},[t._v("#")]),t._v(" 执行器")]),t._v(" "),s("p",[t._v("通过上面一系列的验证,使用引擎提供的接口。经过不断的执行将查询的结果存放在结果集中,通过"),s("code",[t._v("EXPLAIN")]),t._v("可以看到执行器具体扫描了多少行。")]),t._v(" "),s("p",[t._v("经过优化器筛选优化的查询语句后,就进入执行器阶段,开始执行语句")]),t._v(" "),s("p",[t._v("开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示。")]),t._v(" "),s("div",{staticClass:"language-sql extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sql"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("SELECT")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("FROM")]),t._v(" T "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("WHERE")]),t._v(" ID"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'")]),t._v("\n")])])]),s("p",[t._v("如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。")]),t._v(" "),s("p",[t._v("比如我们这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:")]),t._v(" "),s("ol",[s("li",[t._v("调用InnoDB引擎接口取这个表的第一行,判断ID值是不是10,如果不是则跳过,如果是则将这行存在结果集中;")]),t._v(" "),s("li",[t._v("调用引擎接口取"),s("code",[t._v("下一行")]),t._v(",重复相同的判断逻辑,直到取到这个表的最后一行。")]),t._v(" "),s("li",[t._v("执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。")])]),t._v(" "),s("p",[t._v("至此,这个语句就执行完成了")]),t._v(" "),s("p",[t._v('对于有索引的表,执行的逻辑也差不多第一次调用的是"取满足条件的第一行"这个接口,之后循环取"满足条件的下一行"这个接口,这些接口都是引擎中已经定义好的。\n你会在数据库的慢查询日志中看到一个'),s("code",[t._v("rows_examined")]),t._v("的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。")]),t._v(" "),s("p",[t._v("在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟"),s("code",[t._v("rows_examined")]),t._v("并不是完全相同的")]),t._v(" "),s("h3",{attrs:{id:"日志系统"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#日志系统"}},[t._v("#")]),t._v(" 日志系统")]),t._v(" "),s("p",[t._v("首先要清楚redolog和binlog两个日志模块")]),t._v(" "),s("ol",[s("li",[t._v("redolog(InnoDB特有的日志模块,起初InnoDB是另一个公司以插件的方式加到mysql的,拥有"),s("strong",[t._v("crash-safe")]),t._v("故障恢复能力) 重做日志文件,用于记录事务操作的变化,记录修改后的值,不管事务是否提交。保证数据的完整性。其中redolog是固定大小的,是从头开始写,写到末尾在从头开始。同时会有两个指针,一个记录写入的位置,一个标记,当前擦除的位置,不断的循环。整个过程称为crash-safe。即时数据库异常,也会有记录")]),t._v(" "),s("li",[t._v("binlog 归档日志文件,用于记录对mysql数据库执行更改的所有操作。binlog是追加写,不会覆盖之前的。")])]),t._v(" "),s("p",[t._v("MySQL InnoDB 更新一条语句的流程")]),t._v(" "),s("div",{staticClass:"language-sql extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sql"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("UPDATE")]),t._v(" user_info "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("SET")]),t._v(" name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"marco"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("WHERE")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",[s("li",[t._v("执行器先找引擎取出ID=1这一行,ID是主键,引擎直接用树搜索找到这一行,如果本来这一行所在的数据页就在内存中,就直接返回给执行器")]),t._v(" "),s("li",[t._v("执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新一行数据,再调用引擎接口写入这行新数据")]),t._v(" "),s("li",[t._v("引擎将这行新数据更新到内存中,同时将这个更新记录到redolog里面,此时redolog处于prepare状态,然后告知执行器执行任务完成了,随时可以提交事务")]),t._v(" "),s("li",[t._v("执行器生成这个操作的binlog,并把binlog卸乳磁盘")]),t._v(" "),s("li",[t._v("执行器调用引擎的提交事务接口,引擎把刚刚卸乳的redolog改为提交commit状态,更新完成")])]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),s("p",[t._v("注意:Mysql的redolog模块写入拆成2步走,prepare和commit,称为两阶段提交。\n"),s("strong",[t._v("1.redolog的prepare状态 2. binlog的写入")])])]),t._v(" "),s("p",[t._v("如果binlog没有写入并没有提交事务回滚\n如果binlog写入事务没提交,数据库回复后自动完成commit")]),t._v(" "),s("h2",{attrs:{id:"数据结构"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数据结构"}},[t._v("#")]),t._v(" 数据结构")]),t._v(" "),s("p",[t._v("数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优,MySQL官方对索引的定义为:"),s("u",[s("b",[t._v("索引(Index)")]),t._v("是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构")])]),t._v(" "),s("h3",{attrs:{id:"b树、b-树、b-树"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#b树、b-树、b-树"}},[t._v("#")]),t._v(" B树、B-树、B+树")]),t._v(" "),s("p",[t._v("目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构")]),t._v(" "),s("h4",{attrs:{id:"b-树-即二叉搜索树"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#b-树-即二叉搜索树"}},[t._v("#")]),t._v(" B 树 "),s("code",[t._v("即二叉搜索树")])]),t._v(" "),s("center",[s("img",{staticStyle:{display:"left"},attrs:{src:t.$withBase("/db/mysql/mysql-03.jpg"),alt:"foo"}})]),t._v(" "),s("ol",[s("li",[t._v("所有非叶子结点至多拥有两个儿子(Left和Right)")]),t._v(" "),s("li",[t._v("所有结点存储一个关键字;")]),t._v(" "),s("li",[t._v("非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;\n"),s("center",[s("img",{attrs:{src:t.$withBase("/db/mysql/mysql-04.jpg"),alt:"foo"}})])],1)]),t._v(" "),s("p",[t._v("B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;")]),t._v(" "),s("p",[t._v("如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;")]),t._v(" "),s("center",[s("img",{attrs:{src:t.$withBase("/db/mysql/mysql-05.jpg"),alt:"foo"}}),t._v(" "),s("p",[t._v(" 但B树在经过多次插入与删除后,有可能导致不同的结构")])]),t._v(" "),s("p",[t._v("右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题;"),s("br"),t._v("\n实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略;")]),t._v(" "),s("h4",{attrs:{id:"b-tree-一种多路搜索树(并不是二叉的)"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#b-tree-一种多路搜索树(并不是二叉的)"}},[t._v("#")]),t._v(" B- Tree "),s("code",[t._v("一种多路搜索树(并不是二叉的)")])]),t._v(" "),s("center",[s("img",{attrs:{src:t.$withBase("/db/mysql/mysql-06.jpg"),alt:"foo"}})]),t._v(" "),s("p",[t._v("B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;")]),t._v(" "),s("ol",[s("li",[t._v("关键字集合分布在整颗树中;")]),t._v(" "),s("li",[t._v("任何一个关键字出现且只出现在一个结点中;")]),t._v(" "),s("li",[t._v("搜索有可能在非叶子结点结束;")]),t._v(" "),s("li",[t._v("其搜索性能等价于在关键字全集内做一次二分查找;")]),t._v(" "),s("li",[t._v("自动层次控制;")])]),t._v(" "),s("p",[t._v("由于B-Tree的特性,在B-Tree中按key检索数据的算法非常直观:"),s("strong",[t._v("首先从根节点进行二分查找,如果找到则返回对应节点的data,否则对相应区间的指针指向的节点递归进行查找,直到找到节点或找到null指针,前者查找成功,后者查找失败")])]),t._v(" "),s("h4",{attrs:{id:"b-tree-b-树的变体,也是一种多路搜索树"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#b-tree-b-树的变体,也是一种多路搜索树"}},[t._v("#")]),t._v(" B+ Tree "),s("code",[t._v("B-树的变体,也是一种多路搜索树")])]),t._v(" "),s("center",[s("img",{attrs:{src:t.$withBase("/db/mysql/mysql-07.jpg"),alt:"foo"}})]),t._v(" "),s("p",[t._v("B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找")]),t._v(" "),s("ol",[s("li",[t._v("其定义基本与B-树同,除了:")]),t._v(" "),s("li",[t._v("非叶子结点的子树指针与关键字个数相同;")]),t._v(" "),s("li",[t._v("非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);")]),t._v(" "),s("li",[t._v("为所有叶子结点增加一个链指针;")]),t._v(" "),s("li",[t._v("所有关键字都在叶子结点出现;")])]),t._v(" "),s("p",[t._v("一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。")]),t._v(" "),s("h3",{attrs:{id:"磁盘存取原理"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#磁盘存取原理"}},[t._v("#")]),t._v(" 磁盘存取原理")]),t._v(" "),s("div",{staticStyle:{float:"left"}},[s("img",{attrs:{src:t.$withBase("/db/mysql/mysql-02.jpg"),alt:"foo"}})]),t._v(" "),s("p",[t._v("一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动(各个磁盘必须同步转动)。在磁盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不能转动,但是可以沿磁盘半径方向运动(实际是斜切向运动),每个磁头同一时刻也必须是同轴的,即从正上方向下看,所有磁头任何时候都是重叠的(不过目前已经有多磁头独立技术,可不受此限制)。")]),t._v(" "),s("p",[t._v("盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存\n储单元。")]),t._v(" "),s("p",[t._v("当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做"),s("strong",[t._v("寻道时间")]),t._v(",然后磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做"),s("strong",[t._v("旋转时间")]),t._v("。")]),t._v(" "),s("p",[t._v("局部性原理与磁盘预读\n由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。")]),t._v(" "),s("p",[t._v("这样做的理论依据是计算机科学中著名的"),s("strong",[t._v("局部性原理")]),t._v(":当一个数据被用到时,其附近的数据也通常会马上被使用。\n程序运行期间所需要的数据通常比较集中。")]),t._v(" "),s("p",[s("u",[t._v("由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。")])]),t._v(" "),s("p",[t._v("预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。")]),t._v(" "),s("p",[t._v("数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:\n每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。\nB-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为"),s("code",[t._v("O(h)=O(logdN)")])]),t._v(" "),s("p",[t._v("一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。综上所述,用B-Tree作为索引结构效率是非常高的。而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。")]),t._v(" "),s("h3",{attrs:{id:"myisam-索引实现"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#myisam-索引实现"}},[t._v("#")]),t._v(" MyISAM 索引实现")]),t._v(" "),s("p",[t._v("MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。")]),t._v(" "),s("p",[t._v("MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分")]),t._v(" "),s("h3",{attrs:{id:"innodb-索引实现"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#innodb-索引实现"}},[t._v("#")]),t._v(" InnoDB 索引实现")]),t._v(" "),s("p",[t._v("虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。")]),t._v(" "),s("ol",[s("li",[t._v("InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。")]),t._v(" "),s("li",[t._v("与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域\nInnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择")])]),t._v(" "),s("h2",{attrs:{id:"锁机制"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#锁机制"}},[t._v("#")]),t._v(" 锁机制")]),t._v(" "),s("h2",{attrs:{id:"隔离级别"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#隔离级别"}},[t._v("#")]),t._v(" 隔离级别")]),t._v(" "),s("h2",{attrs:{id:"mvcc"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mvcc"}},[t._v("#")]),t._v(" MVCC")]),t._v(" "),s("h2",{attrs:{id:"innodb"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#innodb"}},[t._v("#")]),t._v(" InnoDB")]),t._v(" "),s("h2",{attrs:{id:"explain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#explain"}},[t._v("#")]),t._v(" Explain")]),t._v(" "),s("h3",{attrs:{id:"参考文献"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#参考文献"}},[t._v("#")]),t._v(" 参考文献")]),t._v(" "),s("ul",[s("li",[s("strong",[s("a",{attrs:{href:"http://blog.codinglabs.org/articles/theory-of-mysql-index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("MySQL索引的数据结构以及算法原理"),s("OutboundLink")],1)])]),t._v(" "),s("li",[s("strong",[s("a",{attrs:{href:"https://blog.csdn.net/codingtu/article/details/84038530",target:"_blank",rel:"noopener noreferrer"}},[t._v("MySQL基本原理和使用技巧"),s("OutboundLink")],1)])]),t._v(" "),s("li",[s("strong",[s("a",{attrs:{href:"http://dev.mysql.com/doc/refman/5.1/zh/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("MySQL5.1参考手册"),s("OutboundLink")],1)])])])],1)}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/app.317b3400.js b/assets/js/app.de81a621.js similarity index 85% rename from assets/js/app.317b3400.js rename to assets/js/app.de81a621.js index f19d49c..6603eee 100644 --- a/assets/js/app.317b3400.js +++ b/assets/js/app.de81a621.js @@ -1,4 +1,4 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var r,a,s=e[0],c=e[1],u=e[2],f=0,p=[];f-1}function i(t,e){return e instanceof t||e&&(e.name===t.name||e._name===t._name)}function a(t,e){for(var n in e)t[n]=e[n];return t}var s={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render:function(t,e){var n=e.props,r=e.children,o=e.parent,i=e.data;i.routerView=!0;for(var s=o.$createElement,u=n.name,l=o.$route,f=o._routerViewCache||(o._routerViewCache={}),p=0,d=!1;o&&o._routerRoot!==o;){var h=o.$vnode?o.$vnode.data:{};h.routerView&&p++,h.keepAlive&&o._directInactive&&o._inactive&&(d=!0),o=o.$parent}if(i.routerViewDepth=p,d){var v=f[u],m=v&&v.component;return m?(v.configProps&&c(m,i,v.route,v.configProps),s(m,i,r)):s()}var y=l.matched[p],g=y&&y.components[u];if(!y||!g)return f[u]=null,s();f[u]={component:g},i.registerRouteInstance=function(t,e){var n=y.instances[u];(e&&n!==t||!e&&n===t)&&(y.instances[u]=e)},(i.hook||(i.hook={})).prepatch=function(t,e){y.instances[u]=e.componentInstance},i.hook.init=function(t){t.data.keepAlive&&t.componentInstance&&t.componentInstance!==y.instances[u]&&(y.instances[u]=t.componentInstance)};var b=y.props&&y.props[u];return b&&(a(f[u],{route:l,configProps:b}),c(g,i,l,b)),s(g,i,r)}};function c(t,e,n,r){var o=e.props=function(t,e){switch(typeof e){case"undefined":return;case"object":return e;case"function":return e(t);case"boolean":return e?t.params:void 0;default:0}}(n,r);if(o){o=e.props=a({},o);var i=e.attrs=e.attrs||{};for(var s in o)t.props&&s in t.props||(i[s]=o[s],delete o[s])}}var u=/[!'()*]/g,l=function(t){return"%"+t.charCodeAt(0).toString(16)},f=/%2C/g,p=function(t){return encodeURIComponent(t).replace(u,l).replace(f,",")},d=decodeURIComponent;function h(t){var e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach((function(t){var n=t.replace(/\+/g," ").split("="),r=d(n.shift()),o=n.length>0?d(n.join("=")):null;void 0===e[r]?e[r]=o:Array.isArray(e[r])?e[r].push(o):e[r]=[e[r],o]})),e):e}function v(t){var e=t?Object.keys(t).map((function(e){var n=t[e];if(void 0===n)return"";if(null===n)return p(e);if(Array.isArray(n)){var r=[];return n.forEach((function(t){void 0!==t&&(null===t?r.push(p(e)):r.push(p(e)+"="+p(t)))})),r.join("&")}return p(e)+"="+p(n)})).filter((function(t){return t.length>0})).join("&"):null;return e?"?"+e:""}var m=/\/?$/;function y(t,e,n,r){var o=r&&r.options.stringifyQuery,i=e.query||{};try{i=g(i)}catch(t){}var a={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:w(e,o),matched:t?_(t):[]};return n&&(a.redirectedFrom=w(n,o)),Object.freeze(a)}function g(t){if(Array.isArray(t))return t.map(g);if(t&&"object"==typeof t){var e={};for(var n in t)e[n]=g(t[n]);return e}return t}var b=y(null,{path:"/"});function _(t){for(var e=[];t;)e.unshift(t),t=t.parent;return e}function w(t,e){var n=t.path,r=t.query;void 0===r&&(r={});var o=t.hash;return void 0===o&&(o=""),(n||"/")+(e||v)(r)+o}function x(t,e){return e===b?t===e:!!e&&(t.path&&e.path?t.path.replace(m,"")===e.path.replace(m,"")&&t.hash===e.hash&&O(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&O(t.query,e.query)&&O(t.params,e.params)))}function O(t,e){if(void 0===t&&(t={}),void 0===e&&(e={}),!t||!e)return t===e;var n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every((function(n){var r=t[n],o=e[n];return"object"==typeof r&&"object"==typeof o?O(r,o):String(r)===String(o)}))}function k(t,e,n){var r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;var o=e.split("/");n&&o[o.length-1]||o.pop();for(var i=t.replace(/^\//,"").split("/"),a=0;a=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),l=e&&e.path||"/",f=u.path?k(u.path,l,n||o.append):l,p=function(t,e,n){void 0===e&&(e={});var r,o=n||h;try{r=o(t||"")}catch(t){r={}}for(var i in e)r[i]=e[i];return r}(u.query,o.query,r&&r.options.parseQuery),d=o.hash||u.hash;return d&&"#"!==d.charAt(0)&&(d="#"+d),{_normalized:!0,path:f,query:p,hash:d}}var q,W=function(){},G={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,s=o.route,c=o.href,u={},l=n.options.linkActiveClass,f=n.options.linkExactActiveClass,p=null==l?"router-link-active":l,d=null==f?"router-link-exact-active":f,h=null==this.activeClass?p:this.activeClass,v=null==this.exactActiveClass?d:this.exactActiveClass,g=s.redirectedFrom?y(null,V(s.redirectedFrom),null,n):s;u[v]=x(r,g),u[h]=this.exact?u[v]:function(t,e){return 0===t.path.replace(m,"/").indexOf(e.path.replace(m,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,g);var b=function(t){X(t)&&(e.replace?n.replace(i,W):n.push(i,W))},_={click:X};Array.isArray(this.event)?this.event.forEach((function(t){_[t]=b})):_[this.event]=b;var w={class:u},O=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:s,navigate:b,isActive:u[h],isExactActive:u[v]});if(O){if(1===O.length)return O[0];if(O.length>1||!O.length)return 0===O.length?t():t("span",{},O)}if("a"===this.tag)w.on=_,w.attrs={href:c};else{var k=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=H(l.path,s.params),c(l,s,a)}if(s.path){s.params={};for(var d=0;d=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function bt(t){return function(e,n,r){var i=!1,a=0,s=null;_t(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){i=!0,a++;var u,l=Ot((function(e){var o;((o=e).__esModule||xt&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:q.extend(e),n.components[c]=e,--a<=0&&r()})),f=Ot((function(t){var e="Failed to resolve async component "+c+": "+t;s||(s=o(t)?t:new Error(e),r(s))}));try{u=t(l,f)}catch(t){f(t)}if(u)if("function"==typeof u.then)u.then(l,f);else{var p=u.component;p&&"function"==typeof p.then&&p.then(l,f)}}})),i||r()}}function _t(t,e){return wt(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function wt(t){return Array.prototype.concat.apply([],t)}var xt="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ot(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var kt=function(t){function e(e){t.call(this),this.name=this._name="NavigationDuplicated",this.message='Navigating to current location ("'+e.fullPath+'") is not allowed',Object.defineProperty(this,"stack",{value:(new t).stack,writable:!0,configurable:!0})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Error);kt._name="NavigationDuplicated";var Ct=function(t,e){this.router=t,this.base=function(t){if(!t)if(Y){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=b,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};function St(t,e,n,r){var o=_t(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=q.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return wt(r?o.reverse():o)}function Et(t,e){if(e)return function(){return t.apply(e,arguments)}}Ct.prototype.listen=function(t){this.cb=t},Ct.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Ct.prototype.onError=function(t){this.errorCbs.push(t)},Ct.prototype.transitionTo=function(t,e,n){var r=this,o=this.router.match(t,this.current);this.confirmTransition(o,(function(){r.updateRoute(o),e&&e(o),r.ensureURL(),r.ready||(r.ready=!0,r.readyCbs.forEach((function(t){t(o)})))}),(function(t){n&&n(t),t&&!r.ready&&(r.ready=!0,r.readyErrorCbs.forEach((function(e){e(t)})))}))},Ct.prototype.confirmTransition=function(t,e,n){var r=this,a=this.current,s=function(t){!i(kt,t)&&o(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)};if(x(t,a)&&t.matched.length===a.matched.length)return this.ensureURL(),s(new kt(t));var c=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n-1?decodeURI(t.slice(0,r))+t.slice(r):decodeURI(t)}else t=decodeURI(t.slice(0,n))+t.slice(n);return t}function Pt(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Lt(t){vt?mt(Pt(t)):window.location.hash=t}function Mt(t){vt?yt(Pt(t)):window.location.replace(Pt(t))}var It=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){e.index=n,e.updateRoute(r)}),(function(t){i(kt,t)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Ct),Rt=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Z(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!vt&&!1!==t.fallback,this.fallback&&(e="hash"),Y||(e="abstract"),this.mode=e,e){case"history":this.history=new At(this,t.base);break;case"hash":this.history=new jt(this,t.base,this.fallback);break;case"abstract":this.history=new It(this,t.base);break;default:0}},Nt={currentRoute:{configurable:!0}};function Dt(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Rt.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},Nt.currentRoute.get=function(){return this.history&&this.history.current},Rt.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null)})),!this.app){this.app=t;var n=this.history;if(n instanceof At)n.transitionTo(n.getCurrentLocation());else if(n instanceof jt){var r=function(){n.setupListeners()};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Rt.prototype.beforeEach=function(t){return Dt(this.beforeHooks,t)},Rt.prototype.beforeResolve=function(t){return Dt(this.resolveHooks,t)},Rt.prototype.afterEach=function(t){return Dt(this.afterHooks,t)},Rt.prototype.onReady=function(t,e){this.history.onReady(t,e)},Rt.prototype.onError=function(t){this.history.onError(t)},Rt.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},Rt.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},Rt.prototype.go=function(t){this.history.go(t)},Rt.prototype.back=function(){this.go(-1)},Rt.prototype.forward=function(){this.go(1)},Rt.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Rt.prototype.resolve=function(t,e,n){var r=V(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?C(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},Rt.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==b&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Rt.prototype,Nt),Rt.install=function t(e){if(!t.installed||q!==e){t.installed=!0,q=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",s),e.component("RouterLink",G);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Rt.version="3.1.5",Y&&window.Vue&&window.Vue.use(Rt);var Ft=Rt;var Ut=n(1),Bt={created(){this.$ssrContext&&(this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.description=this.$page.description||this.$description)},mounted(){this.currentMetaTags=new Set,this.updateMeta()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.$page.frontmatter.meta||[],e=t.slice(0);0===t.filter(t=>"description"===t.name).length&&e.push({name:"description",content:this.$description});const n=document.querySelectorAll('meta[name="description"]');n.length&&n.forEach(t=>this.currentMetaTags.add(t)),this.currentMetaTags=new Set(Ht(e,this.currentMetaTags))}},watch:{$page(){this.updateMeta()}},beforeDestroy(){Ht(null,this.currentMetaTags)}};function Ht(t,e){if(e&&[...e].forEach(t=>{document.head.removeChild(t)}),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}var Vt=n(29),qt=n.n(Vt),Wt={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:qt()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Gt=n(30),Xt=n.n(Gt),Yt={mounted(){Xt.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||r.a.component(t.name)||Xt.a.start(),n()}),this.$router.afterEach(()=>{Xt.a.done(),this.isSidebarOpen=!1})}},Kt=n(78),Qt=n.n(Kt),Zt={mounted(){Qt.a.polyfill()}},Jt=(n(97),Object.assign||function(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:{},r=window.Promise||function(t){function e(){}t(e,e)},o=function(t){var e=t.target;e!==C?-1!==b.indexOf(e)&&v({target:e}):h()},i=function(){if(!w&&k.original){var t=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(x-t)>O.scrollOffset&&setTimeout(h,150)}},a=function(t){var e=t.key||t.keyCode;"Escape"!==e&&"Esc"!==e&&27!==e||h()},s=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t;if(t.background&&(C.style.background=t.background),t.container&&t.container instanceof Object&&(e.container=Jt({},O.container,t.container)),t.template){var n=ee(t.template)?t.template:document.querySelector(t.template);e.template=n}return O=Jt({},O,e),b.forEach((function(t){t.dispatchEvent(ae("medium-zoom:update",{detail:{zoom:S}}))})),S},c=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return t(Jt({},O,e))},u=function(){for(var t=arguments.length,e=Array(t),n=0;n0?e.reduce((function(t,e){return[].concat(t,re(e))}),[]):b;return r.forEach((function(t){t.classList.remove("medium-zoom-image"),t.dispatchEvent(ae("medium-zoom:detach",{detail:{zoom:S}}))})),b=b.filter((function(t){return-1===r.indexOf(t)})),S},f=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(r){r.addEventListener("medium-zoom:"+t,e,n)})),_.push({type:"medium-zoom:"+t,listener:e,options:n}),S},p=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(r){r.removeEventListener("medium-zoom:"+t,e,n)})),_=_.filter((function(n){return!(n.type==="medium-zoom:"+t&&n.listener.toString()===e.toString())})),S},d=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target,n=function(){var t={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},e=void 0,n=void 0;if(O.container)if(O.container instanceof Object)e=(t=Jt({},t,O.container)).width-t.left-t.right-2*O.margin,n=t.height-t.top-t.bottom-2*O.margin;else{var r=(ee(O.container)?O.container:document.querySelector(O.container)).getBoundingClientRect(),o=r.width,i=r.height,a=r.left,s=r.top;t=Jt({},t,{width:o,height:i,left:a,top:s})}e=e||t.width-2*O.margin,n=n||t.height-2*O.margin;var c=k.zoomedHd||k.original,u=ne(c)?e:c.naturalWidth||e,l=ne(c)?n:c.naturalHeight||n,f=c.getBoundingClientRect(),p=f.top,d=f.left,h=f.width,v=f.height,m=Math.min(u,e)/h,y=Math.min(l,n)/v,g=Math.min(m,y),b="scale("+g+") translate3d("+((e-h)/2-d+O.margin+t.left)/g+"px, "+((n-v)/2-p+O.margin+t.top)/g+"px, 0)";k.zoomed.style.transform=b,k.zoomedHd&&(k.zoomedHd.style.transform=b)};return new r((function(t){if(e&&-1===b.indexOf(e))t(S);else{if(k.zoomed)t(S);else{if(e)k.original=e;else{if(!(b.length>0))return void t(S);var r=b;k.original=r[0]}if(k.original.dispatchEvent(ae("medium-zoom:open",{detail:{zoom:S}})),x=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,w=!0,k.zoomed=ie(k.original),document.body.appendChild(C),O.template){var o=ee(O.template)?O.template:document.querySelector(O.template);k.template=document.createElement("div"),k.template.appendChild(o.content.cloneNode(!0)),document.body.appendChild(k.template)}if(document.body.appendChild(k.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),k.original.classList.add("medium-zoom-image--hidden"),k.zoomed.classList.add("medium-zoom-image--opened"),k.zoomed.addEventListener("click",h),k.zoomed.addEventListener("transitionend",(function e(){w=!1,k.zoomed.removeEventListener("transitionend",e),k.original.dispatchEvent(ae("medium-zoom:opened",{detail:{zoom:S}})),t(S)})),k.original.getAttribute("data-zoom-src")){k.zoomedHd=k.zoomed.cloneNode(),k.zoomedHd.removeAttribute("srcset"),k.zoomedHd.removeAttribute("sizes"),k.zoomedHd.src=k.zoomed.getAttribute("data-zoom-src"),k.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+k.zoomedHd.src),k.zoomedHd=null,n()};var i=setInterval((function(){k.zoomedHd.complete&&(clearInterval(i),k.zoomedHd.classList.add("medium-zoom-image--opened"),k.zoomedHd.addEventListener("click",h),document.body.appendChild(k.zoomedHd),n())}),10)}else if(k.original.hasAttribute("srcset")){k.zoomedHd=k.zoomed.cloneNode(),k.zoomedHd.removeAttribute("sizes");var a=k.zoomedHd.addEventListener("load",(function(){k.zoomedHd.removeEventListener("load",a),k.zoomedHd.classList.add("medium-zoom-image--opened"),k.zoomedHd.addEventListener("click",h),document.body.appendChild(k.zoomedHd),n()}))}else n()}}}))},h=function(){return new r((function(t){if(!w&&k.original){w=!0,document.body.classList.remove("medium-zoom--opened"),k.zoomed.style.transform="",k.zoomedHd&&(k.zoomedHd.style.transform=""),k.template&&(k.template.style.transition="opacity 150ms",k.template.style.opacity=0),k.original.dispatchEvent(ae("medium-zoom:close",{detail:{zoom:S}})),k.zoomed.addEventListener("transitionend",(function e(){k.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(k.zoomed),k.zoomedHd&&document.body.removeChild(k.zoomedHd),document.body.removeChild(C),k.zoomed.classList.remove("medium-zoom-image--opened"),k.template&&document.body.removeChild(k.template),w=!1,k.zoomed.removeEventListener("transitionend",e),k.original.dispatchEvent(ae("medium-zoom:closed",{detail:{zoom:S}})),k.original=null,k.zoomed=null,k.zoomedHd=null,k.template=null,t(S)}))}else t(S)}))},v=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target;return k.original?h():d({target:e})},m=function(){return O},y=function(){return b},g=function(){return k.original},b=[],_=[],w=!1,x=0,O=n,k={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(e)?O=e:(e||"string"==typeof e)&&u(e),O=Jt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},O);var C=oe(O.background);document.addEventListener("click",o),document.addEventListener("keyup",a),document.addEventListener("scroll",i),window.addEventListener("resize",h);var S={open:d,close:h,toggle:v,update:s,clone:c,attach:u,detach:l,on:f,off:p,getOptions:m,getImages:y,getZoomedImage:g};return S},ce=[Bt,Wt,Yt,Zt,{data:()=>({zoom:null}),mounted(){this.updateZoom()},updated(){this.updateZoom()},methods:{updateZoom(){setTimeout(()=>{this.zoom&&this.zoom.detach(),this.zoom=se(".theme-default-content :not(a) > img",void 0)},1e3)}}}],ue={name:"GlobalLayout",computed:{layout:function(){var t=this.getLayout();return Object(Ut.h)("layout",t),r.a.component(t)}},methods:{getLayout:function(){if(this.$page.path){var t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},le=n(2),fe=Object(le.a)(ue,(function(){var t=this.$createElement;return(this._self._c||t)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;Object(Ut.f)(fe,"mixins",ce);var pe=[{name:"v-746bd11e",path:"/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-746bd11e").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-5ba934e1",path:"/zh/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-5ba934e1").then(n)}},{path:"/zh/index.html",redirect:"/zh/"},{name:"v-74d01bde",path:"/zh/db/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-74d01bde").then(n)}},{path:"/zh/db/index.html",redirect:"/zh/db/"},{name:"v-58cebc34",path:"/zh/db/clickhouse.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-58cebc34").then(n)}},{name:"v-dbd7ec2c",path:"/zh/db/hbase.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-dbd7ec2c").then(n)}},{name:"v-94740eec",path:"/zh/db/mongodb.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-94740eec").then(n)}},{name:"v-5559350a",path:"/zh/db/mysql.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-5559350a").then(n)}},{name:"v-0a8a5aec",path:"/zh/db/neo4j.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-0a8a5aec").then(n)}},{name:"v-fc0c3ca4",path:"/zh/db/postgreSQL.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-fc0c3ca4").then(n)}},{name:"v-f82d23ac",path:"/zh/db/redis.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-f82d23ac").then(n)}},{name:"v-16372753",path:"/zh/devops/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-16372753").then(n)}},{path:"/zh/devops/index.html",redirect:"/zh/devops/"},{name:"v-793e68e1",path:"/zh/distributed/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-793e68e1").then(n)}},{path:"/zh/distributed/index.html",redirect:"/zh/distributed/"},{name:"v-5cfbe97e",path:"/zh/guide/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-5cfbe97e").then(n)}},{path:"/zh/guide/index.html",redirect:"/zh/guide/"},{name:"v-accb5676",path:"/zh/os/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-accb5676").then(n)}},{path:"/zh/os/index.html",redirect:"/zh/os/"},{name:"v-728e1cec",path:"/zh/os/coroutines.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-728e1cec").then(n)}},{name:"v-d2c24fec",path:"/zh/os/cpu.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-d2c24fec").then(n)}},{name:"v-173c9516",path:"/zh/os/io.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-173c9516").then(n)}},{name:"v-3d7c27ec",path:"/zh/os/linux.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-3d7c27ec").then(n)}},{name:"v-77f2e22a",path:"/zh/os/process.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-77f2e22a").then(n)}},{name:"v-d505af64",path:"/zh/os/thread.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-d505af64").then(n)}},{name:"v-4db484c1",path:"/zh/program/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-4db484c1").then(n)}},{path:"/zh/program/index.html",redirect:"/zh/program/"},{name:"v-6c1827f0",path:"/zh/program/c.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-6c1827f0").then(n)}},{name:"v-775f4f8a",path:"/zh/program/golang.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-775f4f8a").then(n)}},{name:"v-3ca656aa",path:"/zh/program/javascript.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-3ca656aa").then(n)}},{name:"v-a9d38bc4",path:"/zh/program/php.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-a9d38bc4").then(n)}},{name:"v-3bd307ca",path:"/zh/program/python.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-3bd307ca").then(n)}},{path:"*",component:fe}],de={title:"",description:"",base:"/",pages:[{title:"Home",frontmatter:{home:!0,heroImage:"/hero.png",actionText:"快速上手 →",footer:"MIT Licensed | Copyright © 2020 Marco"},regularPath:"/",relativePath:"README.md",key:"v-746bd11e",path:"/",lastUpdated:"2/28/2020, 6:33:35 AM"},{title:"Home",frontmatter:{home:!0,heroImage:"/hero.png",actionText:"快速上手 →",actionLink:"/zh/guide/",features:[{title:"简洁至上",details:"以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。"}],footer:"MIT Licensed | Copyright © 2020-PRESENT Marco"},regularPath:"/zh/",relativePath:"zh/README.md",key:"v-5ba934e1",path:"/zh/",lastUpdated:"2/15/2020, 9:48:35 AM"},{title:"数据库 🔎",frontmatter:{},regularPath:"/zh/db/",relativePath:"zh/db/README.md",key:"v-74d01bde",path:"/zh/db/",headers:[{level:2,title:"数据库概述",slug:"数据库概述"},{level:2,title:"附录",slug:"附录"}],lastUpdated:"3/1/2020, 11:29:42 PM"},{title:"Clickhouse",frontmatter:{},regularPath:"/zh/db/clickhouse.html",relativePath:"zh/db/clickhouse.md",key:"v-58cebc34",path:"/zh/db/clickhouse.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"HBase",frontmatter:{},regularPath:"/zh/db/hbase.html",relativePath:"zh/db/hbase.md",key:"v-dbd7ec2c",path:"/zh/db/hbase.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"MongoDB",frontmatter:{},regularPath:"/zh/db/mongodb.html",relativePath:"zh/db/mongodb.md",key:"v-94740eec",path:"/zh/db/mongodb.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"MySQL",frontmatter:{},regularPath:"/zh/db/mysql.html",relativePath:"zh/db/mysql.md",key:"v-5559350a",path:"/zh/db/mysql.html",headers:[{level:2,title:"基础架构",slug:"基础架构"},{level:3,title:"连接器管理",slug:"连接器管理"},{level:3,title:"Mysql缓存",slug:"mysql缓存"},{level:3,title:"分析器",slug:"分析器"},{level:3,title:"优化器",slug:"优化器"},{level:3,title:"执行器",slug:"执行器"},{level:3,title:"日志系统",slug:"日志系统"},{level:2,title:"数据结构",slug:"数据结构"},{level:3,title:"B树、B-树、B+树",slug:"b树、b-树、b-树"},{level:3,title:"磁盘存取原理",slug:"磁盘存取原理"},{level:3,title:"MyISAM 索引实现",slug:"myisam-索引实现"},{level:3,title:"InnoDB 索引实现",slug:"innodb-索引实现"},{level:2,title:"锁机制",slug:"锁机制"},{level:2,title:"隔离级别",slug:"隔离级别"},{level:2,title:"MVCC",slug:"mvcc"},{level:2,title:"InnoDB",slug:"innodb"},{level:2,title:"Explain",slug:"explain"},{level:3,title:"参考文献",slug:"参考文献"}],lastUpdated:"2/16/2020, 4:43:13 PM"},{title:"Neo4J",frontmatter:{},regularPath:"/zh/db/neo4j.html",relativePath:"zh/db/neo4j.md",key:"v-0a8a5aec",path:"/zh/db/neo4j.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"PostgreSQL",frontmatter:{},regularPath:"/zh/db/postgreSQL.html",relativePath:"zh/db/postgreSQL.md",key:"v-fc0c3ca4",path:"/zh/db/postgreSQL.html",headers:[{level:2,title:"初始化",slug:"初始化"},{level:3,title:"数学关系",slug:"数学关系"},{level:3,title:"准备环境",slug:"准备环境"},{level:3,title:"从SQL开始",slug:"从sql开始"},{level:2,title:"体系结构",slug:"体系结构"},{level:2,title:"MVCC",slug:"mvcc"}],lastUpdated:"3/1/2020, 11:29:42 PM"},{title:"Redis",frontmatter:{},regularPath:"/zh/db/redis.html",relativePath:"zh/db/redis.md",key:"v-f82d23ac",path:"/zh/db/redis.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{frontmatter:{},regularPath:"/zh/devops/",relativePath:"zh/devops/README.md",key:"v-16372753",path:"/zh/devops/",lastUpdated:"2/15/2020, 11:02:54 AM"},{frontmatter:{},regularPath:"/zh/distributed/",relativePath:"zh/distributed/README.md",key:"v-793e68e1",path:"/zh/distributed/",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"要怎样努力,才能成为很厉害的人",frontmatter:{},regularPath:"/zh/guide/",relativePath:"zh/guide/README.md",key:"v-5cfbe97e",path:"/zh/guide/",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"操作系统",frontmatter:{},regularPath:"/zh/os/",relativePath:"zh/os/README.md",key:"v-accb5676",path:"/zh/os/",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"协程",frontmatter:{},regularPath:"/zh/os/coroutines.html",relativePath:"zh/os/coroutines.md",key:"v-728e1cec",path:"/zh/os/coroutines.html",lastUpdated:"2/24/2020, 2:21:13 PM"},{title:"CPU",frontmatter:{},regularPath:"/zh/os/cpu.html",relativePath:"zh/os/cpu.md",key:"v-d2c24fec",path:"/zh/os/cpu.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"IO",frontmatter:{},regularPath:"/zh/os/io.html",relativePath:"zh/os/io.md",key:"v-173c9516",path:"/zh/os/io.html",headers:[{level:2,title:"概念",slug:"概念"},{level:3,title:"用户态切换到内核态",slug:"用户态切换到内核态"},{level:3,title:"进程的结构-PCB",slug:"进程的结构-pcb"},{level:3,title:"进程切换",slug:"进程切换"},{level:3,title:"创建进程",slug:"创建进程"},{level:3,title:"进程的阻塞",slug:"进程的阻塞"},{level:3,title:"同步与异步",slug:"同步与异步"},{level:3,title:"同步与异步的区别",slug:"同步与异步的区别"},{level:3,title:"阻塞与非阻塞",slug:"阻塞与非阻塞"},{level:3,title:"文件描述符 fd",slug:"文件描述符-fd"},{level:2,title:"缓存 I/O",slug:"缓存-i-o"},{level:2,title:"网络 I/O",slug:"网络-i-o"},{level:2,title:"IO模式",slug:"io模式"},{level:2,title:"阻塞 I/O",slug:"阻塞-i-o"},{level:3,title:"非阻塞 I/O",slug:"非阻塞-i-o"},{level:3,title:"同步非阻塞与同步阻塞之间有什么优缺点呢?",slug:"同步非阻塞与同步阻塞之间有什么优缺点呢?"},{level:2,title:"I/O 多路复用",slug:"i-o-多路复用"},{level:3,title:"poll",slug:"poll"},{level:3,title:"epoll",slug:"epoll"},{level:3,title:"实现原理",slug:"实现原理"},{level:2,title:"信号驱动 I/O",slug:"信号驱动-i-o"},{level:2,title:"异步 I/O",slug:"异步-i-o"},{level:3,title:"小结",slug:"小结"},{level:2,title:"IO设计模式",slug:"io设计模式"},{level:3,title:"传统IO设计模式",slug:"传统io设计模式"},{level:3,title:"多线程模式",slug:"多线程模式"},{level:3,title:"线程池模式",slug:"线程池模式"},{level:3,title:"高性能IO设计模式",slug:"高性能io设计模式"},{level:3,title:"Reactor",slug:"reactor"},{level:3,title:"Proactor",slug:"proactor"}],lastUpdated:"2/25/2020, 7:09:44 AM"},{title:"LINUX",frontmatter:{},regularPath:"/zh/os/linux.html",relativePath:"zh/os/linux.md",key:"v-3d7c27ec",path:"/zh/os/linux.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"进程",frontmatter:{},regularPath:"/zh/os/process.html",relativePath:"zh/os/process.md",key:"v-77f2e22a",path:"/zh/os/process.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"线程",frontmatter:{},regularPath:"/zh/os/thread.html",relativePath:"zh/os/thread.md",key:"v-d505af64",path:"/zh/os/thread.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"编译型语言",frontmatter:{},regularPath:"/zh/program/",relativePath:"zh/program/README.md",key:"v-4db484c1",path:"/zh/program/",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"C",frontmatter:{},regularPath:"/zh/program/c.html",relativePath:"zh/program/c.md",key:"v-6c1827f0",path:"/zh/program/c.html",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"Golang",frontmatter:{},regularPath:"/zh/program/golang.html",relativePath:"zh/program/golang.md",key:"v-775f4f8a",path:"/zh/program/golang.html",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"JavaScript",frontmatter:{},regularPath:"/zh/program/javascript.html",relativePath:"zh/program/javascript.md",key:"v-3ca656aa",path:"/zh/program/javascript.html",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"PHP",frontmatter:{},regularPath:"/zh/program/php.html",relativePath:"zh/program/php.md",key:"v-a9d38bc4",path:"/zh/program/php.html",headers:[{level:2,title:"源码整体框架",slug:"源码整体框架"},{level:2,title:"执行原理概述",slug:"执行原理概述"},{level:2,title:"Zend 虚拟机",slug:"zend-虚拟机"},{level:3,title:"符号表",slug:"符号表"},{level:3,title:"指令",slug:"指令"},{level:2,title:"生命周期",slug:"生命周期"},{level:3,title:"SAPI",slug:"sapi"},{level:2,title:"内存管理",slug:"内存管理"},{level:2,title:"垃圾回收",slug:"垃圾回收"},{level:3,title:"垃圾的产生",slug:"垃圾的产生"},{level:3,title:"回收过程",slug:"回收过程"},{level:3,title:"垃圾收集的内部实现",slug:"垃圾收集的内部实现"},{level:2,title:"扩展的构成及编译",slug:"扩展的构成及编译"},{level:3,title:"扩展的构成",slug:"扩展的构成"},{level:3,title:"编译工具",slug:"编译工具"},{level:3,title:"php-config",slug:"php-config"},{level:3,title:"编写扩展的基本步骤",slug:"编写扩展的基本步骤"},{level:3,title:"config.m4",slug:"config-m4"}],lastUpdated:"2/24/2020, 2:14:52 AM"},{title:"Python",frontmatter:{},regularPath:"/zh/program/python.html",relativePath:"zh/program/python.md",key:"v-3bd307ca",path:"/zh/program/python.html",lastUpdated:"2/22/2020, 6:07:07 PM"}],themeConfig:{repo:"m9rco/practice",docsRepo:"m9-lab/m9-lab.github.io",docsBranch:"master",editLinks:!0,docsDir:"docs",algolia:{apiKey:"17103d809d3df489f3e1de21aaa02b48",indexName:"practice"},smoothScroll:!0,locales:{"/":{label:"简体中文",selectText:"选择语言",ariaLabel:"选择语言",editLinkText:"在 GitHub 上编辑此页",lastUpdated:"上次更新",nav:[{text:"指南",link:"/zh/guide/"},{text:"数据库",link:"/zh/db/"},{text:"操作系统",link:"/zh/os/"},{text:"编程语言",link:"/zh/program/"},{text:"分布式设计",link:"/zh/distributed/"},{text:"DevOPS",link:"/zh/devops/"},{text:"通用基础",ariaLabel:"通用基础",items:[{text:"算法 & 数据结构",items:[{text:"数据结构",link:"/zh/structures-algorithm/structures.html"},{text:"基本算法",link:"/zh/structures-algorithm/algorithm.html"},{text:"Leetcode",link:"/zh/leetcode/"}]},{text:"网络安全",items:[{text:"WEB 安全",link:"/zh/structures-algorithm/structures.html"},{text:"服务器安全",link:"/zh/structures-algorithm/algorithm.html"},{text:"序列化漏洞",link:"/zh/structures-algorithm/algorithm.html"},{text:"加密解密",link:"/zh/structures-algorithm/algorithm.html"},{text:"网络隔离",link:"/zh/structures-algorithm/algorithm.html"}]},{text:"设计思路",items:[{text:"并发问题",link:"/zh/structures-algorithm/structures.html"},{text:"限流熔断",link:"/zh/structures-algorithm/algorithm.html"},{text:"海量搜索",link:"/zh/structures-algorithm/algorithm.html"}]}]}],sidebar:{"/zh/guide/":[{title:"指南",collapsable:!1,children:[""]}],"/zh/db/":[{title:"关系型数据库",collapsable:!1,children:["mysql","postgreSQL"]},{title:"键-值数据库",collapsable:!1,children:["redis"]},{title:"列数据库",collapsable:!1,children:["hbase","clickhouse"]},{title:"文档型数据库",collapsable:!1,children:["mongodb"]},{title:"图数据库",collapsable:!1,children:["neo4j"]}],"/zh/os/":[{title:"操作系统",collapsable:!1,children:["io","cpu","thread","coroutines","process"]},{title:"计算机原理",collapsable:!1,children:["linux"]}],"/zh/program/":[{title:"解释型语言",collapsable:!1,children:["php","python","javascript"]},{title:"编译型语言",collapsable:!1,children:["golang","c"]}]}},"/en":{label:"English",selectText:"Languages",ariaLabel:"Select language",editLinkText:"Edit this page on GitHub",lastUpdated:"Last Updated",nav:[{text:"Guide",link:"/guide/"},{text:"Config Reference",link:"/config/"},{text:"Plugin",link:"/plugin/"},{text:"Theme",link:"/theme/"},{text:"0.x",link:"https://v0.vuepress.vuejs.org/"}],sidebar:{}}}},locales:{"/":{lang:"zh-CN",title:"笃行",description:"笃行致远,不负芳华",path:"/"},"/en/":{lang:"English",title:"Practice",description:"The back-end architects self practice",path:"/en/"}}};function he(t){var e=document.createElement("link");e.href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css",e.rel="stylesheet",document.body.appendChild(e);var n=document.createElement("script");function r(t){var e=document.getElementById("gitalk-container");e||((e=document.createElement("div")).id="gitalk-container",e.classList.add("content"));var n=document.querySelector(".page-nav");n&&(n.appendChild(e),"undefined"!=typeof Gitalk&&Gitalk instanceof Function&&(t.fullPath,new Gitalk({clientID:"5e01d05713fb81675776",clientSecret:"599d38643f2c2fb15438c137f345a03fcb244b50",repo:"practice",owner:"m9rco",admin:["m9rco"],id:location.pathname,distractionFreeMode:!1,language:"zh-CN"}).render("gitalk-container")))}n.src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js",document.body.appendChild(n),t.afterEach((function(t){n.onload?r(t):n.onload=function(){r(t)}}))}n(98);r.a.component("Bit",(function(){return Promise.all([n.e(0),n.e(6)]).then(n.bind(null,285))})),r.a.component("Comment",(function(){return n.e(11).then(n.bind(null,256))})),r.a.component("OtherComponent",(function(){return n.e(13).then(n.bind(null,286))})),r.a.component("UpgradePath",(function(){return Promise.all([n.e(0),n.e(7)]).then(n.bind(null,287))})),r.a.component("demo-1",(function(){return n.e(14).then(n.bind(null,257))})),r.a.component("diagram-markdown-slot-relationship",(function(){return n.e(15).then(n.bind(null,288))})),r.a.component("svg-container",(function(){return Promise.all([n.e(0),n.e(8)]).then(n.bind(null,289))})),r.a.component("Foo-Bar",(function(){return n.e(12).then(n.bind(null,258))})),r.a.component("Badge",(function(){return Promise.all([n.e(0),n.e(10)]).then(n.bind(null,290))}));n(99),n(100);function ve(t){const e=document.documentElement.getBoundingClientRect(),n=t.getBoundingClientRect();return{x:n.left-e.left,y:n.top-e.top}}n(101);var me={name:"BackToTop",props:{threshold:{type:Number,default:300}},data:function(){return{scrollTop:null}},computed:{show:function(){return this.scrollTop>this.threshold}},mounted:function(){var t=this;this.scrollTop=this.getScrollTop(),window.addEventListener("scroll",qt()((function(){t.scrollTop=t.getScrollTop()}),100))},methods:{getScrollTop:function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"}),this.scrollTop=0}}},ye=(n(110),Object(le.a)(me,(function(){var t=this.$createElement,e=this._self._c||t;return e("transition",{attrs:{name:"fade"}},[this.show?e("svg",{staticClass:"go-to-top",attrs:{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 49.484 28.284"},on:{click:this.scrollToTop}},[e("g",{attrs:{transform:"translate(-229 -126.358)"}},[e("rect",{attrs:{fill:"currentColor",width:"35",height:"5",rx:"2",transform:"translate(229 151.107) rotate(-45)"}}),this._v(" "),e("rect",{attrs:{fill:"currentColor",width:"35",height:"5",rx:"2",transform:"translate(274.949 154.642) rotate(-135)"}})])]):this._e()])}),[],!1,null,"5fd4ef0c",null).exports);function ge(t,e){void 0===e&&(e={});var n=e.registrationOptions;void 0===n&&(n={}),delete e.registrationOptions;var r=function(t){for(var n=[],r=arguments.length-1;r-- >0;)n[r]=arguments[r+1];e&&e[t]&&e[t].apply(e,n)};"serviceWorker"in navigator&&window.addEventListener("load",(function(){Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/))?(!function(t,e,n){fetch(t).then((function(r){404===r.status?(e("error",new Error("Service worker not found at "+t)),_e()):-1===r.headers.get("content-type").indexOf("javascript")?(e("error",new Error("Expected "+t+" to have javascript content-type, but received "+r.headers.get("content-type"))),_e()):be(t,e,n)})).catch((function(t){navigator.onLine?e("error",t):e("offline")}))}(t,r,n),navigator.serviceWorker.ready.then((function(t){r("ready",t)}))):be(t,r,n)}))}function be(t,e,n){navigator.serviceWorker.register(t,n).then((function(t){e("registered",t),t.waiting?e("updated",t):t.onupdatefound=function(){e("updatefound",t);var n=t.installing;n.onstatechange=function(){"installed"===n.state&&(navigator.serviceWorker.controller?e("updated",t):e("cached",t))}}})).catch((function(t){e("error",t)}))}function _e(){"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((function(t){t.unregister()}))}class we{constructor(t){Object.defineProperty(this,"registration",{value:t,configurable:!0,writable:!0})}update(){return this.registration.update()}skipWaiting(){const t=this.registration.waiting;return t?(console.log("[vuepress:sw] Doing worker.skipWaiting()."),new Promise((e,n)=>{const r=new MessageChannel;r.port1.onmessage=t=>{console.log("[vuepress:sw] Done worker.skipWaiting()."),t.data.error?n(t.data.error):e(t.data)},t.postMessage({type:"skip-waiting"},[r.port2])})):Promise.resolve()}}var xe=n(12);r.a.component("SWUpdatePopup",()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,254)));var Oe=n(77),ke=(n(81),n(91),Object(le.a)({},(function(){var t=this.$createElement,e=this._self._c||t;return e("svg",{staticStyle:{"enable-background":"new 0 0 50 50"},attrs:{xmlns:"http://www.w3.org/2000/svg",x:"0px",y:"0px",viewBox:"0 0 30 30"}},[e("rect",{attrs:{x:"0",y:"13",width:"4",height:"5"}},[e("animate",{attrs:{attributeName:"height",attributeType:"XML",values:"5;21;5",begin:"0s",dur:"0.6s",repeatCount:"indefinite"}}),this._v(" "),e("animate",{attrs:{attributeName:"y",attributeType:"XML",values:"13; 5; 13",begin:"0s",dur:"0.6s",repeatCount:"indefinite"}})]),this._v(" "),e("rect",{attrs:{x:"10",y:"13",width:"4",height:"5"}},[e("animate",{attrs:{attributeName:"height",attributeType:"XML",values:"5;21;5",begin:"0.15s",dur:"0.6s",repeatCount:"indefinite"}}),this._v(" "),e("animate",{attrs:{attributeName:"y",attributeType:"XML",values:"13; 5; 13",begin:"0.15s",dur:"0.6s",repeatCount:"indefinite"}})]),this._v(" "),e("rect",{attrs:{x:"20",y:"13",width:"4",height:"5"}},[e("animate",{attrs:{attributeName:"height",attributeType:"XML",values:"5;21;5",begin:"0.3s",dur:"0.6s",repeatCount:"indefinite"}}),this._v(" "),e("animate",{attrs:{attributeName:"y",attributeType:"XML",values:"13; 5; 13",begin:"0.3s",dur:"0.6s",repeatCount:"indefinite"}})])])}),[],!1,null,null,null).exports),Ce={x:0,y:0,"line-width":2,"line-length":50,"text-margin":10,"font-size":14,"font-color":"#8DA1AC","line-color":"#8DA1AC","element-color":"black",fill:"white","yes-text":"yes","no-text":"no","arrow-end":"block",scale:1},Se={ant:Object.assign({},Ce,{symbols:{start:{class:"start-element","font-color":"white",fill:"#595959","line-width":"0px"},end:{class:"end-element","font-color":"white",fill:"#595959","line-width":"0px"},operation:{class:"operation-element","font-color":"white",fill:"#1890ff","line-width":"0px"},inputoutput:{class:"inputoutput-element","font-color":"white",fill:"#1890ff","line-width":"0px"},subroutine:{class:"subroutine-element","font-color":"white",fill:"#FF485E","element-color":"#fff","line-color":"red"},condition:{class:"condition-element","font-color":"white",fill:"#FF485E","line-width":"0px"},parallel:{class:"parallel-element","font-color":"white",fill:"#1890ff","line-width":"0px"}}}),vue:Object.assign({},Ce,{symbols:{start:{class:"start-element","font-color":"white",fill:"#2F495F","line-width":"0px"},end:{class:"end-element","font-color":"white",fill:"#2F495F","line-width":"0px"},operation:{class:"operation-element","font-color":"white",fill:"#00BC7D","line-width":"0px"},inputoutput:{class:"inputoutput-element","font-color":"white",fill:"#EB4D5D","line-width":"0px"},subroutine:{class:"subroutine-element","font-color":"white",fill:"#937AC4","element-color":"#fff","line-color":"red"},condition:{class:"condition-element","font-color":"white",fill:"#FFB500","line-width":"0px"},parallel:{class:"parallel-element","font-color":"white",fill:"#2F495F","line-width":"0px"}}})},Ee={name:"flowchart",components:{Loading:ke},props:{id:{type:String,required:!0},code:{type:String,required:!0},preset:{type:String,default:"vue"}},data:function(){return{loading:!0}},mounted:function(){var t=this,e=Se[this.preset];if(e){var r=this.code;this.$el.setAttribute("id",this.id);Promise.all([n.e(3).then(n.t.bind(null,250,7)),new Promise((function(t){return setTimeout(t,500)}))]).then((function(n){(0,Object(Oe.a)(n,1)[0].default.parse)(r).drawSVG(t.id,e),t.loading=!1}))}else console.warn("[vuepress-plugin-flowchart] Unknown preset: ".concat(this.preset))}},Ae=(n(140),Object(le.a)(Ee,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"vuepress-flowchart",class:{loading:this.loading}},[this.loading?e("Loading",{staticClass:"vuepress-flowchart-loading-icon"}):this._e()],1)}),[],!1,null,null,null).exports),$e=[function(t){var e=t.Vue,r=t.isServer,o=t.router;try{document&&he(o)}catch(t){console.error(t.message)}r||n.e(4).then(n.t.bind(null,249,7)).then((function(t){e.use(t.default)}))},{},function(t){t.Vue.mixin({computed:{$dataBlock:function(){return this.$options.__data__block__}}})},{},{},({Vue:t,router:e})=>{e.options.scrollBehavior=(e,n,r)=>{if(r)return window.scrollTo({top:r.y,behavior:"smooth"});if(e.hash){if(t.$vuepress.$get("disableScrollBehavior"))return!1;const n=document.querySelector(e.hash);return!!n&&window.scrollTo({top:ve(n).y,behavior:"smooth"})}return window.scrollTo({top:0,behavior:"smooth"})}},({Vue:t})=>{t.component("BackToTop",ye)},({router:t,isServer:e})=>{t.onReady(()=>{e||ge("/service-worker.js",{registrationOptions:{},ready(){console.log("[vuepress:sw] Service worker is active."),xe.a.$emit("sw-ready")},cached(t){console.log("[vuepress:sw] Content has been cached for offline use."),xe.a.$emit("sw-cached",new we(t))},updated(t){console.log("[vuepress:sw] Content updated."),xe.a.$emit("sw-updated",new we(t))},offline(){console.log("[vuepress:sw] No internet connection found. App is running in offline mode."),xe.a.$emit("sw-offline")},error(t){console.error("[vuepress:sw] Error during service worker registration:",t),xe.a.$emit("sw-error",t),ga("send","exception",{exDescription:t.message,exFatal:!1})}})})},({router:t})=>{var e,n,r,o,i,a;"undefined"!=typeof window&&(e=window,n=document,r="script",o="ga",e.GoogleAnalyticsObject=o,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,i=n.createElement(r),a=n.getElementsByTagName(r)[0],i.async=1,i.src="https://www.google-analytics.com/analytics.js",a.parentNode.insertBefore(i,a),ga("create","UA-158536766-1","auto"),ga("set","anonymizeIp",!0),t.afterEach((function(t){ga("set","page",t.fullPath),ga("send","pageview")})))},function(t){const{Vue:e}=t;e.component("FlowChart",Ae)}],je=["BackToTop"];n(141),n(93),n(95);var Te=n(80),ze=n.n(Te);function Pe(t,e){for(var n=0;nt.path.toLowerCase()===e.toLowerCase()).length>0}var Re={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return Object(Ut.h)("pageKey",e),r.a.component(e)||r.a.component(e,Object(Ut.d)(e)),r.a.component(e)?t(e):t("")}},Ne={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:[`content__${e.slotKey}`]},n()[e.slotKey])},De=(n(146),Object(le.a)({},(function(t,e){var n=e._c;return n("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[n("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),e._v(" "),n("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})])}),[],!0,null,null,null).exports),Fe={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};r.a.config.productionTip=!1,r.a.use(Ft),r.a.use(Me),r.a.mixin(function(t,e,n=r.a){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const o=new(t(n.$vuepress.$get("siteData"))),i=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(o)),a={};return Object.keys(i).reduce((t,e)=>(e.startsWith("$")&&(t[e]=i[e].get),t),a),{computed:a}}((function(t){return function(){function e(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e)}var n,r,o;return n=e,(r=[{key:"setPage",value:function(t){this.__page=t}},{key:"$site",get:function(){return t}},{key:"$themeConfig",get:function(){return this.$site.themeConfig}},{key:"$frontmatter",get:function(){return this.$page.frontmatter}},{key:"$localeConfig",get:function(){var t,e,n=this.$site.locales,r=void 0===n?{}:n;for(var o in r)"/"===o?e=r[o]:0===this.$page.path.indexOf(o)&&(t=r[o]);return t||e||{}}},{key:"$siteTitle",get:function(){return this.$localeConfig.title||this.$site.title||""}},{key:"$title",get:function(){var t=this.$page,e=this.$page.frontmatter.metaTitle;if("string"==typeof e)return e;var n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}},{key:"$description",get:function(){var t=function(t){if(t){var e=t.filter((function(t){return"description"===t.name}))[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||""}},{key:"$lang",get:function(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}},{key:"$localePath",get:function(){return this.$localeConfig.path||"/"}},{key:"$themeLocaleConfig",get:function(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}},{key:"$page",get:function(){return this.__page?this.__page:function(t,e){for(var n=0;nn||(t.hash?!r.a.$vuepress.$get("disableScrollBehavior")&&{selector:t.hash}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Ie(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Ie(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Ie(t,o)?r(o):Ie(t,n)?r(n):r()}})}(n);const o={};try{$e.forEach(e=>{"function"==typeof e&&e({Vue:r.a,options:o,router:n,siteData:de,isServer:t})})}catch(t){console.error(t)}return{app:new r.a(Object.assign(o,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},je.map(e=>t(e)))])})),router:n}}(!1);window.__VUEPRESS__={version:"1.3.0",hash:"29055b8"},Be.onReady(()=>{Ue.$mount("#app")})}]); \ No newline at end of file + */function o(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function i(t,e){return e instanceof t||e&&(e.name===t.name||e._name===t._name)}function a(t,e){for(var n in e)t[n]=e[n];return t}var s={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render:function(t,e){var n=e.props,r=e.children,o=e.parent,i=e.data;i.routerView=!0;for(var s=o.$createElement,u=n.name,l=o.$route,f=o._routerViewCache||(o._routerViewCache={}),p=0,d=!1;o&&o._routerRoot!==o;){var h=o.$vnode?o.$vnode.data:{};h.routerView&&p++,h.keepAlive&&o._directInactive&&o._inactive&&(d=!0),o=o.$parent}if(i.routerViewDepth=p,d){var v=f[u],m=v&&v.component;return m?(v.configProps&&c(m,i,v.route,v.configProps),s(m,i,r)):s()}var y=l.matched[p],g=y&&y.components[u];if(!y||!g)return f[u]=null,s();f[u]={component:g},i.registerRouteInstance=function(t,e){var n=y.instances[u];(e&&n!==t||!e&&n===t)&&(y.instances[u]=e)},(i.hook||(i.hook={})).prepatch=function(t,e){y.instances[u]=e.componentInstance},i.hook.init=function(t){t.data.keepAlive&&t.componentInstance&&t.componentInstance!==y.instances[u]&&(y.instances[u]=t.componentInstance)};var b=y.props&&y.props[u];return b&&(a(f[u],{route:l,configProps:b}),c(g,i,l,b)),s(g,i,r)}};function c(t,e,n,r){var o=e.props=function(t,e){switch(typeof e){case"undefined":return;case"object":return e;case"function":return e(t);case"boolean":return e?t.params:void 0;default:0}}(n,r);if(o){o=e.props=a({},o);var i=e.attrs=e.attrs||{};for(var s in o)t.props&&s in t.props||(i[s]=o[s],delete o[s])}}var u=/[!'()*]/g,l=function(t){return"%"+t.charCodeAt(0).toString(16)},f=/%2C/g,p=function(t){return encodeURIComponent(t).replace(u,l).replace(f,",")},d=decodeURIComponent;function h(t){var e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach((function(t){var n=t.replace(/\+/g," ").split("="),r=d(n.shift()),o=n.length>0?d(n.join("=")):null;void 0===e[r]?e[r]=o:Array.isArray(e[r])?e[r].push(o):e[r]=[e[r],o]})),e):e}function v(t){var e=t?Object.keys(t).map((function(e){var n=t[e];if(void 0===n)return"";if(null===n)return p(e);if(Array.isArray(n)){var r=[];return n.forEach((function(t){void 0!==t&&(null===t?r.push(p(e)):r.push(p(e)+"="+p(t)))})),r.join("&")}return p(e)+"="+p(n)})).filter((function(t){return t.length>0})).join("&"):null;return e?"?"+e:""}var m=/\/?$/;function y(t,e,n,r){var o=r&&r.options.stringifyQuery,i=e.query||{};try{i=g(i)}catch(t){}var a={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:w(e,o),matched:t?_(t):[]};return n&&(a.redirectedFrom=w(n,o)),Object.freeze(a)}function g(t){if(Array.isArray(t))return t.map(g);if(t&&"object"==typeof t){var e={};for(var n in t)e[n]=g(t[n]);return e}return t}var b=y(null,{path:"/"});function _(t){for(var e=[];t;)e.unshift(t),t=t.parent;return e}function w(t,e){var n=t.path,r=t.query;void 0===r&&(r={});var o=t.hash;return void 0===o&&(o=""),(n||"/")+(e||v)(r)+o}function x(t,e){return e===b?t===e:!!e&&(t.path&&e.path?t.path.replace(m,"")===e.path.replace(m,"")&&t.hash===e.hash&&O(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&O(t.query,e.query)&&O(t.params,e.params)))}function O(t,e){if(void 0===t&&(t={}),void 0===e&&(e={}),!t||!e)return t===e;var n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every((function(n){var r=t[n],o=e[n];return"object"==typeof r&&"object"==typeof o?O(r,o):String(r)===String(o)}))}function k(t,e,n){var r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;var o=e.split("/");n&&o[o.length-1]||o.pop();for(var i=t.replace(/^\//,"").split("/"),a=0;a=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),l=e&&e.path||"/",f=u.path?k(u.path,l,n||o.append):l,p=function(t,e,n){void 0===e&&(e={});var r,o=n||h;try{r=o(t||"")}catch(t){r={}}for(var i in e)r[i]=e[i];return r}(u.query,o.query,r&&r.options.parseQuery),d=o.hash||u.hash;return d&&"#"!==d.charAt(0)&&(d="#"+d),{_normalized:!0,path:f,query:p,hash:d}}var q,W=function(){},G={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,s=o.route,c=o.href,u={},l=n.options.linkActiveClass,f=n.options.linkExactActiveClass,p=null==l?"router-link-active":l,d=null==f?"router-link-exact-active":f,h=null==this.activeClass?p:this.activeClass,v=null==this.exactActiveClass?d:this.exactActiveClass,g=s.redirectedFrom?y(null,V(s.redirectedFrom),null,n):s;u[v]=x(r,g),u[h]=this.exact?u[v]:function(t,e){return 0===t.path.replace(m,"/").indexOf(e.path.replace(m,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,g);var b=function(t){X(t)&&(e.replace?n.replace(i,W):n.push(i,W))},_={click:X};Array.isArray(this.event)?this.event.forEach((function(t){_[t]=b})):_[this.event]=b;var w={class:u},O=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:s,navigate:b,isActive:u[h],isExactActive:u[v]});if(O){if(1===O.length)return O[0];if(O.length>1||!O.length)return 0===O.length?t():t("span",{},O)}if("a"===this.tag)w.on=_,w.attrs={href:c};else{var k=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=H(l.path,s.params),c(l,s,a)}if(s.path){s.params={};for(var d=0;d=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function bt(t){return function(e,n,r){var i=!1,a=0,s=null;_t(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){i=!0,a++;var u,l=Ot((function(e){var o;((o=e).__esModule||xt&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:q.extend(e),n.components[c]=e,--a<=0&&r()})),f=Ot((function(t){var e="Failed to resolve async component "+c+": "+t;s||(s=o(t)?t:new Error(e),r(s))}));try{u=t(l,f)}catch(t){f(t)}if(u)if("function"==typeof u.then)u.then(l,f);else{var p=u.component;p&&"function"==typeof p.then&&p.then(l,f)}}})),i||r()}}function _t(t,e){return wt(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function wt(t){return Array.prototype.concat.apply([],t)}var xt="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ot(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var kt=function(t){function e(e){t.call(this),this.name=this._name="NavigationDuplicated",this.message='Navigating to current location ("'+e.fullPath+'") is not allowed',Object.defineProperty(this,"stack",{value:(new t).stack,writable:!0,configurable:!0})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Error);kt._name="NavigationDuplicated";var Ct=function(t,e){this.router=t,this.base=function(t){if(!t)if(Y){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=b,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};function St(t,e,n,r){var o=_t(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=q.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return wt(r?o.reverse():o)}function Et(t,e){if(e)return function(){return t.apply(e,arguments)}}Ct.prototype.listen=function(t){this.cb=t},Ct.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Ct.prototype.onError=function(t){this.errorCbs.push(t)},Ct.prototype.transitionTo=function(t,e,n){var r=this,o=this.router.match(t,this.current);this.confirmTransition(o,(function(){r.updateRoute(o),e&&e(o),r.ensureURL(),r.ready||(r.ready=!0,r.readyCbs.forEach((function(t){t(o)})))}),(function(t){n&&n(t),t&&!r.ready&&(r.ready=!0,r.readyErrorCbs.forEach((function(e){e(t)})))}))},Ct.prototype.confirmTransition=function(t,e,n){var r=this,a=this.current,s=function(t){!i(kt,t)&&o(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)};if(x(t,a)&&t.matched.length===a.matched.length)return this.ensureURL(),s(new kt(t));var c=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n-1?decodeURI(t.slice(0,r))+t.slice(r):decodeURI(t)}else t=decodeURI(t.slice(0,n))+t.slice(n);return t}function Pt(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Lt(t){vt?mt(Pt(t)):window.location.hash=t}function Mt(t){vt?yt(Pt(t)):window.location.replace(Pt(t))}var It=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){e.index=n,e.updateRoute(r)}),(function(t){i(kt,t)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Ct),Rt=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Z(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!vt&&!1!==t.fallback,this.fallback&&(e="hash"),Y||(e="abstract"),this.mode=e,e){case"history":this.history=new At(this,t.base);break;case"hash":this.history=new jt(this,t.base,this.fallback);break;case"abstract":this.history=new It(this,t.base);break;default:0}},Nt={currentRoute:{configurable:!0}};function Dt(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Rt.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},Nt.currentRoute.get=function(){return this.history&&this.history.current},Rt.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null)})),!this.app){this.app=t;var n=this.history;if(n instanceof At)n.transitionTo(n.getCurrentLocation());else if(n instanceof jt){var r=function(){n.setupListeners()};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Rt.prototype.beforeEach=function(t){return Dt(this.beforeHooks,t)},Rt.prototype.beforeResolve=function(t){return Dt(this.resolveHooks,t)},Rt.prototype.afterEach=function(t){return Dt(this.afterHooks,t)},Rt.prototype.onReady=function(t,e){this.history.onReady(t,e)},Rt.prototype.onError=function(t){this.history.onError(t)},Rt.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},Rt.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},Rt.prototype.go=function(t){this.history.go(t)},Rt.prototype.back=function(){this.go(-1)},Rt.prototype.forward=function(){this.go(1)},Rt.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Rt.prototype.resolve=function(t,e,n){var r=V(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?C(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},Rt.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==b&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Rt.prototype,Nt),Rt.install=function t(e){if(!t.installed||q!==e){t.installed=!0,q=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",s),e.component("RouterLink",G);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Rt.version="3.1.5",Y&&window.Vue&&window.Vue.use(Rt);var Ft=Rt;var Ut=n(1),Bt={created(){this.$ssrContext&&(this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.description=this.$page.description||this.$description)},mounted(){this.currentMetaTags=new Set,this.updateMeta()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.$page.frontmatter.meta||[],e=t.slice(0);0===t.filter(t=>"description"===t.name).length&&e.push({name:"description",content:this.$description});const n=document.querySelectorAll('meta[name="description"]');n.length&&n.forEach(t=>this.currentMetaTags.add(t)),this.currentMetaTags=new Set(Ht(e,this.currentMetaTags))}},watch:{$page(){this.updateMeta()}},beforeDestroy(){Ht(null,this.currentMetaTags)}};function Ht(t,e){if(e&&[...e].forEach(t=>{document.head.removeChild(t)}),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}var Vt=n(29),qt=n.n(Vt),Wt={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:qt()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Gt=n(30),Xt=n.n(Gt),Yt={mounted(){Xt.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||r.a.component(t.name)||Xt.a.start(),n()}),this.$router.afterEach(()=>{Xt.a.done(),this.isSidebarOpen=!1})}},Kt=n(78),Qt=n.n(Kt),Zt={mounted(){Qt.a.polyfill()}},Jt=(n(97),Object.assign||function(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:{},r=window.Promise||function(t){function e(){}t(e,e)},o=function(t){var e=t.target;e!==C?-1!==b.indexOf(e)&&v({target:e}):h()},i=function(){if(!w&&k.original){var t=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(x-t)>O.scrollOffset&&setTimeout(h,150)}},a=function(t){var e=t.key||t.keyCode;"Escape"!==e&&"Esc"!==e&&27!==e||h()},s=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t;if(t.background&&(C.style.background=t.background),t.container&&t.container instanceof Object&&(e.container=Jt({},O.container,t.container)),t.template){var n=ee(t.template)?t.template:document.querySelector(t.template);e.template=n}return O=Jt({},O,e),b.forEach((function(t){t.dispatchEvent(ae("medium-zoom:update",{detail:{zoom:S}}))})),S},c=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return t(Jt({},O,e))},u=function(){for(var t=arguments.length,e=Array(t),n=0;n0?e.reduce((function(t,e){return[].concat(t,re(e))}),[]):b;return r.forEach((function(t){t.classList.remove("medium-zoom-image"),t.dispatchEvent(ae("medium-zoom:detach",{detail:{zoom:S}}))})),b=b.filter((function(t){return-1===r.indexOf(t)})),S},f=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(r){r.addEventListener("medium-zoom:"+t,e,n)})),_.push({type:"medium-zoom:"+t,listener:e,options:n}),S},p=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(r){r.removeEventListener("medium-zoom:"+t,e,n)})),_=_.filter((function(n){return!(n.type==="medium-zoom:"+t&&n.listener.toString()===e.toString())})),S},d=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target,n=function(){var t={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},e=void 0,n=void 0;if(O.container)if(O.container instanceof Object)e=(t=Jt({},t,O.container)).width-t.left-t.right-2*O.margin,n=t.height-t.top-t.bottom-2*O.margin;else{var r=(ee(O.container)?O.container:document.querySelector(O.container)).getBoundingClientRect(),o=r.width,i=r.height,a=r.left,s=r.top;t=Jt({},t,{width:o,height:i,left:a,top:s})}e=e||t.width-2*O.margin,n=n||t.height-2*O.margin;var c=k.zoomedHd||k.original,u=ne(c)?e:c.naturalWidth||e,l=ne(c)?n:c.naturalHeight||n,f=c.getBoundingClientRect(),p=f.top,d=f.left,h=f.width,v=f.height,m=Math.min(u,e)/h,y=Math.min(l,n)/v,g=Math.min(m,y),b="scale("+g+") translate3d("+((e-h)/2-d+O.margin+t.left)/g+"px, "+((n-v)/2-p+O.margin+t.top)/g+"px, 0)";k.zoomed.style.transform=b,k.zoomedHd&&(k.zoomedHd.style.transform=b)};return new r((function(t){if(e&&-1===b.indexOf(e))t(S);else{if(k.zoomed)t(S);else{if(e)k.original=e;else{if(!(b.length>0))return void t(S);var r=b;k.original=r[0]}if(k.original.dispatchEvent(ae("medium-zoom:open",{detail:{zoom:S}})),x=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,w=!0,k.zoomed=ie(k.original),document.body.appendChild(C),O.template){var o=ee(O.template)?O.template:document.querySelector(O.template);k.template=document.createElement("div"),k.template.appendChild(o.content.cloneNode(!0)),document.body.appendChild(k.template)}if(document.body.appendChild(k.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),k.original.classList.add("medium-zoom-image--hidden"),k.zoomed.classList.add("medium-zoom-image--opened"),k.zoomed.addEventListener("click",h),k.zoomed.addEventListener("transitionend",(function e(){w=!1,k.zoomed.removeEventListener("transitionend",e),k.original.dispatchEvent(ae("medium-zoom:opened",{detail:{zoom:S}})),t(S)})),k.original.getAttribute("data-zoom-src")){k.zoomedHd=k.zoomed.cloneNode(),k.zoomedHd.removeAttribute("srcset"),k.zoomedHd.removeAttribute("sizes"),k.zoomedHd.src=k.zoomed.getAttribute("data-zoom-src"),k.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+k.zoomedHd.src),k.zoomedHd=null,n()};var i=setInterval((function(){k.zoomedHd.complete&&(clearInterval(i),k.zoomedHd.classList.add("medium-zoom-image--opened"),k.zoomedHd.addEventListener("click",h),document.body.appendChild(k.zoomedHd),n())}),10)}else if(k.original.hasAttribute("srcset")){k.zoomedHd=k.zoomed.cloneNode(),k.zoomedHd.removeAttribute("sizes");var a=k.zoomedHd.addEventListener("load",(function(){k.zoomedHd.removeEventListener("load",a),k.zoomedHd.classList.add("medium-zoom-image--opened"),k.zoomedHd.addEventListener("click",h),document.body.appendChild(k.zoomedHd),n()}))}else n()}}}))},h=function(){return new r((function(t){if(!w&&k.original){w=!0,document.body.classList.remove("medium-zoom--opened"),k.zoomed.style.transform="",k.zoomedHd&&(k.zoomedHd.style.transform=""),k.template&&(k.template.style.transition="opacity 150ms",k.template.style.opacity=0),k.original.dispatchEvent(ae("medium-zoom:close",{detail:{zoom:S}})),k.zoomed.addEventListener("transitionend",(function e(){k.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(k.zoomed),k.zoomedHd&&document.body.removeChild(k.zoomedHd),document.body.removeChild(C),k.zoomed.classList.remove("medium-zoom-image--opened"),k.template&&document.body.removeChild(k.template),w=!1,k.zoomed.removeEventListener("transitionend",e),k.original.dispatchEvent(ae("medium-zoom:closed",{detail:{zoom:S}})),k.original=null,k.zoomed=null,k.zoomedHd=null,k.template=null,t(S)}))}else t(S)}))},v=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target;return k.original?h():d({target:e})},m=function(){return O},y=function(){return b},g=function(){return k.original},b=[],_=[],w=!1,x=0,O=n,k={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(e)?O=e:(e||"string"==typeof e)&&u(e),O=Jt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},O);var C=oe(O.background);document.addEventListener("click",o),document.addEventListener("keyup",a),document.addEventListener("scroll",i),window.addEventListener("resize",h);var S={open:d,close:h,toggle:v,update:s,clone:c,attach:u,detach:l,on:f,off:p,getOptions:m,getImages:y,getZoomedImage:g};return S},ce=[Bt,Wt,Yt,Zt,{data:()=>({zoom:null}),mounted(){this.updateZoom()},updated(){this.updateZoom()},methods:{updateZoom(){setTimeout(()=>{this.zoom&&this.zoom.detach(),this.zoom=se(".theme-default-content :not(a) > img",void 0)},1e3)}}}],ue={name:"GlobalLayout",computed:{layout:function(){var t=this.getLayout();return Object(Ut.h)("layout",t),r.a.component(t)}},methods:{getLayout:function(){if(this.$page.path){var t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},le=n(2),fe=Object(le.a)(ue,(function(){var t=this.$createElement;return(this._self._c||t)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;Object(Ut.f)(fe,"mixins",ce);var pe=[{name:"v-746bd11e",path:"/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-746bd11e").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-5ba934e1",path:"/zh/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-5ba934e1").then(n)}},{path:"/zh/index.html",redirect:"/zh/"},{name:"v-74d01bde",path:"/zh/db/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-74d01bde").then(n)}},{path:"/zh/db/index.html",redirect:"/zh/db/"},{name:"v-58cebc34",path:"/zh/db/clickhouse.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-58cebc34").then(n)}},{name:"v-dbd7ec2c",path:"/zh/db/hbase.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-dbd7ec2c").then(n)}},{name:"v-94740eec",path:"/zh/db/mongodb.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-94740eec").then(n)}},{name:"v-5559350a",path:"/zh/db/mysql.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-5559350a").then(n)}},{name:"v-0a8a5aec",path:"/zh/db/neo4j.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-0a8a5aec").then(n)}},{name:"v-fc0c3ca4",path:"/zh/db/postgreSQL.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-fc0c3ca4").then(n)}},{name:"v-f82d23ac",path:"/zh/db/redis.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-f82d23ac").then(n)}},{name:"v-16372753",path:"/zh/devops/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-16372753").then(n)}},{path:"/zh/devops/index.html",redirect:"/zh/devops/"},{name:"v-793e68e1",path:"/zh/distributed/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-793e68e1").then(n)}},{path:"/zh/distributed/index.html",redirect:"/zh/distributed/"},{name:"v-5cfbe97e",path:"/zh/guide/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-5cfbe97e").then(n)}},{path:"/zh/guide/index.html",redirect:"/zh/guide/"},{name:"v-accb5676",path:"/zh/os/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-accb5676").then(n)}},{path:"/zh/os/index.html",redirect:"/zh/os/"},{name:"v-728e1cec",path:"/zh/os/coroutines.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-728e1cec").then(n)}},{name:"v-d2c24fec",path:"/zh/os/cpu.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-d2c24fec").then(n)}},{name:"v-173c9516",path:"/zh/os/io.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-173c9516").then(n)}},{name:"v-3d7c27ec",path:"/zh/os/linux.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-3d7c27ec").then(n)}},{name:"v-77f2e22a",path:"/zh/os/process.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-77f2e22a").then(n)}},{name:"v-d505af64",path:"/zh/os/thread.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-d505af64").then(n)}},{name:"v-4db484c1",path:"/zh/program/",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-4db484c1").then(n)}},{path:"/zh/program/index.html",redirect:"/zh/program/"},{name:"v-6c1827f0",path:"/zh/program/c.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-6c1827f0").then(n)}},{name:"v-775f4f8a",path:"/zh/program/golang.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-775f4f8a").then(n)}},{name:"v-3ca656aa",path:"/zh/program/javascript.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-3ca656aa").then(n)}},{name:"v-a9d38bc4",path:"/zh/program/php.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-a9d38bc4").then(n)}},{name:"v-3bd307ca",path:"/zh/program/python.html",component:fe,beforeEnter:function(t,e,n){Object(Ut.a)("Layout","v-3bd307ca").then(n)}},{path:"*",component:fe}],de={title:"",description:"",base:"/",pages:[{title:"Home",frontmatter:{home:!0,heroImage:"/hero.png",actionText:"快速上手 →",footer:"MIT Licensed | Copyright © 2020 Marco"},regularPath:"/",relativePath:"README.md",key:"v-746bd11e",path:"/",lastUpdated:"2/28/2020, 6:33:35 AM"},{title:"Home",frontmatter:{home:!0,heroImage:"/hero.png",actionText:"快速上手 →",actionLink:"/zh/guide/",features:[{title:"简洁至上",details:"以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。"}],footer:"MIT Licensed | Copyright © 2020-PRESENT Marco"},regularPath:"/zh/",relativePath:"zh/README.md",key:"v-5ba934e1",path:"/zh/",lastUpdated:"2/15/2020, 9:48:35 AM"},{title:"数据库 🔎",frontmatter:{},regularPath:"/zh/db/",relativePath:"zh/db/README.md",key:"v-74d01bde",path:"/zh/db/",headers:[{level:2,title:"数据库概述",slug:"数据库概述"},{level:2,title:"附录",slug:"附录"}],lastUpdated:"3/1/2020, 11:29:42 PM"},{title:"Clickhouse",frontmatter:{},regularPath:"/zh/db/clickhouse.html",relativePath:"zh/db/clickhouse.md",key:"v-58cebc34",path:"/zh/db/clickhouse.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"HBase",frontmatter:{},regularPath:"/zh/db/hbase.html",relativePath:"zh/db/hbase.md",key:"v-dbd7ec2c",path:"/zh/db/hbase.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"MongoDB",frontmatter:{},regularPath:"/zh/db/mongodb.html",relativePath:"zh/db/mongodb.md",key:"v-94740eec",path:"/zh/db/mongodb.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"MySQL",frontmatter:{},regularPath:"/zh/db/mysql.html",relativePath:"zh/db/mysql.md",key:"v-5559350a",path:"/zh/db/mysql.html",headers:[{level:2,title:"基础架构",slug:"基础架构"},{level:3,title:"连接器管理",slug:"连接器管理"},{level:3,title:"Mysql缓存",slug:"mysql缓存"},{level:3,title:"分析器",slug:"分析器"},{level:3,title:"优化器",slug:"优化器"},{level:3,title:"执行器",slug:"执行器"},{level:3,title:"日志系统",slug:"日志系统"},{level:2,title:"基础拓扑",slug:"基础拓扑"},{level:2,title:"数据结构",slug:"数据结构"},{level:3,title:"B树、B-树、B+树",slug:"b树、b-树、b-树"},{level:3,title:"磁盘存取原理",slug:"磁盘存取原理"},{level:3,title:"MyISAM 索引实现",slug:"myisam-索引实现"},{level:3,title:"InnoDB 索引实现",slug:"innodb-索引实现"},{level:2,title:"锁机制",slug:"锁机制"},{level:2,title:"隔离级别",slug:"隔离级别"},{level:2,title:"MVCC",slug:"mvcc"},{level:2,title:"InnoDB",slug:"innodb"},{level:2,title:"Explain",slug:"explain"},{level:2,title:"查询优化",slug:"查询优化"},{level:3,title:"查找分析查询速度慢点原因",slug:"查找分析查询速度慢点原因"},{level:3,title:"优化手段",slug:"优化手段"},{level:3,title:"参考文献",slug:"参考文献"}],lastUpdated:"3/8/2020, 2:17:06 PM"},{title:"Neo4J",frontmatter:{},regularPath:"/zh/db/neo4j.html",relativePath:"zh/db/neo4j.md",key:"v-0a8a5aec",path:"/zh/db/neo4j.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"PostgreSQL",frontmatter:{},regularPath:"/zh/db/postgreSQL.html",relativePath:"zh/db/postgreSQL.md",key:"v-fc0c3ca4",path:"/zh/db/postgreSQL.html",headers:[{level:2,title:"初始化",slug:"初始化"},{level:3,title:"数学关系",slug:"数学关系"},{level:3,title:"准备环境",slug:"准备环境"},{level:3,title:"从SQL开始",slug:"从sql开始"},{level:2,title:"体系结构",slug:"体系结构"},{level:2,title:"MVCC",slug:"mvcc"}],lastUpdated:"3/1/2020, 11:29:42 PM"},{title:"Redis",frontmatter:{},regularPath:"/zh/db/redis.html",relativePath:"zh/db/redis.md",key:"v-f82d23ac",path:"/zh/db/redis.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{frontmatter:{},regularPath:"/zh/devops/",relativePath:"zh/devops/README.md",key:"v-16372753",path:"/zh/devops/",lastUpdated:"2/15/2020, 11:02:54 AM"},{frontmatter:{},regularPath:"/zh/distributed/",relativePath:"zh/distributed/README.md",key:"v-793e68e1",path:"/zh/distributed/",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"要怎样努力,才能成为很厉害的人",frontmatter:{},regularPath:"/zh/guide/",relativePath:"zh/guide/README.md",key:"v-5cfbe97e",path:"/zh/guide/",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"操作系统",frontmatter:{},regularPath:"/zh/os/",relativePath:"zh/os/README.md",key:"v-accb5676",path:"/zh/os/",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"协程",frontmatter:{},regularPath:"/zh/os/coroutines.html",relativePath:"zh/os/coroutines.md",key:"v-728e1cec",path:"/zh/os/coroutines.html",lastUpdated:"2/24/2020, 2:21:13 PM"},{title:"CPU",frontmatter:{},regularPath:"/zh/os/cpu.html",relativePath:"zh/os/cpu.md",key:"v-d2c24fec",path:"/zh/os/cpu.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"IO",frontmatter:{},regularPath:"/zh/os/io.html",relativePath:"zh/os/io.md",key:"v-173c9516",path:"/zh/os/io.html",headers:[{level:2,title:"概念",slug:"概念"},{level:3,title:"用户态切换到内核态",slug:"用户态切换到内核态"},{level:3,title:"进程的结构-PCB",slug:"进程的结构-pcb"},{level:3,title:"进程切换",slug:"进程切换"},{level:3,title:"创建进程",slug:"创建进程"},{level:3,title:"进程的阻塞",slug:"进程的阻塞"},{level:3,title:"同步与异步",slug:"同步与异步"},{level:3,title:"同步与异步的区别",slug:"同步与异步的区别"},{level:3,title:"阻塞与非阻塞",slug:"阻塞与非阻塞"},{level:3,title:"文件描述符 fd",slug:"文件描述符-fd"},{level:2,title:"缓存 I/O",slug:"缓存-i-o"},{level:2,title:"网络 I/O",slug:"网络-i-o"},{level:2,title:"IO模式",slug:"io模式"},{level:2,title:"阻塞 I/O",slug:"阻塞-i-o"},{level:3,title:"非阻塞 I/O",slug:"非阻塞-i-o"},{level:3,title:"同步非阻塞与同步阻塞之间有什么优缺点呢?",slug:"同步非阻塞与同步阻塞之间有什么优缺点呢?"},{level:2,title:"I/O 多路复用",slug:"i-o-多路复用"},{level:3,title:"poll",slug:"poll"},{level:3,title:"epoll",slug:"epoll"},{level:3,title:"实现原理",slug:"实现原理"},{level:2,title:"信号驱动 I/O",slug:"信号驱动-i-o"},{level:2,title:"异步 I/O",slug:"异步-i-o"},{level:3,title:"小结",slug:"小结"},{level:2,title:"IO设计模式",slug:"io设计模式"},{level:3,title:"传统IO设计模式",slug:"传统io设计模式"},{level:3,title:"多线程模式",slug:"多线程模式"},{level:3,title:"线程池模式",slug:"线程池模式"},{level:3,title:"高性能IO设计模式",slug:"高性能io设计模式"},{level:3,title:"Reactor",slug:"reactor"},{level:3,title:"Proactor",slug:"proactor"}],lastUpdated:"2/25/2020, 7:09:44 AM"},{title:"LINUX",frontmatter:{},regularPath:"/zh/os/linux.html",relativePath:"zh/os/linux.md",key:"v-3d7c27ec",path:"/zh/os/linux.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"进程",frontmatter:{},regularPath:"/zh/os/process.html",relativePath:"zh/os/process.md",key:"v-77f2e22a",path:"/zh/os/process.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"线程",frontmatter:{},regularPath:"/zh/os/thread.html",relativePath:"zh/os/thread.md",key:"v-d505af64",path:"/zh/os/thread.html",lastUpdated:"2/15/2020, 11:02:54 AM"},{title:"编译型语言",frontmatter:{},regularPath:"/zh/program/",relativePath:"zh/program/README.md",key:"v-4db484c1",path:"/zh/program/",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"C",frontmatter:{},regularPath:"/zh/program/c.html",relativePath:"zh/program/c.md",key:"v-6c1827f0",path:"/zh/program/c.html",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"Golang",frontmatter:{},regularPath:"/zh/program/golang.html",relativePath:"zh/program/golang.md",key:"v-775f4f8a",path:"/zh/program/golang.html",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"JavaScript",frontmatter:{},regularPath:"/zh/program/javascript.html",relativePath:"zh/program/javascript.md",key:"v-3ca656aa",path:"/zh/program/javascript.html",lastUpdated:"2/22/2020, 6:07:07 PM"},{title:"PHP",frontmatter:{},regularPath:"/zh/program/php.html",relativePath:"zh/program/php.md",key:"v-a9d38bc4",path:"/zh/program/php.html",headers:[{level:2,title:"源码整体框架",slug:"源码整体框架"},{level:2,title:"执行原理概述",slug:"执行原理概述"},{level:2,title:"Zend 虚拟机",slug:"zend-虚拟机"},{level:3,title:"符号表",slug:"符号表"},{level:3,title:"指令",slug:"指令"},{level:2,title:"生命周期",slug:"生命周期"},{level:3,title:"SAPI",slug:"sapi"},{level:2,title:"内存管理",slug:"内存管理"},{level:2,title:"垃圾回收",slug:"垃圾回收"},{level:3,title:"垃圾的产生",slug:"垃圾的产生"},{level:3,title:"回收过程",slug:"回收过程"},{level:3,title:"垃圾收集的内部实现",slug:"垃圾收集的内部实现"},{level:2,title:"扩展的构成及编译",slug:"扩展的构成及编译"},{level:3,title:"扩展的构成",slug:"扩展的构成"},{level:3,title:"编译工具",slug:"编译工具"},{level:3,title:"php-config",slug:"php-config"},{level:3,title:"编写扩展的基本步骤",slug:"编写扩展的基本步骤"},{level:3,title:"config.m4",slug:"config-m4"}],lastUpdated:"2/24/2020, 2:14:52 AM"},{title:"Python",frontmatter:{},regularPath:"/zh/program/python.html",relativePath:"zh/program/python.md",key:"v-3bd307ca",path:"/zh/program/python.html",lastUpdated:"2/22/2020, 6:07:07 PM"}],themeConfig:{repo:"m9rco/practice",docsRepo:"m9-lab/m9-lab.github.io",docsBranch:"master",editLinks:!0,docsDir:"docs",algolia:{apiKey:"17103d809d3df489f3e1de21aaa02b48",indexName:"practice"},smoothScroll:!0,locales:{"/":{label:"简体中文",selectText:"选择语言",ariaLabel:"选择语言",editLinkText:"在 GitHub 上编辑此页",lastUpdated:"上次更新",nav:[{text:"指南",link:"/zh/guide/"},{text:"数据库",link:"/zh/db/"},{text:"操作系统",link:"/zh/os/"},{text:"编程语言",link:"/zh/program/"},{text:"分布式设计",link:"/zh/distributed/"},{text:"DevOPS",link:"/zh/devops/"},{text:"通用基础",ariaLabel:"通用基础",items:[{text:"算法 & 数据结构",items:[{text:"数据结构",link:"/zh/structures-algorithm/structures.html"},{text:"基本算法",link:"/zh/structures-algorithm/algorithm.html"},{text:"Leetcode",link:"/zh/leetcode/"}]},{text:"网络安全",items:[{text:"WEB 安全",link:"/zh/structures-algorithm/structures.html"},{text:"服务器安全",link:"/zh/structures-algorithm/algorithm.html"},{text:"序列化漏洞",link:"/zh/structures-algorithm/algorithm.html"},{text:"加密解密",link:"/zh/structures-algorithm/algorithm.html"},{text:"网络隔离",link:"/zh/structures-algorithm/algorithm.html"}]},{text:"设计思路",items:[{text:"并发问题",link:"/zh/structures-algorithm/structures.html"},{text:"限流熔断",link:"/zh/structures-algorithm/algorithm.html"},{text:"海量搜索",link:"/zh/structures-algorithm/algorithm.html"}]}]}],sidebar:{"/zh/guide/":[{title:"指南",collapsable:!1,children:[""]}],"/zh/db/":[{title:"关系型数据库",collapsable:!1,children:["mysql","postgreSQL"]},{title:"键-值数据库",collapsable:!1,children:["redis"]},{title:"列数据库",collapsable:!1,children:["hbase","clickhouse"]},{title:"文档型数据库",collapsable:!1,children:["mongodb"]},{title:"图数据库",collapsable:!1,children:["neo4j"]}],"/zh/os/":[{title:"操作系统",collapsable:!1,children:["io","cpu","thread","coroutines","process"]},{title:"计算机原理",collapsable:!1,children:["linux"]}],"/zh/program/":[{title:"解释型语言",collapsable:!1,children:["php","python","javascript"]},{title:"编译型语言",collapsable:!1,children:["golang","c"]}]}},"/en":{label:"English",selectText:"Languages",ariaLabel:"Select language",editLinkText:"Edit this page on GitHub",lastUpdated:"Last Updated",nav:[{text:"Guide",link:"/guide/"},{text:"Config Reference",link:"/config/"},{text:"Plugin",link:"/plugin/"},{text:"Theme",link:"/theme/"},{text:"0.x",link:"https://v0.vuepress.vuejs.org/"}],sidebar:{}}}},locales:{"/":{lang:"zh-CN",title:"笃行",description:"笃行致远,不负芳华",path:"/"},"/en/":{lang:"English",title:"Practice",description:"The back-end architects self practice",path:"/en/"}}};function he(t){var e=document.createElement("link");e.href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css",e.rel="stylesheet",document.body.appendChild(e);var n=document.createElement("script");function r(t){var e=document.getElementById("gitalk-container");e||((e=document.createElement("div")).id="gitalk-container",e.classList.add("content"));var n=document.querySelector(".page-nav");n&&(n.appendChild(e),"undefined"!=typeof Gitalk&&Gitalk instanceof Function&&(t.fullPath,new Gitalk({clientID:"5e01d05713fb81675776",clientSecret:"599d38643f2c2fb15438c137f345a03fcb244b50",repo:"practice",owner:"m9rco",admin:["m9rco"],id:location.pathname,distractionFreeMode:!1,language:"zh-CN"}).render("gitalk-container")))}n.src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js",document.body.appendChild(n),t.afterEach((function(t){n.onload?r(t):n.onload=function(){r(t)}}))}n(98);r.a.component("Bit",(function(){return Promise.all([n.e(0),n.e(6)]).then(n.bind(null,285))})),r.a.component("Comment",(function(){return n.e(11).then(n.bind(null,256))})),r.a.component("OtherComponent",(function(){return n.e(13).then(n.bind(null,286))})),r.a.component("UpgradePath",(function(){return Promise.all([n.e(0),n.e(7)]).then(n.bind(null,287))})),r.a.component("demo-1",(function(){return n.e(14).then(n.bind(null,257))})),r.a.component("diagram-markdown-slot-relationship",(function(){return n.e(15).then(n.bind(null,288))})),r.a.component("svg-container",(function(){return Promise.all([n.e(0),n.e(8)]).then(n.bind(null,289))})),r.a.component("Foo-Bar",(function(){return n.e(12).then(n.bind(null,258))})),r.a.component("Badge",(function(){return Promise.all([n.e(0),n.e(10)]).then(n.bind(null,290))}));n(99),n(100);function ve(t){const e=document.documentElement.getBoundingClientRect(),n=t.getBoundingClientRect();return{x:n.left-e.left,y:n.top-e.top}}n(101);var me={name:"BackToTop",props:{threshold:{type:Number,default:300}},data:function(){return{scrollTop:null}},computed:{show:function(){return this.scrollTop>this.threshold}},mounted:function(){var t=this;this.scrollTop=this.getScrollTop(),window.addEventListener("scroll",qt()((function(){t.scrollTop=t.getScrollTop()}),100))},methods:{getScrollTop:function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"}),this.scrollTop=0}}},ye=(n(110),Object(le.a)(me,(function(){var t=this.$createElement,e=this._self._c||t;return e("transition",{attrs:{name:"fade"}},[this.show?e("svg",{staticClass:"go-to-top",attrs:{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 49.484 28.284"},on:{click:this.scrollToTop}},[e("g",{attrs:{transform:"translate(-229 -126.358)"}},[e("rect",{attrs:{fill:"currentColor",width:"35",height:"5",rx:"2",transform:"translate(229 151.107) rotate(-45)"}}),this._v(" "),e("rect",{attrs:{fill:"currentColor",width:"35",height:"5",rx:"2",transform:"translate(274.949 154.642) rotate(-135)"}})])]):this._e()])}),[],!1,null,"5fd4ef0c",null).exports);function ge(t,e){void 0===e&&(e={});var n=e.registrationOptions;void 0===n&&(n={}),delete e.registrationOptions;var r=function(t){for(var n=[],r=arguments.length-1;r-- >0;)n[r]=arguments[r+1];e&&e[t]&&e[t].apply(e,n)};"serviceWorker"in navigator&&window.addEventListener("load",(function(){Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/))?(!function(t,e,n){fetch(t).then((function(r){404===r.status?(e("error",new Error("Service worker not found at "+t)),_e()):-1===r.headers.get("content-type").indexOf("javascript")?(e("error",new Error("Expected "+t+" to have javascript content-type, but received "+r.headers.get("content-type"))),_e()):be(t,e,n)})).catch((function(t){navigator.onLine?e("error",t):e("offline")}))}(t,r,n),navigator.serviceWorker.ready.then((function(t){r("ready",t)}))):be(t,r,n)}))}function be(t,e,n){navigator.serviceWorker.register(t,n).then((function(t){e("registered",t),t.waiting?e("updated",t):t.onupdatefound=function(){e("updatefound",t);var n=t.installing;n.onstatechange=function(){"installed"===n.state&&(navigator.serviceWorker.controller?e("updated",t):e("cached",t))}}})).catch((function(t){e("error",t)}))}function _e(){"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((function(t){t.unregister()}))}class we{constructor(t){Object.defineProperty(this,"registration",{value:t,configurable:!0,writable:!0})}update(){return this.registration.update()}skipWaiting(){const t=this.registration.waiting;return t?(console.log("[vuepress:sw] Doing worker.skipWaiting()."),new Promise((e,n)=>{const r=new MessageChannel;r.port1.onmessage=t=>{console.log("[vuepress:sw] Done worker.skipWaiting()."),t.data.error?n(t.data.error):e(t.data)},t.postMessage({type:"skip-waiting"},[r.port2])})):Promise.resolve()}}var xe=n(12);r.a.component("SWUpdatePopup",()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,254)));var Oe=n(77),ke=(n(81),n(91),Object(le.a)({},(function(){var t=this.$createElement,e=this._self._c||t;return e("svg",{staticStyle:{"enable-background":"new 0 0 50 50"},attrs:{xmlns:"http://www.w3.org/2000/svg",x:"0px",y:"0px",viewBox:"0 0 30 30"}},[e("rect",{attrs:{x:"0",y:"13",width:"4",height:"5"}},[e("animate",{attrs:{attributeName:"height",attributeType:"XML",values:"5;21;5",begin:"0s",dur:"0.6s",repeatCount:"indefinite"}}),this._v(" "),e("animate",{attrs:{attributeName:"y",attributeType:"XML",values:"13; 5; 13",begin:"0s",dur:"0.6s",repeatCount:"indefinite"}})]),this._v(" "),e("rect",{attrs:{x:"10",y:"13",width:"4",height:"5"}},[e("animate",{attrs:{attributeName:"height",attributeType:"XML",values:"5;21;5",begin:"0.15s",dur:"0.6s",repeatCount:"indefinite"}}),this._v(" "),e("animate",{attrs:{attributeName:"y",attributeType:"XML",values:"13; 5; 13",begin:"0.15s",dur:"0.6s",repeatCount:"indefinite"}})]),this._v(" "),e("rect",{attrs:{x:"20",y:"13",width:"4",height:"5"}},[e("animate",{attrs:{attributeName:"height",attributeType:"XML",values:"5;21;5",begin:"0.3s",dur:"0.6s",repeatCount:"indefinite"}}),this._v(" "),e("animate",{attrs:{attributeName:"y",attributeType:"XML",values:"13; 5; 13",begin:"0.3s",dur:"0.6s",repeatCount:"indefinite"}})])])}),[],!1,null,null,null).exports),Ce={x:0,y:0,"line-width":2,"line-length":50,"text-margin":10,"font-size":14,"font-color":"#8DA1AC","line-color":"#8DA1AC","element-color":"black",fill:"white","yes-text":"yes","no-text":"no","arrow-end":"block",scale:1},Se={ant:Object.assign({},Ce,{symbols:{start:{class:"start-element","font-color":"white",fill:"#595959","line-width":"0px"},end:{class:"end-element","font-color":"white",fill:"#595959","line-width":"0px"},operation:{class:"operation-element","font-color":"white",fill:"#1890ff","line-width":"0px"},inputoutput:{class:"inputoutput-element","font-color":"white",fill:"#1890ff","line-width":"0px"},subroutine:{class:"subroutine-element","font-color":"white",fill:"#FF485E","element-color":"#fff","line-color":"red"},condition:{class:"condition-element","font-color":"white",fill:"#FF485E","line-width":"0px"},parallel:{class:"parallel-element","font-color":"white",fill:"#1890ff","line-width":"0px"}}}),vue:Object.assign({},Ce,{symbols:{start:{class:"start-element","font-color":"white",fill:"#2F495F","line-width":"0px"},end:{class:"end-element","font-color":"white",fill:"#2F495F","line-width":"0px"},operation:{class:"operation-element","font-color":"white",fill:"#00BC7D","line-width":"0px"},inputoutput:{class:"inputoutput-element","font-color":"white",fill:"#EB4D5D","line-width":"0px"},subroutine:{class:"subroutine-element","font-color":"white",fill:"#937AC4","element-color":"#fff","line-color":"red"},condition:{class:"condition-element","font-color":"white",fill:"#FFB500","line-width":"0px"},parallel:{class:"parallel-element","font-color":"white",fill:"#2F495F","line-width":"0px"}}})},Ee={name:"flowchart",components:{Loading:ke},props:{id:{type:String,required:!0},code:{type:String,required:!0},preset:{type:String,default:"vue"}},data:function(){return{loading:!0}},mounted:function(){var t=this,e=Se[this.preset];if(e){var r=this.code;this.$el.setAttribute("id",this.id);Promise.all([n.e(3).then(n.t.bind(null,250,7)),new Promise((function(t){return setTimeout(t,500)}))]).then((function(n){(0,Object(Oe.a)(n,1)[0].default.parse)(r).drawSVG(t.id,e),t.loading=!1}))}else console.warn("[vuepress-plugin-flowchart] Unknown preset: ".concat(this.preset))}},Ae=(n(140),Object(le.a)(Ee,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"vuepress-flowchart",class:{loading:this.loading}},[this.loading?e("Loading",{staticClass:"vuepress-flowchart-loading-icon"}):this._e()],1)}),[],!1,null,null,null).exports),$e=[function(t){var e=t.Vue,r=t.isServer,o=t.router;try{document&&he(o)}catch(t){console.error(t.message)}r||n.e(4).then(n.t.bind(null,249,7)).then((function(t){e.use(t.default)}))},{},function(t){t.Vue.mixin({computed:{$dataBlock:function(){return this.$options.__data__block__}}})},{},{},({Vue:t,router:e})=>{e.options.scrollBehavior=(e,n,r)=>{if(r)return window.scrollTo({top:r.y,behavior:"smooth"});if(e.hash){if(t.$vuepress.$get("disableScrollBehavior"))return!1;const n=document.querySelector(e.hash);return!!n&&window.scrollTo({top:ve(n).y,behavior:"smooth"})}return window.scrollTo({top:0,behavior:"smooth"})}},({Vue:t})=>{t.component("BackToTop",ye)},({router:t,isServer:e})=>{t.onReady(()=>{e||ge("/service-worker.js",{registrationOptions:{},ready(){console.log("[vuepress:sw] Service worker is active."),xe.a.$emit("sw-ready")},cached(t){console.log("[vuepress:sw] Content has been cached for offline use."),xe.a.$emit("sw-cached",new we(t))},updated(t){console.log("[vuepress:sw] Content updated."),xe.a.$emit("sw-updated",new we(t))},offline(){console.log("[vuepress:sw] No internet connection found. App is running in offline mode."),xe.a.$emit("sw-offline")},error(t){console.error("[vuepress:sw] Error during service worker registration:",t),xe.a.$emit("sw-error",t),ga("send","exception",{exDescription:t.message,exFatal:!1})}})})},({router:t})=>{var e,n,r,o,i,a;"undefined"!=typeof window&&(e=window,n=document,r="script",o="ga",e.GoogleAnalyticsObject=o,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,i=n.createElement(r),a=n.getElementsByTagName(r)[0],i.async=1,i.src="https://www.google-analytics.com/analytics.js",a.parentNode.insertBefore(i,a),ga("create","UA-158536766-1","auto"),ga("set","anonymizeIp",!0),t.afterEach((function(t){ga("set","page",t.fullPath),ga("send","pageview")})))},function(t){const{Vue:e}=t;e.component("FlowChart",Ae)}],je=["BackToTop"];n(141),n(93),n(95);var Te=n(80),ze=n.n(Te);function Pe(t,e){for(var n=0;nt.path.toLowerCase()===e.toLowerCase()).length>0}var Re={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return Object(Ut.h)("pageKey",e),r.a.component(e)||r.a.component(e,Object(Ut.d)(e)),r.a.component(e)?t(e):t("")}},Ne={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:[`content__${e.slotKey}`]},n()[e.slotKey])},De=(n(146),Object(le.a)({},(function(t,e){var n=e._c;return n("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[n("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),e._v(" "),n("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})])}),[],!0,null,null,null).exports),Fe={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};r.a.config.productionTip=!1,r.a.use(Ft),r.a.use(Me),r.a.mixin(function(t,e,n=r.a){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const o=new(t(n.$vuepress.$get("siteData"))),i=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(o)),a={};return Object.keys(i).reduce((t,e)=>(e.startsWith("$")&&(t[e]=i[e].get),t),a),{computed:a}}((function(t){return function(){function e(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e)}var n,r,o;return n=e,(r=[{key:"setPage",value:function(t){this.__page=t}},{key:"$site",get:function(){return t}},{key:"$themeConfig",get:function(){return this.$site.themeConfig}},{key:"$frontmatter",get:function(){return this.$page.frontmatter}},{key:"$localeConfig",get:function(){var t,e,n=this.$site.locales,r=void 0===n?{}:n;for(var o in r)"/"===o?e=r[o]:0===this.$page.path.indexOf(o)&&(t=r[o]);return t||e||{}}},{key:"$siteTitle",get:function(){return this.$localeConfig.title||this.$site.title||""}},{key:"$title",get:function(){var t=this.$page,e=this.$page.frontmatter.metaTitle;if("string"==typeof e)return e;var n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}},{key:"$description",get:function(){var t=function(t){if(t){var e=t.filter((function(t){return"description"===t.name}))[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||""}},{key:"$lang",get:function(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}},{key:"$localePath",get:function(){return this.$localeConfig.path||"/"}},{key:"$themeLocaleConfig",get:function(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}},{key:"$page",get:function(){return this.__page?this.__page:function(t,e){for(var n=0;nn||(t.hash?!r.a.$vuepress.$get("disableScrollBehavior")&&{selector:t.hash}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Ie(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Ie(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Ie(t,o)?r(o):Ie(t,n)?r(n):r()}})}(n);const o={};try{$e.forEach(e=>{"function"==typeof e&&e({Vue:r.a,options:o,router:n,siteData:de,isServer:t})})}catch(t){console.error(t)}return{app:new r.a(Object.assign(o,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},je.map(e=>t(e)))])})),router:n}}(!1);window.__VUEPRESS__={version:"1.3.0",hash:"5e84ca7"},Be.onReady(()=>{Ue.$mount("#app")})}]); \ No newline at end of file diff --git a/db/mysql/mysql-08.png b/db/mysql/mysql-08.png new file mode 100644 index 0000000..dbc8b13 Binary files /dev/null and b/db/mysql/mysql-08.png differ diff --git a/db/mysql/mysql-09.png b/db/mysql/mysql-09.png new file mode 100644 index 0000000..55d358c Binary files /dev/null and b/db/mysql/mysql-09.png differ diff --git a/index.html b/index.html index 35d8215..39f2a44 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@ - + @@ -119,6 +119,6 @@

- + diff --git a/service-worker.js b/service-worker.js index 31a98c8..9f00d61 100644 --- a/service-worker.js +++ b/service-worker.js @@ -27,7 +27,7 @@ self.addEventListener('message', (event) => { self.__precacheManifest = [ { "url": "404.html", - "revision": "4b49a7a628f51024ae26e3716431f6aa" + "revision": "5c691582e928830b672b4edb736012cb" }, { "url": "architecture.png", @@ -94,8 +94,8 @@ self.__precacheManifest = [ "revision": "aac6a89d5d33f593344c1f616d0e5f82" }, { - "url": "assets/js/23.d22a11cb.js", - "revision": "6ec012f55cab6a33150ae90581d50413" + "url": "assets/js/23.3b91481f.js", + "revision": "09aeaf4c0833214e823b2bc6f43fb317" }, { "url": "assets/js/24.9a3abbc6.js", @@ -198,8 +198,8 @@ self.__precacheManifest = [ "revision": "c1f319c99acdf47265e5e17c04b1c431" }, { - "url": "assets/js/app.317b3400.js", - "revision": "d30ffa44ce4db023da63a84aeeb60048" + "url": "assets/js/app.de81a621.js", + "revision": "69d92376a4fece2322933271adace70b" }, { "url": "assets/js/vendors~docsearch.87ae9561.js", @@ -241,6 +241,14 @@ self.__precacheManifest = [ "url": "db/mysql/mysql-07.jpg", "revision": "416a1b17f4bc9055db554500393f6e2c" }, + { + "url": "db/mysql/mysql-08.png", + "revision": "291daaf6f952e100727c4ef5cf5e680f" + }, + { + "url": "db/mysql/mysql-09.png", + "revision": "6f6c9472b695263d30c665fb795290ca" + }, { "url": "db/postgresql/postgresql-01.png", "revision": "67635cd276286d0b14aa3917466ec08f" @@ -307,7 +315,7 @@ self.__precacheManifest = [ }, { "url": "index.html", - "revision": "465af8e5411f931a505507612ba027b6" + "revision": "f5daff5e867b834bbe1842b8a8e0b0ab" }, { "url": "line-numbers-desktop.png", @@ -391,103 +399,103 @@ self.__precacheManifest = [ }, { "url": "zh/db/clickhouse.html", - "revision": "0b719590fff4f7f9a313542fe97cbd2a" + "revision": "29dac2771e8133bebd934a411039a43c" }, { "url": "zh/db/hbase.html", - "revision": "70aa429513f9de8477590f63687295fd" + "revision": "ce783cfa39ea759b4013e50f173bea16" }, { "url": "zh/db/index.html", - "revision": "1313119f0bc34f206e0e8558042c00ca" + "revision": "230663f7d37ae3a8dd1a67924cf8f546" }, { "url": "zh/db/mongodb.html", - "revision": "6abc2468d6089a7fcd9d779f21c42bc4" + "revision": "656201205e6e204128753b012848c4c0" }, { "url": "zh/db/mysql.html", - "revision": "733e55d8ee6e551259902f6ca983ccaa" + "revision": "2598191da571c4243f2851086d7acb6e" }, { "url": "zh/db/neo4j.html", - "revision": "28a0e9e42d7f1e3bd0f524fcc95ad34b" + "revision": "3e3b9a35cf59bd97320ddaff62de5ba4" }, { "url": "zh/db/postgreSQL.html", - "revision": "1e052f09686d7d4422c833ccca3bb377" + "revision": "47746bbd42bd042b1279017558f24abb" }, { "url": "zh/db/redis.html", - "revision": "e1b318ca2bc8176baf6789e16ae3df26" + "revision": "dcaa602b278d14f38ee82c6010b8d99e" }, { "url": "zh/devops/index.html", - "revision": "316c5fc5e74f9d05e47afe3918524cd1" + "revision": "cb4f98dbce5dfe827ec318cf23e42790" }, { "url": "zh/distributed/index.html", - "revision": "fe09771504970e3f4db9d46447107df4" + "revision": "005488d5937fb3c270829d90fe2986ee" }, { "url": "zh/guide/index.html", - "revision": "2249f3a2bc9937f71ada603299dbeee7" + "revision": "100f55943c5cc987ee70e67212a26bcb" }, { "url": "zh/index.html", - "revision": "ccdd9d59a4793605d90d7258c1446599" + "revision": "5ba03c6da89d018f8965b93f36697087" }, { "url": "zh/os/coroutines.html", - "revision": "49c674a49b5f49eed0fb7d0888a43058" + "revision": "04d43a6cb2499dbc547791c8075957f0" }, { "url": "zh/os/cpu.html", - "revision": "39d7ef8a295621a637f4569c55338de8" + "revision": "2334be7e1e96228128305bb5f1df708f" }, { "url": "zh/os/index.html", - "revision": "3db5cf3ff66ede35418e431285ad4211" + "revision": "1ba91e130878ad3bff2baf27291268a9" }, { "url": "zh/os/io.html", - "revision": "f07bf4849a35274a59a708781d25cff7" + "revision": "698694559da51cbc2bd7594848b727b1" }, { "url": "zh/os/linux.html", - "revision": "1951a3d409aa5883ea4633ee63b04b0a" + "revision": "4f4d0474c2faba1c3b356e4ae6dd620d" }, { "url": "zh/os/process.html", - "revision": "0975225c059c8e742797ee1c28d07dd4" + "revision": "2d18181030e711219848609befa29224" }, { "url": "zh/os/thread.html", - "revision": "f4e7160861559b43c52241264df98f06" + "revision": "2f420d6f0ed883a79696ff32ee9fd54e" }, { "url": "zh/program/c.html", - "revision": "0936a914faabe5a63e0259caa89110d5" + "revision": "060262a17bda273d335b73a0aa2d6825" }, { "url": "zh/program/golang.html", - "revision": "6661e04edebf9636fbc1addc7da8dd84" + "revision": "0864f842206d7752f707ba6f409d894a" }, { "url": "zh/program/index.html", - "revision": "3bc8f310ed7623f28b714a46d483c986" + "revision": "a3df97437dc63f7eaa2d1345b7e4863e" }, { "url": "zh/program/javascript.html", - "revision": "497e6f99fbe1bba3d9949b3ca7ab9bb9" + "revision": "2a67444afa460c638fd4cd3a5a8169d6" }, { "url": "zh/program/php.html", - "revision": "cd812ebe292061b854804f9c981741e9" + "revision": "76952705bffdf229c5d7d13c24b354e9" }, { "url": "zh/program/python.html", - "revision": "ed19a0f38f5e63c3c9d7c8a0a6b917bc" + "revision": "07f480ad1007bebd85f0d4ed14d7d77f" } ].concat(self.__precacheManifest || []); workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); diff --git a/zh/db/clickhouse.html b/zh/db/clickhouse.html index ff1b744..a84611e 100644 --- a/zh/db/clickhouse.html +++ b/zh/db/clickhouse.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/db/hbase.html b/zh/db/hbase.html index d4ebc56..70d83a1 100644 --- a/zh/db/hbase.html +++ b/zh/db/hbase.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/db/index.html b/zh/db/index.html index b73265d..c91899f 100644 --- a/zh/db/index.html +++ b/zh/db/index.html @@ -16,7 +16,7 @@ - + @@ -113,6 +113,6 @@ GitHub

# 数据库 🔎

数据库不是凭空产生的,它们是为了解决实际使用中提出的问题,在RDBMS(关系数据库管理系统)出现的环境中,数据库插叙你的灵活性比灵活的模式更重要

# 数据库概述

本节包含了9种数据库的信息

MongoDB counchDB Riak Redis PostgreSQL Neo4J HBase Mysql Clickhouse
类型 文档 文档 键-值 键-值 关系 关系
数据类型 有类型 有类型 Blob 半类型 预定义且有类型 无类型 预定义且有类型
数据关系 自由定义的(链接) 预定义 预定义的(边)
标准对象 JSON JSON 文本 字符串 哈希
编写语言 C++ Erlang Erlang C/C++ C JAVA JAVA
接口协议 TCP上自定义 HTTP HTTP-Protobuf TCP上的简单文本 TCP上自定义 HTTP Thrift-HTTP
HTTP/REST
二级索引
版本化
Build Load mongoimport Bulk Doc API COPY命令
非常大的文件 GridFS 附件 Luwak(已弃用) BLOB
自由定义的查询 命令mapreduce 临时视图 弱支持Lucene 命令 SQL 图遍历,Cypher,搜索
mapreduce JavaScript JavaScript JavaScript,Erlang Hadoop
伸缩性 数据中心 数据中心 数据中心 集群(主-从) 集群(通过一些扩展) 集群(通过HA) 数据中心
耐久性 写前日志安全模式 只在崩溃时 写入法定数则耐久 仅追加的日志 ACID ACID 写前日志
请求压缩 文件重写 快照
复制 主-从(通过复集) 主-主 基于对等主-主 主-从 主-从 主-从(在企业版中) 主-从
并发 写锁 无锁的MVCC 向量锁 表/行写锁 写锁 每行一段
分片 锁(通过BigCouch过滤器) 插件(客户端) 扩展(PL/Proxy) 通过HDFS
事务 多操作队列 ACID ACID
触发器 更新验证或改变API 提交前后 事物事件处理程序
安全性 用户 用户 口令 用户/群 Kerberos,通过Hadoop的安全性
一主机多实例
主要区别 容易查询大量数据 耐久的可嵌入的集群 高可用性 非常非常快 最好的OSS RDBMS模型 灵活的图 规模非常大,Hadoop基础设施
不足 嵌入能力 查询能力 查询能力 负责数据 分布式高可用性 Blob或TB级数据 灵活增长查询能力

# 附录

- + diff --git a/zh/db/mongodb.html b/zh/db/mongodb.html index a027a71..a152250 100644 --- a/zh/db/mongodb.html +++ b/zh/db/mongodb.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/db/mysql.html b/zh/db/mysql.html index 475e500..86739db 100644 --- a/zh/db/mysql.html +++ b/zh/db/mysql.html @@ -16,7 +16,7 @@ - + @@ -112,7 +112,7 @@ English GitHub -

# MySQL

MySQL是一个关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性

# 基础架构

foo

# 连接器管理

链接的建立过程复杂,操作中如果需要大量长时间的存取数据,使用长链接 +

# MySQL

MySQL是一个关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性

# 基础架构

foo

# 连接器管理

  • 长连接:连接成功后,如果客户端持续有请求,则一直使用同一个连接
  • 短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个

链接的建立过程复杂,操作中如果需要大量长时间的存取数据,使用长链接 使用长链接的缺点: 容易占用内存, 因为MySQL在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM)

解决长连接占用内存,短链接繁琐的问题

  1. 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。
  2. 如果你用的是MySQL 5.7或更新版本,可以在每次执行一个比较大的操作后,通过执行mysql_reset_connection来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

# Mysql缓存

Mysql通过在内存中建立缓冲区[buffer]缓寸[cache]来提高Mysql性能,key是查询的语句,value是查询的结果,对于InnoDB引擎,Mysql采用缓冲池[buffer pool]的方式来缓存数据和索引,对于MyISAM引擎,Mysql采用缓存的方式来缓存数据和索引,先看缓存数据,如果存在则直接返回。如果没有则直接往下走

  • 关键字缓存(key cache)
    • 当Mysql收到传入的sql语句时,它首先和先前已经解析过的sql语句进行比较,如果发现相同,则返回已缓存数据。一定是完全相同,因此MySQL的查询缓存命中率很低
  • 查询缓存(query cache)
SHOW variables LIKE 'have_query_cache'; # 查询mysql缓存配置信息
@@ -128,7 +128,7 @@
 你会在数据库的慢查询日志中看到一个rows_examined的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。

在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟rows_examined并不是完全相同的

# 日志系统

首先要清楚redolog和binlog两个日志模块

  1. redolog(InnoDB特有的日志模块,起初InnoDB是另一个公司以插件的方式加到mysql的,拥有crash-safe故障恢复能力) 重做日志文件,用于记录事务操作的变化,记录修改后的值,不管事务是否提交。保证数据的完整性。其中redolog是固定大小的,是从头开始写,写到末尾在从头开始。同时会有两个指针,一个记录写入的位置,一个标记,当前擦除的位置,不断的循环。整个过程称为crash-safe。即时数据库异常,也会有记录
  2. binlog 归档日志文件,用于记录对mysql数据库执行更改的所有操作。binlog是追加写,不会覆盖之前的。

MySQL InnoDB 更新一条语句的流程

UPDATE user_info SET name = "marco" WHERE id = 1;
 
  1. 执行器先找引擎取出ID=1这一行,ID是主键,引擎直接用树搜索找到这一行,如果本来这一行所在的数据页就在内存中,就直接返回给执行器
  2. 执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新一行数据,再调用引擎接口写入这行新数据
  3. 引擎将这行新数据更新到内存中,同时将这个更新记录到redolog里面,此时redolog处于prepare状态,然后告知执行器执行任务完成了,随时可以提交事务
  4. 执行器生成这个操作的binlog,并把binlog卸乳磁盘
  5. 执行器调用引擎的提交事务接口,引擎把刚刚卸乳的redolog改为提交commit状态,更新完成

提示

注意:Mysql的redolog模块写入拆成2步走,prepare和commit,称为两阶段提交。 1.redolog的prepare状态 2. binlog的写入

如果binlog没有写入并没有提交事务回滚 -如果binlog写入事务没提交,数据库回复后自动完成commit

# 数据结构

数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优,MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构

# B树、B-树、B+树

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构

# B 树 即二叉搜索树

foo
  1. 所有非叶子结点至多拥有两个儿子(Left和Right)
  2. 所有结点存储一个关键字;
  3. 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树; +如果binlog写入事务没提交,数据库回复后自动完成commit

    # 基础拓扑

    foo

    # 数据结构

    数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优,MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构

    # B树、B-树、B+树

    目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构

    # B 树 即二叉搜索树

    foo
    1. 所有非叶子结点至多拥有两个儿子(Left和Right)
    2. 所有结点存储一个关键字;
    3. 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;
      foo

    B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;

    如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;

    foo

    但B树在经过多次插入与删除后,有可能导致不同的结构

    右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题;
    实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略;

    # B- Tree 一种多路搜索树(并不是二叉的)

    foo

    B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;

    1. 关键字集合分布在整颗树中;
    2. 任何一个关键字出现且只出现在一个结点中;
    3. 搜索有可能在非叶子结点结束;
    4. 其搜索性能等价于在关键字全集内做一次二分查找;
    5. 自动层次控制;

    由于B-Tree的特性,在B-Tree中按key检索数据的算法非常直观:首先从根节点进行二分查找,如果找到则返回对应节点的data,否则对相应区间的指针指向的节点递归进行查找,直到找到节点或找到null指针,前者查找成功,后者查找失败

    # B+ Tree B-树的变体,也是一种多路搜索树

    foo

    B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找

    1. 其定义基本与B-树同,除了:
    2. 非叶子结点的子树指针与关键字个数相同;
    3. 非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
    4. 为所有叶子结点增加一个链指针;
    5. 所有关键字都在叶子结点出现;

    一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。

    # 磁盘存取原理

    foo

    一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动(各个磁盘必须同步转动)。在磁盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不能转动,但是可以沿磁盘半径方向运动(实际是斜切向运动),每个磁头同一时刻也必须是同轴的,即从正上方向下看,所有磁头任何时候都是重叠的(不过目前已经有多磁头独立技术,可不受此限制)。

    盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存 储单元。

    当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做寻道时间,然后磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做旋转时间

    局部性原理与磁盘预读 @@ -136,11 +136,70 @@ 程序运行期间所需要的数据通常比较集中。

    由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。

    预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。

    数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧: 每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。 B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)

    一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。综上所述,用B-Tree作为索引结构效率是非常高的。而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。

    # MyISAM 索引实现

    MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

    MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分

    # InnoDB 索引实现

    虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

    1. InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
    2. 与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域 -InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择

    # 锁机制

    # 隔离级别

    # MVCC

    # InnoDB

    # Explain

    # 参考文献

- + diff --git a/zh/db/neo4j.html b/zh/db/neo4j.html index d5f1357..4d3938d 100644 --- a/zh/db/neo4j.html +++ b/zh/db/neo4j.html @@ -16,7 +16,7 @@ - + @@ -117,6 +117,6 @@

- + diff --git a/zh/db/postgreSQL.html b/zh/db/postgreSQL.html index 26ac5f0..bbe21c4 100644 --- a/zh/db/postgreSQL.html +++ b/zh/db/postgreSQL.html @@ -16,7 +16,7 @@ - + @@ -148,6 +148,6 @@

# 初始化 →

- + diff --git a/zh/db/redis.html b/zh/db/redis.html index 899b9a6..3245984 100644 --- a/zh/db/redis.html +++ b/zh/db/redis.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/devops/index.html b/zh/devops/index.html index 8686f5e..65b1f9b 100644 --- a/zh/devops/index.html +++ b/zh/devops/index.html @@ -16,7 +16,7 @@ - + @@ -113,6 +113,6 @@ GitHub

README.md

- + diff --git a/zh/distributed/index.html b/zh/distributed/index.html index 0ebeaaf..7573af1 100644 --- a/zh/distributed/index.html +++ b/zh/distributed/index.html @@ -16,7 +16,7 @@ - + @@ -113,6 +113,6 @@ GitHub

README.md

- + diff --git a/zh/guide/index.html b/zh/guide/index.html index 880741c..6feacef 100644 --- a/zh/guide/index.html +++ b/zh/guide/index.html @@ -16,7 +16,7 @@ - + @@ -113,6 +113,6 @@ GitHub

# 要怎样努力,才能成为很厉害的人

foo

我以前啊,和你一样,很想成为一个很厉害很厉害很厉害的人。

喜欢看热血的东西,幻想自己是屠龙的勇士,登塔的先锋,我左手有剑,右手有光,没头没脑的燃烧自己,敌人的骑军来了,我说你们何人堪与之战,我的女人在等我。

后来我现实了一点,我觉得我要成为那种说走就走,说日就日的男人,我梳大背头,流浪在欧洲或者新几内亚的,我拍孩子,拍野兽,拍流浪的雏妓,与罗伯特德尼罗握手,说嘿,我给你写了愤怒的公牛2。

再后来,我觉得我人生的梦想,是在城市中心买上一间顶层公寓,把一整面墙都改造成钢化玻璃,在灯火通明的夜晚,我就要端着酒站在巨大的窗前,看整个城市在呼吸,然后我的朋友叩门,他带来了一打嫩模,我们就玩一些成年人的游戏

现在,我发现龙并不存在,我不会骑马,不会用单反,家住2楼,我能做的,就是把眼前的事儿做好,赚到足够的钱,这样我可以给我的姑娘一个地球仪,然后用飞镖扎它,扎到哪儿,就去哪儿玩。

这样看来,虽然我的想法随着生殖器的发育,始终在变,但那个很厉害很厉害的人,一直离我很远,甚至越来越远。

我心中曾经执剑的少年,此刻也混迹在市井之间。

血似乎都凉了。

我也不是没有惶恐过,是不是我这一生,都不能左手持剑,右手握着罗伯特德尼罗,说这里的嫩模随便你玩但是你他妈别从窗户上掉下去。

这样一看,我逊得不行,我的朋友都是一些凡人,比我还逊,业余生活就是推塔、中单、跪。

我心想,我是不是这辈子都要做一个逊逼,直到我的坟墓上写好墓志铭,我甚至都想好了:

我来,我见,我挂了。

最后我给了自己一个否定的答复,我不要。

我喜欢我的朋友们,喜欢我现在的生活,首先我希望你明白,没有厉害与逊逼得区分,只有血的凉与热,有的人觉得生活就这样吧,我算了,现在没什么不好。

有的人觉得生活这样挺好,但是我还要更好。

这种只要剧情稍微热血一点就会热泪盈眶的傻逼,已经不多了,一刻也不要停留。

所以现在,我和你不一样了,我仍然想成为一个很厉害很厉害很厉害的人,像我们这种剧情稍微热血一点就会热泪盈眶的傻逼,要好好珍惜自己。

很多人坐下来了,跟你说你不行,说你省点儿心吧,说你请静一静。

汹涌的人群就把你这样的少年淹没了,人群散去的时候,你也不见了,你那些承诺,谁也听不见,这个世界对于你,就再不可能有什么更有趣更漂亮的女朋友。

你就失约了,小逼崽子。

这么跟你说。

虽然随着年龄的增长,我趋于现实,不能像你那样分分钟冲动的燃烧,然而我每时每刻都有想做的事,有想达成的目标。

不排除以后的某一年,我会握着罗伯特德尼罗的手,他说这是你写得吗,愤怒的公牛2,只要他还没死。

故事里拳王拉莫塔忍着伤,他举着铁拳,挥汗如雨,要和命运斗争,他说我怎么能失约呢,我是那个要成为很厉害很厉害的拳王拉莫塔!

小伙儿,成为很厉害很厉害的人,最重要的,就是要热血,永远也不要让你的血凉下去,你凉下去了,就再也不能找到一个更有趣更漂亮的女友,你就失约了,于是那天她踏梦而来,就成了一个彻头彻尾的笑话。

当有一天你成为你讨厌的那种人,浑浑噩噩,你走在街上,看见那些更有趣更漂亮的女孩,你会不会想起多年以前,你说我答应你,在一个承诺就是永远的年纪。

读书,交友,美容,都不如你这一腔狗血,滚烫,灼人,你要燃上大半辈子,才对得起你现在说的这些话。

我听闻最美的故事,是公主死去了,屠龙的少年还在燃烧。

火苗再小,你都要反复的点燃。

所谓热血的少年,青涩的爱恋,死亡与梦之约。

这么好的故事。

你可别演砸了。

最后我给你点个人建议:

  1. 读书,读到倦,网上有很多方法,但你从来沉不下心看。
  2. 学习,学到疼,网上有很多方法,但你从来沉不下心看。
  3. 开口说话,冷场也要说话,脸皮薄也要说话,挨打也要说话。
  4. 如果你现在不知道做什么,至少你还可以先从做一个牛逼的学生开始。
  5. 更漂亮更有趣的女孩,五年以后再找。
  6. 承诺是鞭子,不是兴奋剂。
  7. 年纪大了,也不要说什么心如死灰。

改变自己是非常,非常,非常痛苦的,我能看出来你一腔热血的优点,自然知道你孤僻懒散自以为是的缺点,方法很多,不过我不确定你吃不吃得了苦,我和你共勉吧。

在成为最厉害最厉害最厉害的道路上。

- + diff --git a/zh/index.html b/zh/index.html index 674bed1..9b530c6 100644 --- a/zh/index.html +++ b/zh/index.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@

简洁至上

以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。

- + diff --git a/zh/os/coroutines.html b/zh/os/coroutines.html index dec0caa..bad8239 100644 --- a/zh/os/coroutines.html +++ b/zh/os/coroutines.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/os/cpu.html b/zh/os/cpu.html index b912f1a..b091d8a 100644 --- a/zh/os/cpu.html +++ b/zh/os/cpu.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/os/index.html b/zh/os/index.html index 85c6abe..2565c38 100644 --- a/zh/os/index.html +++ b/zh/os/index.html @@ -16,7 +16,7 @@ - + @@ -113,6 +113,6 @@ GitHub

# 操作系统

- + diff --git a/zh/os/io.html b/zh/os/io.html index 8e9076e..b33d4a9 100644 --- a/zh/os/io.html +++ b/zh/os/io.html @@ -16,7 +16,7 @@ - + @@ -279,6 +279,6 @@ →

- + diff --git a/zh/os/linux.html b/zh/os/linux.html index f6cebd4..b13ede2 100644 --- a/zh/os/linux.html +++ b/zh/os/linux.html @@ -16,7 +16,7 @@ - + @@ -117,6 +117,6 @@

- + diff --git a/zh/os/process.html b/zh/os/process.html index f35ae8b..bcedf9e 100644 --- a/zh/os/process.html +++ b/zh/os/process.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/os/thread.html b/zh/os/thread.html index e05ec0a..f554527 100644 --- a/zh/os/thread.html +++ b/zh/os/thread.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/program/c.html b/zh/program/c.html index d40b744..72e5dd4 100644 --- a/zh/program/c.html +++ b/zh/program/c.html @@ -16,7 +16,7 @@ - + @@ -117,6 +117,6 @@

- + diff --git a/zh/program/golang.html b/zh/program/golang.html index 8f85cfa..f67f662 100644 --- a/zh/program/golang.html +++ b/zh/program/golang.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/program/index.html b/zh/program/index.html index da28819..87c2b77 100644 --- a/zh/program/index.html +++ b/zh/program/index.html @@ -16,7 +16,7 @@ - + @@ -129,6 +129,6 @@ 中间码依赖jvm,而不依赖于平台(操作系统),只要jvm支持中间码,中间就能运行,不同平台的兼容性,就由jvm来解决,开发者可以专注于开发业务逻辑,这解决了编译语言的跨平台问题。

但如果你代码发生了改变,仍然需要再次编译。

# 完全解释

PHP是完全解释,它一次编译都省了,直接由解释器加载源代码,就开始逐行翻译并运行。 那么,调试程序的时候,更改代码就能直接再次运行,不存在编译的步骤,它在跨平台的基础上,又为开发调试提供了便利。 但这不一定是好事,这将导致php每一次运行,都需要先解释,再执行,运行效率上比不上java的直接由jvm运行中间码。

当然,java半编译半解释,虽然通过jvm解决了跨平台问题,但运行效率上,也是比不上编译型语言的,因为编译型语言开发的程序运行时,计算机只需要关注程序本身的流程就好了,但java,jvm也是对计算机资源的一种开销,不过这种开销非常小,几乎可以忽略。

- + diff --git a/zh/program/javascript.html b/zh/program/javascript.html index b8ebdf8..719a644 100644 --- a/zh/program/javascript.html +++ b/zh/program/javascript.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- + diff --git a/zh/program/php.html b/zh/program/php.html index 11a9e60..76ee24a 100644 --- a/zh/program/php.html +++ b/zh/program/php.html @@ -16,7 +16,7 @@ - + @@ -345,6 +345,6 @@ →

- + diff --git a/zh/program/python.html b/zh/program/python.html index c620bda..92aa248 100644 --- a/zh/program/python.html +++ b/zh/program/python.html @@ -16,7 +16,7 @@ - + @@ -121,6 +121,6 @@ →

- +