diff --git a/README.md b/README.md index 464c4897..0f34e8e1 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,6 @@ 目录按《剑指 Offer 第二版》编排,在牛客网的在线编程中出现的题目都已ç»� AC。 -> [2016 校招真题题解](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/2016%20校招真题题解.md) - -未完æˆ� - # 网络 > [计算机网络](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/计算机网络.md) diff --git a/notes/MySQL.md b/notes/MySQL.md index e83bb6a0..f0fe5704 100644 --- a/notes/MySQL.md +++ b/notes/MySQL.md @@ -1,227 +1,249 @@ -* [存储引擎](#存储引擎) +* [ÊÂÎñËÄ´óÌØÐÔ](#ÊÂÎñËÄ´óÌØÐÔ) + * [1. Ô­×ÓÐÔ](#1-Ô­×ÓÐÔ) + * [2. Ò»ÖÂÐÔ](#2-Ò»ÖÂÐÔ) + * [3. ¸ôÀëÐÔ](#3-¸ôÀëÐÔ) + * [4. ³Ö¾ÃÐÔ](#4-³Ö¾ÃÐÔ) +* [´æ´¢ÒýÇæ](#´æ´¢ÒýÇæ) * [1. InnoDB](#1-innodb) * [2. MyISAM](#2-myisam) - * [3. InnoDB 与 MyISAM 的比较](#3-innodb-与-myisam-的比较) -* [æ•°æ�®ç±»åž‹](#æ•°æ�®ç±»åž‹) - * [1. æ•´åž‹](#1-æ•´åž‹) - * [2. 浮点数](#2-浮点数) - * [3. 字符串](#3-字符串) - * [4. 时间和日期](#4-时间和日期) -* [索引](#索引) - * [1. 索引分类](#1-索引分类) - * [1.1 B-Tree 索引](#11-b-tree-索引) - * [1.2 哈希索引](#12-哈希索引) - * [1.3. 空间索引数æ�®ï¼ˆR-Tree)](#13-空间索引数æ�®ï¼ˆr-tree)) - * [1.4 全文索引](#14-全文索引) - * [2. 索引的优点](#2-索引的优点) - * [3. 索引优化](#3-索引优化) - * [3.1 独立的列](#31-独立的列) - * [3.2 å‰�缀索引](#32-å‰�缀索引) - * [3.3 多列索引](#33-多列索引) - * [3.4 索引列的顺åº�](#34-索引列的顺åº�) - * [3.5 è�šç°‡ç´¢å¼•](#35-è�šç°‡ç´¢å¼•) - * [3.6 覆盖索引](#36-覆盖索引) - * [4. B-Tree å’Œ B+Tree 原ç�†](#4-b-tree-å’Œ-b+tree-原ç�†) + * [3. InnoDB Óë MyISAM µÄ±È½Ï](#3-innodb-Óë-myisam-µÄ±È½Ï) +* [Êý¾ÝÀàÐÍ](#Êý¾ÝÀàÐÍ) + * [1. ÕûÐÍ](#1-ÕûÐÍ) + * [2. ¸¡µãÊý](#2-¸¡µãÊý) + * [3. ×Ö·û´®](#3-×Ö·û´®) + * [4. ʱ¼äºÍÈÕÆÚ](#4-ʱ¼äºÍÈÕÆÚ) +* [Ë÷Òý](#Ë÷Òý) + * [1. Ë÷Òý·ÖÀà](#1-Ë÷Òý·ÖÀà) + * [1.1 B-Tree Ë÷Òý](#11-b-tree-Ë÷Òý) + * [1.2 ¹þÏ£Ë÷Òý](#12-¹þÏ£Ë÷Òý) + * [1.3. ¿Õ¼äË÷ÒýÊý¾Ý£¨R-Tree£©](#13-¿Õ¼äË÷ÒýÊý¾Ý£¨r-tree£©) + * [1.4 È«ÎÄË÷Òý](#14-È«ÎÄË÷Òý) + * [2. Ë÷ÒýµÄÓŵã](#2-Ë÷ÒýµÄÓŵã) + * [3. Ë÷ÒýÓÅ»¯](#3-Ë÷ÒýÓÅ»¯) + * [3.1 ¶ÀÁ¢µÄÁÐ](#31-¶ÀÁ¢µÄÁÐ) + * [3.2 ǰ׺Ë÷Òý](#32-ǰ׺Ë÷Òý) + * [3.3 ¶àÁÐË÷Òý](#33-¶àÁÐË÷Òý) + * [3.4 Ë÷ÒýÁеÄ˳Ðò](#34-Ë÷ÒýÁеÄ˳Ðò) + * [3.5 ¾Û´ØË÷Òý](#35-¾Û´ØË÷Òý) + * [3.6 ¸²¸ÇË÷Òý](#36-¸²¸ÇË÷Òý) + * [4. B-Tree ºÍ B+Tree Ô­Àí](#4-b-tree-ºÍ-b+tree-Ô­Àí) * [4. 1 B-Tree](#4-1-b-tree) * [4.2 B+Tree](#42-b+tree) - * [4.3 带有顺åº�访问指针的 B+Tree](#43-带有顺åº�访问指针的-b+tree) - * [4.4 为什么使用 B-Tree å’Œ B+Tree](#44-为什么使用-b-tree-å’Œ-b+tree) -* [查询性能优化](#查询性能优化) + * [4.3 ´øÓÐ˳Ðò·ÃÎÊÖ¸ÕëµÄ B+Tree](#43-´øÓÐ˳Ðò·ÃÎÊÖ¸ÕëµÄ-b+tree) + * [4.4 ΪʲôʹÓà B-Tree ºÍ B+Tree](#44-ΪʲôʹÓÃ-b-tree-ºÍ-b+tree) +* [²éѯÐÔÄÜÓÅ»¯](#²éѯÐÔÄÜÓÅ»¯) * [1. Explain](#1-explain) - * [2. å‡�少返回的列](#2-å‡�少返回的列) - * [3. å‡�少返回的行](#3-å‡�少返回的行) - * [4. 拆分大的 DELETE 或 INSERT 语å�¥](#4-拆分大的-delete-或-insert-语å�¥) -* [分库与分表](#分库与分表) -* [故障转移和故障æ�¢å¤�](#故障转移和故障æ�¢å¤�) - * [1. 故障转移](#1-故障转移) - * [2. æ•…éšœæ�¢å¤�](#2-æ•…éšœæ�¢å¤�) -* [å�‚考资料](#å�‚考资料) + * [2. ¼õÉÙ·µ»ØµÄÁÐ](#2-¼õÉÙ·µ»ØµÄÁÐ) + * [3. ¼õÉÙ·µ»ØµÄÐÐ](#3-¼õÉÙ·µ»ØµÄÐÐ) + * [4. ²ð·Ö´óµÄ DELETE »ò INSERT Óï¾ä](#4-²ð·Ö´óµÄ-delete-»ò-insert-Óï¾ä) +* [·Ö¿âÓë·Ö±í](#·Ö¿âÓë·Ö±í) +* [¹ÊÕÏ×ªÒÆºÍ¹ÊÕϻָ´](#¹ÊÕÏ×ªÒÆºÍ¹ÊÕϻָ´) + * [1. ¹ÊÕÏ×ªÒÆ](#1-¹ÊÕÏ×ªÒÆ) + * [2. ¹ÊÕϻָ´](#2-¹ÊÕϻָ´) +* [²Î¿¼×ÊÁÏ](#²Î¿¼×ÊÁÏ) +# ÊÂÎñËÄ´óÌØÐÔ -# 存储引擎 +## 1. Ô­×ÓÐÔ + +Ҫô¶¼Ö´ÐУ¬ÒªÃ´¶¼²»Ö´ÐС£ + +## 2. Ò»ÖÂÐÔ + +ÊÂÎñÖ´ÐÐǰºó¶¼±£³ÖÒ»ÖÂÐÔ״̬¡£ + +## 3. ¸ôÀëÐÔ + +¶à¸öÊÂÎñµ¥¶ÀÖ´ÐУ¬»¥²»Ó°Ïì¡£ + +## 4. ³Ö¾ÃÐÔ + +¼´Ê¹ÏµÍ³·¢Éú¹ÊÕÏ£¬ÊÂÎñÖ´ÐеĽá¹ûÒ²²»ÄܶªÊ§¡£ + +# ´æ´¢ÒýÇæ ## 1. InnoDB -InnoDB 是 MySQL 的默认事务型引擎,å�ªæœ‰åœ¨éœ€è¦� InnoDB ä¸�支æŒ�的特性时,æ‰�考虑使用其它存储引擎。 +InnoDB ÊÇ MySQL µÄĬÈÏÊÂÎñÐÍÒýÇæ£¬Ö»ÓÐÔÚÐèÒª InnoDB ²»Ö§³ÖµÄÌØÐÔʱ£¬²Å¿¼ÂÇʹÓÃÆäËü´æ´¢ÒýÇæ¡£ -采用 MVCC æ�¥æ”¯æŒ�高并å�‘,并且实现了四个标准的隔离级别,默认级别是å�¯é‡�å¤�读。 +²ÉÓà MVCC À´Ö§³Ö¸ß²¢·¢£¬²¢ÇÒʵÏÖÁËËĸö±ê×¼µÄ¸ôÀë¼¶±ð£¬Ä¬Èϼ¶±ðÊÇ¿ÉÖØ¸´¶Á¡£ -表是基于è�šç°‡ç´¢å¼•建立的,它对主键的查询性能有很高的æ��å�‡ã€‚ +±íÊÇ»ùÓÚ¾Û´ØË÷Òý½¨Á¢µÄ£¬Ëü¶ÔÖ÷¼üµÄ²éѯÐÔÄÜÓкܸߵÄÌáÉý¡£ -内部å�šäº†å¾ˆå¤šä¼˜åŒ–,包括从ç£�盘读å�–æ•°æ�®æ—¶é‡‡ç”¨çš„å�¯é¢„测性读,能够自动在内存中创建 hash 索引以加速读æ“�作的自适应哈希索引,以å�Šèƒ½å¤ŸåŠ é€Ÿæ�’å…¥æ“�作的æ�’入缓冲区等。 +ÄÚ²¿×öÁ˺ܶàÓÅ»¯£¬°üÀ¨´Ó´ÅÅ̶ÁÈ¡Êý¾Ýʱ²ÉÓõĿÉÔ¤²âÐÔ¶Á£¬Äܹ»×Ô¶¯ÔÚÄÚ´æÖд´½¨ hash Ë÷ÒýÒÔ¼ÓËÙ¶Á²Ù×÷µÄ×ÔÊÊÓ¦¹þÏ£Ë÷Òý£¬ÒÔ¼°Äܹ»¼ÓËÙ²åÈë²Ù×÷µÄ²åÈ뻺³åÇøµÈ¡£ -通过一些机制和工具支æŒ�真正的热备份。 +ͨ¹ýһЩ»úÖÆºÍ¹¤¾ßÖ§³ÖÕæÕýµÄÈȱ¸·Ý¡£ ## 2. MyISAM -MyISAM æ��供了大é‡�的特性,包括全文索引ã€�压缩ã€�空间函数(GIS)等。但 MyISAM ä¸�支æŒ�事务和行级é”�,而且奔溃å�Žæ— æ³•安全æ�¢å¤�。 +MyISAM ÌṩÁË´óÁ¿µÄÌØÐÔ£¬°üÀ¨È«ÎÄË÷Òý¡¢Ñ¹Ëõ¡¢¿Õ¼äº¯Êý£¨GIS£©µÈ¡£µ« MyISAM ²»Ö§³ÖÊÂÎñºÍÐм¶Ëø£¬¶øÇÒ±¼À£ºóÎÞ·¨°²È«»Ö¸´¡£ -å�ªèƒ½å¯¹æ•´å¼ è¡¨åŠ é”�,而ä¸�是针对行。 +Ö»ÄܶÔÕûÕűí¼ÓËø£¬¶ø²»ÊÇÕë¶ÔÐС£ -å�¯ä»¥æ‰‹å·¥æˆ–者自动执行检查和修å¤�æ“�作,但是和事务æ�¢å¤�以å�Šå¥”溃æ�¢å¤�ä¸�å�Œï¼Œå�¯èƒ½å¯¼è‡´ä¸€äº›æ•°æ�®ä¸¢å¤±ï¼Œè€Œä¸”ä¿®å¤�æ“�作是é�žå¸¸æ…¢çš„。 +¿ÉÒÔÊÖ¹¤»òÕß×Ô¶¯Ö´Ðмì²éºÍÐÞ¸´²Ù×÷£¬µ«ÊǺÍÊÂÎñ»Ö¸´ÒÔ¼°±¼À£»Ö¸´²»Í¬£¬¿ÉÄܵ¼ÖÂһЩÊý¾Ý¶ªÊ§£¬¶øÇÒÐÞ¸´²Ù×÷ÊǷdz£ÂýµÄ¡£ -å�¯ä»¥åŒ…å�«åЍæ€�或者é�™æ€�的行。 +¿ÉÒÔ°üº¬¶¯Ì¬»òÕß¾²Ì¬µÄÐС£ -如果指定了 DELAY_KEY_WRITE 选项,在æ¯�次修改执行完æˆ�时,ä¸�会立å�³å°†ä¿®æ”¹çš„索引数æ�®å†™å…¥ç£�盘,而是会写到内存中的键缓冲区,å�ªæœ‰åœ¨æ¸…ç�†é”®ç¼“冲区或者关闭表的时候æ‰�会将对应的索引å�—写入ç£�盘。这ç§�æ–¹å¼�å�¯ä»¥æž�大的æ��å�‡å†™å…¥æ€§èƒ½ï¼Œä½†æ˜¯åœ¨æ•°æ�®åº“或者主机奔溃时会造æˆ�索引æ�Ÿå��,需è¦�执行修å¤�æ“�作。 +Èç¹ûÖ¸¶¨ÁË DELAY_KEY_WRITE Ñ¡ÏÔÚÿ´ÎÐÞ¸ÄÖ´ÐÐÍê³Éʱ£¬²»»áÁ¢¼´½«Ð޸ĵÄË÷ÒýÊý¾ÝдÈë´ÅÅÌ£¬¶øÊÇ»áдµ½ÄÚ´æÖеļü»º³åÇø£¬Ö»ÓÐÔÚÇåÀí¼ü»º³åÇø»òÕ߹رձíµÄʱºò²Å»á½«¶ÔÓ¦µÄË÷Òý¿éдÈë´ÅÅÌ¡£ÕâÖÖ·½Ê½¿ÉÒÔ¼«´óµÄÌáÉýдÈëÐÔÄÜ£¬µ«ÊÇÔÚÊý¾Ý¿â»òÕßÖ÷»ú±¼À£Ê±»áÔì³ÉË÷ÒýË𻵣¬ÐèÒªÖ´ÐÐÐÞ¸´²Ù×÷¡£ -如果表在创建并导入数æ�®ä»¥å�Žï¼Œä¸�会å†�进行修改æ“�作,那么这样的表适å�ˆé‡‡ç”¨ MyISAM 压缩表。 +Èç¹û±íÔÚ´´½¨²¢µ¼ÈëÊý¾ÝÒԺ󣬲»»áÔÙ½øÐÐÐ޸IJÙ×÷£¬ÄÇôÕâÑùµÄ±íÊʺϲÉÓà MyISAM ѹËõ±í¡£ -对于å�ªè¯»æ•°æ�®ï¼Œæˆ–者表比较å°�ã€�å�¯ä»¥å®¹å¿�ä¿®å¤�æ“�作,则ä¾�ç„¶å�¯ä»¥ç»§ç»­ä½¿ç”¨ MyISAM。 +¶ÔÓÚÖ»¶ÁÊý¾Ý£¬»òÕß±í±È½ÏС¡¢¿ÉÒÔÈÝÈÌÐÞ¸´²Ù×÷£¬ÔòÒÀÈ»¿ÉÒÔ¼ÌÐøÊ¹Óà MyISAM¡£ -MyISAM 设计简å�•,数æ�®ä»¥ç´§å¯†æ ¼å¼�存储,所以在æŸ�些场景下性能很好。 +MyISAM Éè¼Æ¼òµ¥£¬Êý¾ÝÒÔ½ôÃܸñʽ´æ´¢£¬ËùÒÔÔÚijЩ³¡¾°ÏÂÐÔÄܺܺᣠ-## 3. InnoDB 与 MyISAM 的比较 +## 3. InnoDB Óë MyISAM µÄ±È½Ï -**事务** +**ÊÂÎñ** -InnoDB 是事务型的。 +InnoDB ÊÇÊÂÎñÐ͵ġ£ -**备份** +**±¸·Ý** -InnoDB 支æŒ�在线热备份。 +InnoDB Ö§³ÖÔÚÏßÈȱ¸·Ý¡£ -**奔溃æ�¢å¤�** +**±¼À£»Ö¸´** -MyISAM 奔溃å�Žå�‘生æ�Ÿå��的概率比 InnoDB 高很多,而且æ�¢å¤�的速度也更慢。 +MyISAM ±¼À£ºó·¢ÉúË𻵵ĸÅÂÊ±È InnoDB ¸ßºÜ¶à£¬¶øÇÒ»Ö¸´µÄËÙ¶ÈÒ²¸üÂý¡£ -**å¹¶å�‘** +**²¢·¢** -MyISAM å�ªæ”¯æŒ�表级é”�,而 InnoDB 还支æŒ�行级é”�。 +MyISAM Ö»Ö§³Ö±í¼¶Ëø£¬¶ø InnoDB »¹Ö§³ÖÐм¶Ëø¡£ -**其它特性** +**ÆäËüÌØÐÔ** -MyISAM 支æŒ�全文索引,地ç�†ç©ºé—´ç´¢å¼•ï¼› +MyISAM Ö§³ÖÈ«ÎÄË÷Òý£¬µØÀí¿Õ¼äË÷Òý£» -# æ•°æ�®ç±»åž‹ +# Êý¾ÝÀàÐÍ -## 1. æ•´åž‹ +## 1. ÕûÐÍ -TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 分别使用 8, 16, 24, 64 ä½�存储空间,一般情况下越å°�的列越好。 +TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT ·Ö±ðʹÓà 8, 16, 24, 64 λ´æ´¢¿Õ¼ä£¬Ò»°ãÇé¿öÏÂԽСµÄÁÐÔ½ºÃ¡£ -INT(11) 中的数字å�ªæ˜¯è§„定了交互工具显示字符的个数,对于存储和计算æ�¥è¯´æ˜¯æ²¡æœ‰æ„�义的。 +INT(11) ÖеÄÊý×ÖÖ»Êǹ涨Á˽»»¥¹¤¾ßÏÔʾ×Ö·ûµÄ¸öÊý£¬¶ÔÓÚ´æ´¢ºÍ¼ÆËãÀ´ËµÊÇûÓÐÒâÒåµÄ¡£ -## 2. 浮点数 +## 2. ¸¡µãÊý -FLOAT å’Œ DOUBLE 为浮点类型,DECIMAL 为高精度å°�数类型。CPU 原生支æŒ�浮点è¿�算,但是ä¸�支æŒ� DECIMAl 类型的计算,因此 DECIMAL 的计算比浮点类型需è¦�更高的代价。 +FLOAT ºÍ DOUBLE Ϊ¸¡µãÀàÐÍ£¬DECIMAL Ϊ¸ß¾«¶ÈСÊýÀàÐÍ¡£CPU Ô­ÉúÖ§³Ö¸¡µãÔËË㣬µ«ÊDz»Ö§³Ö DECIMAl ÀàÐ͵ļÆË㣬Òò´Ë DECIMAL µÄ¼ÆËã±È¸¡µãÀàÐÍÐèÒª¸ü¸ßµÄ´ú¼Û¡£ -FLOATã€�DOUBLE å’Œ DECIMAL 都å�¯ä»¥æŒ‡å®šåˆ—宽,例如 DECIMAL(18, 9) 表示总共 18 ä½�,å�– 9 ä½�存储å°�数部分,剩下 9 ä½�存储整数部分。 +FLOAT¡¢DOUBLE ºÍ DECIMAL ¶¼¿ÉÒÔÖ¸¶¨ÁÐ¿í£¬ÀýÈç DECIMAL(18, 9) ±íʾ×ܹ² 18 λ£¬È¡ 9 λ´æ´¢Ð¡Êý²¿·Ö£¬Ê£Ï 9 λ´æ´¢ÕûÊý²¿·Ö¡£ -## 3. 字符串 +## 3. ×Ö·û´® -主è¦�有 CHAR å’Œ VARCHAR 两ç§�类型,一ç§�是定长的,一ç§�是å�˜é•¿çš„。 +Ö÷ÒªÓÐ CHAR ºÍ VARCHAR Á½ÖÖÀàÐÍ£¬Ò»ÖÖÊǶ¨³¤µÄ£¬Ò»ÖÖÊDZ䳤µÄ¡£ -VARCHAR è¿™ç§�å�˜é•¿ç±»åž‹èƒ½å¤ŸèŠ‚çœ�空间,因为å�ªéœ€è¦�存储必è¦�的内容。但是在执行 UPDATE æ—¶å�¯èƒ½ä¼šä½¿è¡Œå�˜å¾—比原æ�¥é•¿ï¼Œå½“超出一个页所能容纳的大å°�时,就è¦�执行é¢�外的æ“�作,MyISAM 会将行拆æˆ�ä¸�å�Œçš„片段存储,而 InnoDB 则需è¦�分裂页æ�¥ä½¿è¡Œæ”¾è¿›é¡µå†…。 +VARCHAR ÕâÖֱ䳤ÀàÐÍÄܹ»½ÚÊ¡¿Õ¼ä£¬ÒòΪֻÐèÒª´æ´¢±ØÒªµÄÄÚÈÝ¡£µ«ÊÇÔÚÖ´ÐÐ UPDATE ʱ¿ÉÄÜ»áʹÐбäµÃ±ÈÔ­À´³¤£¬µ±³¬³öÒ»¸öÒ³ËùÄÜÈÝÄɵĴóСʱ£¬¾ÍÒªÖ´ÐжîÍâµÄ²Ù×÷£¬MyISAM »á½«Ðвð³É²»Í¬µÄƬ¶Î´æ´¢£¬¶ø InnoDB ÔòÐèÒª·ÖÁÑÒ³À´Ê¹ÐзŽøÒ³ÄÚ¡£ -VARCHAR 会ä¿�留字符串末尾的空格,而 CHAR 会删除。 +VARCHAR »á±£Áô×Ö·û´®Ä©Î²µÄ¿Õ¸ñ£¬¶ø CHAR »áɾ³ý¡£ -## 4. 时间和日期 +## 4. ʱ¼äºÍÈÕÆÚ -MySQL æ��供了两ç§�相似的日期时间类型:DATATIME å’Œ TIMESTAMP。 +MySQL ÌṩÁËÁ½ÖÖÏàËÆµÄÈÕÆÚʱ¼äÀàÐÍ£ºDATATIME ºÍ TIMESTAMP¡£ **DATATIME** -能够ä¿�存从 1001 年到 9999 年的日期和时间,精度为秒,使用 8 字节的存储空间。 +Äܹ»±£´æ´Ó 1001 Äêµ½ 9999 ÄêµÄÈÕÆÚºÍʱ¼ä£¬¾«¶ÈΪÃ룬ʹÓà 8 ×ֽڵĴ洢¿Õ¼ä¡£ -它与时区无关。 +ËüÓëÊ±ÇøÎ޹ء£ -默认情况下,MySQL 以一ç§�å�¯æŽ’åº�çš„ã€�无歧义的格å¼�显示 DATATIME 值,例如“2008-01016 22:37:08â€�,这是 ANSI 标准定义的日期和时间表示方法。 +ĬÈÏÇé¿öÏ£¬MySQL ÒÔÒ»ÖÖ¿ÉÅÅÐòµÄ¡¢ÎÞÆçÒåµÄ¸ñʽÏÔʾ DATATIME Öµ£¬ÀýÈç¡°2008-01016 22:37:08¡±£¬ÕâÊÇ ANSI ±ê×¼¶¨ÒåµÄÈÕÆÚºÍʱ¼ä±íʾ·½·¨¡£ **TIMESTAMP** -å’Œ UNIX 时间戳相å�Œï¼Œä¿�存从 1970 å¹´ 1 月 1 æ—¥å�ˆå¤œï¼ˆæ ¼æž—å¨�治时间)以æ�¥çš„秒数,使用 4 个字节,å�ªèƒ½è¡¨ç¤ºä»Ž 1970 å¹´ 到 2038 年。 +ºÍ UNIX ʱ¼ä´ÁÏàͬ£¬±£´æ´Ó 1970 Äê 1 Ô 1 ÈÕÎçÒ¹£¨¸ñÁÖÍþÖÎʱ¼ä£©ÒÔÀ´µÄÃëÊý£¬Ê¹Óà 4 ¸ö×Ö½Ú£¬Ö»Äܱíʾ´Ó 1970 Äê µ½ 2038 Äê¡£ -它和时区有关。 +ËüºÍÊ±ÇøÓйء£ -MySQL æ��供了 FROM_UNIXTIME() 函数把 Unxi 时间戳转æ�¢ä¸ºæ—¥æœŸï¼Œå¹¶æ��供了 UNIX_TIMESTAMP() 函数把日期转æ�¢ä¸º Unix 时间戳。 +MySQL ÌṩÁË FROM_UNIXTIME() º¯Êý°Ñ Unxi ʱ¼ä´Áת»»ÎªÈÕÆÚ£¬²¢ÌṩÁË UNIX_TIMESTAMP() º¯Êý°ÑÈÕÆÚת»»Îª Unix ʱ¼ä´Á¡£ -默认情况下,如果æ�’入时没有指定 TIMESTAMP 列的值,会将这个值设置为当å‰�时间。 +ĬÈÏÇé¿öÏ£¬Èç¹û²åÈëʱûÓÐÖ¸¶¨ TIMESTAMP ÁеÄÖµ£¬»á½«Õâ¸öÖµÉèÖÃΪµ±Ç°Ê±¼ä¡£ -应该尽é‡�使用 TIMESTAMP,因为它比 DATETIME 空间效率更高。 +Ó¦¸Ã¾¡Á¿Ê¹Óà TIMESTAMP£¬ÒòΪËü±È DATETIME ¿Õ¼äЧÂʸü¸ß¡£ -# 索引 +# Ë÷Òý -索引是在存储引擎层实现的,而ä¸�是在æœ�务器层实现的,所以ä¸�å�Œå­˜å‚¨å¼•擎具有ä¸�å�Œçš„索引类型和实现。 +Ë÷ÒýÊÇÔÚ´æ´¢ÒýÇæ²ãʵÏֵ쬶ø²»ÊÇÔÚ·þÎñÆ÷²ãʵÏֵģ¬ËùÒÔ²»Í¬´æ´¢ÒýÇæ¾ßÓв»Í¬µÄË÷ÒýÀàÐͺÍʵÏÖ¡£ -索引能够轻易将查询性能æ��å�‡å‡ ä¸ªæ•°é‡�级。 +Ë÷ÒýÄܹ»ÇáÒ×½«²éѯÐÔÄÜÌáÉý¼¸¸öÊýÁ¿¼¶¡£ -对于é�žå¸¸å°�的表ã€�大部分情况下简å�•的全表扫æ��比建立索引更高效。对于中到大型的表,索引就é�žå¸¸æœ‰æ•ˆã€‚但是对于特大型的表,建立和使用索引的代价将会éš�之增长。这ç§�情况下,需è¦�用到一ç§�技术å�¯ä»¥ç›´æŽ¥åŒºåˆ†å‡ºéœ€è¦�查询的一组数æ�®ï¼Œè€Œä¸�是一æ�¡è®°å½•一æ�¡è®°å½•地匹é…�,例如å�¯ä»¥ä½¿ç”¨åˆ†åŒºæŠ€æœ¯ã€‚ +¶ÔÓڷdz£Ð¡µÄ±í¡¢´ó²¿·ÖÇé¿öϼòµ¥µÄÈ«±íɨÃè±È½¨Á¢Ë÷Òý¸ü¸ßЧ¡£¶ÔÓÚÖе½´óÐÍµÄ±í£¬Ë÷Òý¾Í·Ç³£ÓÐЧ¡£µ«ÊǶÔÓÚÌØ´óÐÍµÄ±í£¬½¨Á¢ºÍʹÓÃË÷ÒýµÄ´ú¼Û½«»áËæÖ®Ôö³¤¡£ÕâÖÖÇé¿öÏ£¬ÐèÒªÓõ½Ò»ÖÖ¼¼Êõ¿ÉÒÔÖ±½ÓÇø·Ö³öÐèÒª²éѯµÄÒ»×éÊý¾Ý£¬¶ø²»ÊÇÒ»Ìõ¼Ç¼һÌõ¼Ç¼µØÆ¥Å䣬ÀýÈç¿ÉÒÔʹÓ÷ÖÇø¼¼Êõ¡£ -## 1. 索引分类 +## 1. Ë÷Òý·ÖÀà -### 1.1 B-Tree 索引 +### 1.1 B-Tree Ë÷Òý -B-Tree 索引是大多数 MySQL 存储引擎的默认索引类型。 +B-Tree Ë÷ÒýÊÇ´ó¶àÊý MySQL ´æ´¢ÒýÇæµÄĬÈÏË÷ÒýÀàÐÍ¡£ -因为ä¸�å†�需è¦�进行全表扫æ��,å�ªéœ€è¦�对树进行æ�œç´¢å�³å�¯ï¼Œå› æ­¤æŸ¥æ‰¾é€Ÿåº¦å¿«å¾ˆå¤šã€‚ +ÒòΪ²»ÔÙÐèÒª½øÐÐÈ«±íɨÃ裬ֻÐèÒª¶ÔÊ÷½øÐÐËÑË÷¼´¿É£¬Òò´Ë²éÕÒËÙ¶È¿ìºÜ¶à¡£ -å�¯ä»¥æŒ‡å®šå¤šä¸ªåˆ—作为索引列,多个索引列共å�Œç»„æˆ�键。B-Tree 索引适用于全键值ã€�键值范围和键å‰�缀查找,其中键å‰�缀查找å�ªé€‚用于最左å‰�缀查找。 +¿ÉÒÔÖ¸¶¨¶à¸öÁÐ×÷ΪË÷ÒýÁУ¬¶à¸öË÷ÒýÁй²Í¬×é³É¼ü¡£B-Tree Ë÷ÒýÊÊÓÃÓÚÈ«¼üÖµ¡¢¼üÖµ·¶Î§ºÍ¼üǰ׺²éÕÒ£¬ÆäÖмüǰ׺²éÕÒÖ»ÊÊÓÃÓÚ×î×óǰ׺²éÕÒ¡£ -除了用于查找,还å�¯ä»¥ç”¨äºŽæŽ’åº�和分组。 +³ýÁËÓÃÓÚ²éÕÒ£¬»¹¿ÉÒÔÓÃÓÚÅÅÐòºÍ·Ö×é¡£ -如果ä¸�是按照索引列的顺åº�进行查找,则无法使用索引。 +Èç¹û²»Êǰ´ÕÕË÷ÒýÁеÄ˳Ðò½øÐвéÕÒ£¬ÔòÎÞ·¨Ê¹ÓÃË÷Òý¡£ -### 1.2 哈希索引 +### 1.2 ¹þÏ£Ë÷Òý -基于哈希表实现,优点是查找é�žå¸¸å¿«ã€‚ +»ùÓÚ¹þÏ£±íʵÏÖ£¬ÓŵãÊDzéÕҷdz£¿ì¡£ -在 MySQL 中å�ªæœ‰ Memory 引擎显å¼�支æŒ�哈希索引。 +ÔÚ MySQL ÖÐÖ»ÓÐ Memory ÒýÇæÏÔʽ֧³Ö¹þÏ£Ë÷Òý¡£ -InnoDB 引擎有一个特殊的功能å�«â€œè‡ªé€‚应哈希索引â€�,当æŸ�个索引值被使用的é�žå¸¸é¢‘ç¹�时,会在 B-Tree 索引之上å†�创建一个哈希索引,这样就让 B-Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。 +InnoDB ÒýÇæÓÐÒ»¸öÌØÊâµÄ¹¦ÄܽС°×ÔÊÊÓ¦¹þÏ£Ë÷Òý¡±£¬µ±Ä³¸öË÷ÒýÖµ±»Ê¹Óõķdz£Æµ·±Ê±£¬»áÔÚ B-Tree Ë÷ÒýÖ®ÉÏÔÙ´´½¨Ò»¸ö¹þÏ£Ë÷Òý£¬ÕâÑù¾ÍÈà B-Tree Ë÷Òý¾ßÓйþÏ£Ë÷ÒýµÄһЩÓŵ㣬±ÈÈç¿ìËٵĹþÏ£²éÕÒ¡£ -é™�制:哈希索引å�ªåŒ…å�«å“ˆå¸Œå€¼å’Œè¡ŒæŒ‡é’ˆï¼Œè€Œä¸�存储字段值,所以ä¸�能使用索引中的值æ�¥é�¿å…�读å�–行。ä¸�过,访问内存中的行的速度很快,所以大部分情况下这一点对性能影å“�å¹¶ä¸�明显;无法用于分组与排åº�ï¼›å�ªæ”¯æŒ�精确查找,无法用于部分查找和范围查找;如果哈希冲çª�很多,查找速度会å�˜å¾—很慢。 +ÏÞÖÆ£º¹þÏ£Ë÷ÒýÖ»°üº¬¹þÏ£ÖµºÍÐÐÖ¸Õ룬¶ø²»´æ´¢×Ö¶ÎÖµ£¬ËùÒÔ²»ÄÜʹÓÃË÷ÒýÖеÄÖµÀ´±ÜÃâ¶ÁÈ¡ÐС£²»¹ý£¬·ÃÎÊÄÚ´æÖеÄÐеÄËٶȺܿ죬ËùÒԴ󲿷ÖÇé¿öÏÂÕâÒ»µã¶ÔÐÔÄÜÓ°Ïì²¢²»Ã÷ÏÔ£»ÎÞ·¨ÓÃÓÚ·Ö×éÓëÅÅÐò£»Ö»Ö§³Ö¾«È·²éÕÒ£¬ÎÞ·¨ÓÃÓÚ²¿·Ö²éÕҺͷ¶Î§²éÕÒ£»Èç¹û¹þÏ£³åÍ»ºÜ¶à£¬²éÕÒËÙ¶È»á±äµÃºÜÂý¡£ -### 1.3. 空间索引数æ�®ï¼ˆR-Tree) +### 1.3. ¿Õ¼äË÷ÒýÊý¾Ý£¨R-Tree£© -MyISAM 存储引擎支æŒ�空间索引,å�¯ä»¥ç”¨äºŽåœ°ç�†æ•°æ�®å­˜å‚¨ã€‚ +MyISAM ´æ´¢ÒýÇæÖ§³Ö¿Õ¼äË÷Òý£¬¿ÉÒÔÓÃÓÚµØÀíÊý¾Ý´æ´¢¡£ -空间索引会从所有维度æ�¥ç´¢å¼•æ•°æ�®ï¼Œå�¯ä»¥æœ‰æ•ˆåœ°ä½¿ç”¨ä»»æ„�维度æ�¥è¿›è¡Œç»„å�ˆæŸ¥è¯¢ã€‚ +¿Õ¼äË÷Òý»á´ÓËùÓÐά¶ÈÀ´Ë÷ÒýÊý¾Ý£¬¿ÉÒÔÓÐЧµØÊ¹ÓÃÈÎÒâά¶ÈÀ´½øÐÐ×éºÏ²éѯ¡£ -### 1.4 全文索引 +### 1.4 È«ÎÄË÷Òý -MyISAM 存储引擎支æŒ�全文索引,用于查找文本中的关键è¯�,而ä¸�是直接比较索引中的值。 +MyISAM ´æ´¢ÒýÇæÖ§³ÖÈ«ÎÄË÷Òý£¬ÓÃÓÚ²éÕÒÎı¾ÖеĹؼü´Ê£¬¶ø²»ÊÇÖ±½Ó±È½ÏË÷ÒýÖеÄÖµ¡£ -使用 MATCH AGAINST,而ä¸�是普通的 WHERE。 +ʹÓà MATCH AGAINST£¬¶ø²»ÊÇÆÕͨµÄ WHERE¡£ -## 2. 索引的优点 +## 2. Ë÷ÒýµÄÓŵã -- 大大å‡�少了æœ�务器需è¦�扫æ��的数æ�®é‡�ï¼› +- ´ó´ó¼õÉÙÁË·þÎñÆ÷ÐèҪɨÃèµÄÊý¾ÝÁ¿£» -- 帮助æœ�务器é�¿å…�进行排åº�和创建临时表; +- °ïÖú·þÎñÆ÷±ÜÃâ½øÐÐÅÅÐòºÍ´´½¨ÁÙʱ±í£» -- å°†éš�机 I/O å�˜ä¸ºé¡ºåº� I/O。 +- ½«Ëæ»ú I/O ±äΪ˳Ðò I/O¡£ -## 3. 索引优化 +## 3. Ë÷ÒýÓÅ»¯ -### 3.1 独立的列 +### 3.1 ¶ÀÁ¢µÄÁÐ -在进行查询时,索引列ä¸�能是表达å¼�的一部分,也ä¸�能是函数的å�‚数,å�¦åˆ™æ— æ³•使用索引。 +ÔÚ½øÐвéѯʱ£¬Ë÷ÒýÁв»ÄÜÊDZí´ïʽµÄÒ»²¿·Ö£¬Ò²²»ÄÜÊǺ¯ÊýµÄ²ÎÊý£¬·ñÔòÎÞ·¨Ê¹ÓÃË÷Òý¡£ -例如下é�¢çš„æŸ¥è¯¢ä¸�能使用 actor_id 列的索引: +ÀýÈçÏÂÃæµÄ²éѯ²»ÄÜʹÓà actor_id ÁеÄË÷Òý£º ```sql SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; ``` -### 3.2 å‰�缀索引 +### 3.2 ǰ׺Ë÷Òý -对于 BLOBã€�TEXT å’Œ VARCHAR 类型的列,必须使用å‰�缀索引,å�ªç´¢å¼•开始的部分字符。 +¶ÔÓÚ BLOB¡¢TEXT ºÍ VARCHAR ÀàÐ͵ÄÁУ¬±ØÐëʹÓÃǰ׺Ë÷Òý£¬Ö»Ë÷Òý¿ªÊ¼µÄ²¿·Ö×Ö·û¡£ -对于å‰�缀长度的选å�–需è¦�æ ¹æ�® **索引选择性** æ�¥ç¡®å®šï¼šä¸�é‡�å¤�的索引值和记录总数的比值。选择性越高,查询效率也越高。最大值为 1 ,此时æ¯�个记录都有唯一的索引与其对应。 +¶ÔÓÚǰ׺³¤¶ÈµÄѡȡÐèÒª¸ù¾Ý **Ë÷ÒýÑ¡ÔñÐÔ** À´È·¶¨£º²»Öظ´µÄË÷ÒýÖµºÍ¼Ç¼×ÜÊýµÄ±ÈÖµ¡£Ñ¡ÔñÐÔÔ½¸ß£¬²éѯЧÂÊÒ²Ô½¸ß¡£×î´óֵΪ 1 £¬´Ëʱÿ¸ö¼Ç¼¶¼ÓÐΨһµÄË÷ÒýÓëÆä¶ÔÓ¦¡£ -### 3.3 多列索引 +### 3.3 ¶àÁÐË÷Òý -在需è¦�使用多个列作为æ�¡ä»¶è¿›è¡ŒæŸ¥è¯¢æ—¶ï¼Œä½¿ç”¨å¤šåˆ—索引比使用多个å�•列索引性能更好。例如下é�¢çš„语å�¥ä¸­ï¼Œæœ€å¥½æŠŠ actor_id å’Œ file_id 设置为多列索引。 +ÔÚÐèҪʹÓöà¸öÁÐ×÷ΪÌõ¼þ½øÐвéѯʱ£¬Ê¹ÓöàÁÐË÷Òý±ÈʹÓöà¸öµ¥ÁÐË÷ÒýÐÔÄܸüºÃ¡£ÀýÈçÏÂÃæµÄÓï¾äÖУ¬×îºÃ°Ñ actor_id ºÍ file_id ÉèÖÃΪ¶àÁÐË÷Òý¡£ ```sql SELECT file_id, actor_ id FROM sakila.film_actor WhERE actor_id = 1 OR film_id = 1; ``` -### 3.4 索引列的顺åº� +### 3.4 Ë÷ÒýÁеÄ˳Ðò -让选择性最强的索引列放在å‰�é�¢ï¼Œä¾‹å¦‚下é�¢æ˜¾ç¤ºçš„结果中 customer_id 的选择性比 staff_id 更高,因此最好把 customer_id 列放在多列索引的å‰�é�¢ã€‚ +ÈÃÑ¡ÔñÐÔ×îÇ¿µÄË÷ÒýÁзÅÔÚÇ°Ãæ£¬ÀýÈçÏÂÃæÏÔʾµÄ½á¹ûÖÐ customer_id µÄÑ¡ÔñÐÔ±È staff_id ¸ü¸ß£¬Òò´Ë×îºÃ°Ñ customer_id ÁзÅÔÚ¶àÁÐË÷ÒýµÄÇ°Ãæ¡£ ```sql SELECT COUNT(DISTINCT staff_id)/COUNT(*) AS staff_id_selectivity, @@ -236,107 +258,107 @@ customer_id_selectivity: 0.0373 COUNT(*): 16049 ``` -### 3.5 è�šç°‡ç´¢å¼• +### 3.5 ¾Û´ØË÷Òý ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b9e9ae8c-e216-4c01-b267-a50dbeb98fa4.jpg) -è�šç°‡ç´¢å¼•å¹¶ä¸�是一ç§�索引类型,而是一ç§�æ•°æ�®å­˜å‚¨æ–¹å¼�。 +¾Û´ØË÷Òý²¢²»ÊÇÒ»ÖÖË÷ÒýÀàÐÍ£¬¶øÊÇÒ»ÖÖÊý¾Ý´æ´¢·½Ê½¡£ -术语“è�šç°‡â€�表示数æ�®è¡Œå’Œç›¸é‚»çš„键值紧密地存储在一起,InnoDB çš„è�šç°‡ç´¢å¼•的数æ�®è¡Œå­˜æ”¾åœ¨ B-Tree çš„å�¶å­�页中。 +ÊõÓï¡°¾Û´Ø¡±±íʾÊý¾ÝÐкÍÏàÁڵļüÖµ½ôÃܵش洢ÔÚÒ»Æð£¬InnoDB µÄ¾Û´ØË÷ÒýµÄÊý¾ÝÐдæ·ÅÔÚ B-Tree µÄÒ¶×ÓÒ³ÖС£ -因为无法把数æ�®è¡Œå­˜æ”¾åœ¨ä¸¤ä¸ªä¸�å�Œçš„地方,所以一个表å�ªèƒ½æœ‰ä¸€ä¸ªè�šç°‡ç´¢å¼•。 +ÒòΪÎÞ·¨°ÑÊý¾ÝÐдæ·ÅÔÚÁ½¸ö²»Í¬µÄµØ·½£¬ËùÒÔÒ»¸ö±íÖ»ÄÜÓÐÒ»¸ö¾Û´ØË÷Òý¡£ -**优点** +**Óŵã** -1. å�¯ä»¥æŠŠç›¸å…³æ•°æ�®ä¿�存在一起,å‡�å°‘ I/O æ“�作; -2. 因为数æ�®ä¿�存在 B-Tree 中,因此数æ�®è®¿é—®æ›´å¿«ã€‚ +1. ¿ÉÒÔ°ÑÏà¹ØÊý¾Ý±£´æÔÚÒ»Æð£¬¼õÉÙ I/O ²Ù×÷£» +2. ÒòΪÊý¾Ý±£´æÔÚ B-Tree ÖУ¬Òò´ËÊý¾Ý·ÃÎʸü¿ì¡£ -**缺点** +**ȱµã** -1. è�šç°‡ç´¢å¼•最大é™�度æ��高了 I/O 密集型应用的性能,但是如果数æ�®å…¨éƒ¨æ”¾åœ¨å†…存,就没必è¦�用è�šç°‡ç´¢å¼•。 -2. æ�’入速度严é‡�ä¾�赖于æ�’入顺åº�,按主键的顺åº�æ�’入是最快的。 -3. æ›´æ–°æ“�作代价很高,因为æ¯�个被更新的行都会移动到新的ä½�置。 -4. 当æ�’入到æŸ�个已满的页中,存储引擎会将该页分裂æˆ�两个页é�¢æ�¥å®¹çº³è¯¥è¡Œï¼Œé¡µåˆ†è£‚会导致表å� ç”¨æ›´å¤šçš„ç£�盘空间。 -5. 如果行比较稀ç–�,或者由于页分裂导致数æ�®å­˜å‚¨ä¸�连续时,è�šç°‡ç´¢å¼•å�¯èƒ½å¯¼è‡´å…¨è¡¨æ‰«æ��速度å�˜æ…¢ã€‚ +1. ¾Û´ØË÷Òý×î´óÏÞ¶ÈÌá¸ßÁË I/O Ãܼ¯ÐÍÓ¦ÓõÄÐÔÄÜ£¬µ«ÊÇÈç¹ûÊý¾ÝÈ«²¿·ÅÔÚÄڴ棬¾Íû±ØÒªÓþ۴ØË÷Òý¡£ +2. ²åÈëËÙ¶ÈÑÏÖØÒÀÀµÓÚ²åÈë˳Ðò£¬°´Ö÷¼üµÄ˳Ðò²åÈëÊÇ×î¿ìµÄ¡£ +3. ¸üвÙ×÷´ú¼ÛºÜ¸ß£¬ÒòΪÿ¸ö±»¸üеÄÐж¼»áÒÆ¶¯µ½ÐµÄλÖᣠ+4. µ±²åÈ뵽ij¸öÒÑÂúµÄÒ³ÖУ¬´æ´¢ÒýÇæ»á½«¸ÃÒ³·ÖÁѳÉÁ½¸öÒ³ÃæÀ´ÈÝÄɸÃÐУ¬Ò³·ÖÁѻᵼÖ±íÕ¼Óøü¶àµÄ´ÅÅ̿ռ䡣 +5. Èç¹ûÐбȽÏÏ¡Ê裬»òÕßÓÉÓÚÒ³·ÖÁѵ¼ÖÂÊý¾Ý´æ´¢²»Á¬ÐøÊ±£¬¾Û´ØË÷Òý¿ÉÄܵ¼ÖÂÈ«±íɨÃèËٶȱäÂý¡£ -### 3.6 覆盖索引 +### 3.6 ¸²¸ÇË÷Òý -索引包å�«æ‰€æœ‰éœ€è¦�查询的字段的值。 +Ë÷Òý°üº¬ËùÓÐÐèÒª²éѯµÄ×ֶεÄÖµ¡£ -## 4. B-Tree å’Œ B+Tree 原ç�† +## 4. B-Tree ºÍ B+Tree Ô­Àí ### 4. 1 B-Tree ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5ed71283-a070-4b21-85ae-f2cbfd6ba6e1.jpg) -为了æ��è¿° B-Tree,首先定义一æ�¡æ•°æ�®è®°å½•为一个二元组 [key, data],key 为记录的键,data 为数æ�®è®°å½•除 key 外的数æ�®ã€‚ +ΪÁËÃèÊö B-Tree£¬Ê×Ïȶ¨ÒåÒ»ÌõÊý¾Ý¼Ç¼Ϊһ¸ö¶þÔª×é [key, data]£¬key Ϊ¼Ç¼µÄ¼ü£¬data ΪÊý¾Ý¼Ç¼³ý key ÍâµÄÊý¾Ý¡£ -B-Tree 是满足下列æ�¡ä»¶çš„æ•°æ�®ç»“构: +B-Tree ÊÇÂú×ãÏÂÁÐÌõ¼þµÄÊý¾Ý½á¹¹£º -- 所有å�¶èŠ‚ç‚¹å…·æœ‰ç›¸å�Œçš„æ·±åº¦ï¼Œä¹Ÿå°±æ˜¯è¯´ B-Tree 是平衡的; -- 一个节点中的 key 从左到å�³é�žé€’å‡�排列; -- 如果æŸ�个指针的左å�³ç›¸é‚» key 分别是 keyi å’Œ keyi+1,且ä¸�为 null,则该指针指å�‘节点的所有 key 大于 keyi 且å°�于 keyi+1。 +- ËùÓÐÒ¶½Úµã¾ßÓÐÏàͬµÄÉî¶È£¬Ò²¾ÍÊÇ˵ B-Tree ÊÇÆ½ºâµÄ£» +- Ò»¸ö½ÚµãÖÐµÄ key ´Ó×óµ½ÓҷǵݼõÅÅÁУ» +- Èç¹ûij¸öÖ¸ÕëµÄ×óÓÒÏàÁÚ key ·Ö±ðÊÇ keyi ºÍ keyi+1£¬ÇÒ²»Îª null£¬Ôò¸ÃÖ¸ÕëÖ¸Ïò½ÚµãµÄËùÓÐ key ´óÓÚ keyi ÇÒСÓÚ keyi+1¡£ -在 B-Tree 中按 key 检索数æ�®çš„算法é�žå¸¸ç›´è§‚:首先从根节点进行二分查找,如果找到则返回对应节点的 data,å�¦åˆ™å¯¹ç›¸åº”区间的指针指å�‘的节点递归进行查找,直到找到节点或找到 null 指针,å‰�者查找æˆ�功,å�Žè€…查找失败。 +ÔÚ B-Tree Öа´ key ¼ìË÷Êý¾ÝµÄËã·¨·Ç³£Ö±¹Û£ºÊ×ÏÈ´Ó¸ù½Úµã½øÐжþ·Ö²éÕÒ£¬Èç¹ûÕÒµ½Ôò·µ»Ø¶ÔÓ¦½ÚµãµÄ data£¬·ñÔò¶ÔÏàÓ¦Çø¼äµÄÖ¸ÕëÖ¸ÏòµÄ½ÚµãµÝ¹é½øÐвéÕÒ£¬Ö±µ½ÕÒµ½½Úµã»òÕÒµ½ null Ö¸Õ룬ǰÕß²éÕҳɹ¦£¬ºóÕß²éÕÒʧ°Ü¡£ -由于æ�’入删除新的数æ�®è®°å½•会破å�� B-Tree 的性质,因此在æ�’入删除时,需è¦�对树进行一个分裂ã€�å�ˆå¹¶ã€�转移等æ“�作以ä¿�æŒ� B-Tree 性质。 +ÓÉÓÚ²åÈëɾ³ýеÄÊý¾Ý¼Ç¼»áÆÆ»µ B-Tree µÄÐÔÖÊ£¬Òò´ËÔÚ²åÈëɾ³ýʱ£¬ÐèÒª¶ÔÊ÷½øÐÐÒ»¸ö·ÖÁÑ¡¢ºÏ²¢¡¢×ªÒƵȲÙ×÷ÒÔ±£³Ö B-Tree ÐÔÖÊ¡£ ### 4.2 B+Tree ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/63cd5b50-d6d8-4df6-8912-ef4a1dd5ba13.jpg) -与 B-Tree 相比,B+Tree 有以下ä¸�å�Œç‚¹ï¼š +Óë B-Tree Ïà±È£¬B+Tree ÓÐÒÔϲ»Í¬µã£º -- æ¯�个节点的指针上é™�为 2d 而ä¸�是 2d+1ï¼› -- 内节点ä¸�存储 data,å�ªå­˜å‚¨ key,å�¶å­�节点ä¸�存储指针。 +- ÿ¸ö½ÚµãµÄÖ¸ÕëÉÏÏÞΪ 2d ¶ø²»ÊÇ 2d+1£» +- Äڽڵ㲻´æ´¢ data£¬Ö»´æ´¢ key£¬Ò¶×ӽڵ㲻´æ´¢Ö¸Õë¡£ -### 4.3 带有顺åº�访问指针的 B+Tree +### 4.3 ´øÓÐ˳Ðò·ÃÎÊÖ¸ÕëµÄ B+Tree ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1ee5f0a5-b8df-43b9-95ab-c516c54ec797.jpg) -一般在数æ�®åº“系统或文件系统中使用的 B+Tree 结构都在ç»�å…¸ B+Tree 基础上进行了优化,在å�¶å­�节点增加了顺åº�访问指针,å�šè¿™ä¸ªä¼˜åŒ–的目的是为了æ��高区间访问的性能。 +Ò»°ãÔÚÊý¾Ý¿âϵͳ»òÎļþϵͳÖÐʹÓÃµÄ B+Tree ½á¹¹¶¼ÔÚ¾­µä B+Tree »ù´¡ÉϽøÐÐÁËÓÅ»¯£¬ÔÚÒ¶×Ó½ÚµãÔö¼ÓÁË˳Ðò·ÃÎÊÖ¸Õ룬×öÕâ¸öÓÅ»¯µÄÄ¿µÄÊÇΪÁËÌá¸ßÇø¼ä·ÃÎʵÄÐÔÄÜ¡£ -### 4.4 为什么使用 B-Tree å’Œ B+Tree +### 4.4 ΪʲôʹÓà B-Tree ºÍ B+Tree -红黑树等数æ�®ç»“构也å�¯ä»¥ç”¨æ�¥å®žçŽ°ç´¢å¼•ï¼Œä½†æ˜¯æ–‡ä»¶ç³»ç»Ÿå�Šæ•°æ�®åº“系统普é��采用 B-/+Tree 作为索引结构。 +ºìºÚÊ÷µÈÊý¾Ý½á¹¹Ò²¿ÉÒÔÓÃÀ´ÊµÏÖË÷Òý£¬µ«ÊÇÎļþϵͳ¼°Êý¾Ý¿âϵͳÆÕ±é²ÉÓà B-/+Tree ×÷ΪË÷Òý½á¹¹¡£ -页是计算机管ç�†å­˜å‚¨å™¨çš„逻辑å�—,硬件å�Šæ“�作系统往往将主存和ç£�盘存储区分割为连续的大å°�相等的å�—,æ¯�个存储å�—称为一页(在许多æ“�作系统中,页得大å°�通常为 4k),主存和ç£�盘以页为å�•ä½�交æ�¢æ•°æ�®ã€‚ +Ò³ÊǼÆËã»ú¹ÜÀí´æ´¢Æ÷µÄÂß¼­¿é£¬Ó²¼þ¼°²Ù×÷ϵͳÍùÍù½«Ö÷´æºÍ´ÅÅÌ´æ´¢Çø·Ö¸îΪÁ¬ÐøµÄ´óСÏàµÈµÄ¿é£¬Ã¿¸ö´æ´¢¿é³ÆÎªÒ»Ò³£¨ÔÚÐí¶à²Ù×÷ϵͳÖУ¬Ò³µÃ´óСͨ³£Îª 4k£©£¬Ö÷´æºÍ´ÅÅÌÒÔҳΪµ¥Î»½»»»Êý¾Ý¡£ -一般æ�¥è¯´ï¼Œç´¢å¼•本身也很大,ä¸�å�¯èƒ½å…¨éƒ¨å­˜å‚¨åœ¨å†…存中,因此索引往往以索引文件的形å¼�存储的ç£�盘上。为了å‡�å°‘ç£�盘 I/O,ç£�盘往往ä¸�是严格按需读å�–,而是æ¯�次都会预读。这样å�šçš„ç�†è®ºä¾�æ�®æ˜¯è®¡ç®—机科学中著å��的局部性原ç�†ï¼šå½“一个数æ�®è¢«ç”¨åˆ°æ—¶ï¼Œå…¶é™„近的数æ�®ä¹Ÿé€šå¸¸ä¼šé©¬ä¸Šè¢«ä½¿ç”¨ã€‚æ•°æ�®åº“系统的设计者巧妙利用了ç£�盘预读原ç�†ï¼Œå°†ä¸€ä¸ªèŠ‚ç‚¹çš„å¤§å°�设为等于一个页,这样æ¯�个节点å�ªéœ€è¦�一次 I/O å°±å�¯ä»¥å®Œå…¨è½½å…¥ã€‚B-Tree 中一次检索最多需è¦� h-1 次 I/O(根节点常驻内存),æ¸�è¿›å¤�æ�‚度为 O(h)=O(logdN)。一般实际应用中,出度 d 是é�žå¸¸å¤§çš„æ•°å­—,通常超过 100,因此 h é�žå¸¸å°�(通常ä¸�超过 3)。而红黑树这ç§�结构,h 明显è¦�深的多。并且于逻辑上很近的节点(父å­�)物ç�†ä¸Šå�¯èƒ½å¾ˆè¿œï¼Œæ— æ³•利用局部性,效率明显比 B-Tree 差很多。 +Ò»°ãÀ´Ëµ£¬Ë÷Òý±¾ÉíÒ²ºÜ´ó£¬²»¿ÉÄÜÈ«²¿´æ´¢ÔÚÄÚ´æÖУ¬Òò´ËË÷ÒýÍùÍùÒÔË÷ÒýÎļþµÄÐÎʽ´æ´¢µÄ´ÅÅÌÉÏ¡£ÎªÁ˼õÉÙ´ÅÅÌ I/O£¬´ÅÅÌÍùÍù²»ÊÇÑϸñ°´Ðè¶ÁÈ¡£¬¶øÊÇÿ´Î¶¼»áÔ¤¶Á¡£ÕâÑù×öµÄÀíÂÛÒÀ¾ÝÊǼÆËã»ú¿ÆÑ§ÖÐÖøÃûµÄ¾Ö²¿ÐÔÔ­Àí£ºµ±Ò»¸öÊý¾Ý±»Óõ½Ê±£¬Æä¸½½üµÄÊý¾ÝҲͨ³£»áÂíÉϱ»Ê¹Óá£Êý¾Ý¿âϵͳµÄÉè¼ÆÕßÇÉÃîÀûÓÃÁË´ÅÅÌÔ¤¶ÁÔ­Àí£¬½«Ò»¸ö½ÚµãµÄ´óСÉèΪµÈÓÚÒ»¸öÒ³£¬ÕâÑùÿ¸ö½ÚµãÖ»ÐèÒªÒ»´Î I/O ¾Í¿ÉÒÔÍêÈ«ÔØÈë¡£B-Tree ÖÐÒ»´Î¼ìË÷×î¶àÐèÒª h-1 ´Î I/O£¨¸ù½Úµã³£×¤Äڴ棩£¬½¥½ø¸´ÔÓ¶ÈΪ O(h)=O(logdN)¡£Ò»°ãʵ¼ÊÓ¦ÓÃÖУ¬³ö¶È d ÊǷdz£´óµÄÊý×Ö£¬Í¨³£³¬¹ý 100£¬Òò´Ë h ·Ç³£Ð¡£¨Í¨³£²»³¬¹ý 3£©¡£¶øºìºÚÊ÷ÕâÖֽṹ£¬h Ã÷ÏÔÒªÉîµÄ¶à¡£²¢ÇÒÓÚÂß¼­ÉϺܽüµÄ½Úµã£¨¸¸×Ó£©ÎïÀíÉÏ¿ÉÄܺÜÔ¶£¬ÎÞ·¨ÀûÓþֲ¿ÐÔ£¬Ð§ÂÊÃ÷ÏÔ±È B-Tree ²îºÜ¶à¡£ -B+Tree 更适å�ˆå¤–存索引,原因和内节点出度 d 有关。由于 B+Tree 内节点去掉了 data 域,因此å�¯ä»¥æ‹¥æœ‰æ›´å¤§çš„出度,拥有更好的性能。 +B+Tree ¸üÊʺÏÍâ´æË÷Òý£¬Ô­ÒòºÍÄÚ½Úµã³ö¶È d Óйء£ÓÉÓÚ B+Tree ÄÚ½ÚµãÈ¥µôÁË data Óò£¬Òò´Ë¿ÉÒÔÓµÓиü´óµÄ³ö¶È£¬ÓµÓиüºÃµÄÐÔÄÜ¡£ -# 查询性能优化 +# ²éѯÐÔÄÜÓÅ»¯ ## 1. Explain -用æ�¥åˆ†æž� SQL 语å�¥ï¼Œåˆ†æž�结果中比较é‡�è¦�的字段有: +ÓÃÀ´·ÖÎö SQL Óï¾ä£¬·ÖÎö½á¹ûÖбȽÏÖØÒªµÄ×Ö¶ÎÓУº -- select_type : 查询类型,有简å�•查询ã€�è�”å�ˆæŸ¥è¯¢å’Œå­�查询 +- select_type : ²éѯÀàÐÍ£¬Óмòµ¥²éѯ¡¢ÁªºÏ²éѯºÍ×Ó²éѯ -- key : 使用的索引 +- key : ʹÓõÄË÷Òý -- rows : 扫æ��的行数 +- rows : ɨÃèµÄÐÐÊý -## 2. å‡�少返回的列 +## 2. ¼õÉÙ·µ»ØµÄÁÐ -慢查询主è¦�是因为访问了过多数æ�®ï¼Œé™¤äº†è®¿é—®è¿‡å¤šè¡Œä¹‹å¤–,也包括访问过多列。 +Âý²éѯÖ÷ÒªÊÇÒòΪ·ÃÎÊÁ˹ý¶àÊý¾Ý£¬³ýÁË·ÃÎʹý¶àÐÐÖ®Í⣬Ҳ°üÀ¨·ÃÎʹý¶àÁС£ -最好ä¸�è¦�使用 SELECT * 语å�¥ï¼Œè¦�æ ¹æ�®éœ€è¦�选择查询的列。 +×îºÃ²»ÒªÊ¹Óà SELECT * Óï¾ä£¬Òª¸ù¾ÝÐèҪѡÔñ²éѯµÄÁС£ -## 3. å‡�少返回的行 +## 3. ¼õÉÙ·µ»ØµÄÐÐ -最好使用 LIMIT 语å�¥æ�¥å�–出想è¦�的那些行。 +×îºÃʹÓà LIMIT Óï¾äÀ´È¡³öÏëÒªµÄÄÇЩÐС£ -还å�¯ä»¥å»ºç«‹ç´¢å¼•æ�¥å‡�å°‘æ�¡ä»¶è¯­å�¥çš„全表扫æ��。例如对于下é�¢çš„语å�¥ï¼Œä¸�适用索引的情况下需è¦�进行全表扫æ��,而使用索引å�ªéœ€è¦�扫æ��几行记录å�³å�¯ï¼Œä½¿ç”¨ Explain 语å�¥å�¯ä»¥é€šè¿‡è§‚察 rows 字段æ�¥çœ‹å‡ºè¿™ç§�差异。 +»¹¿ÉÒÔ½¨Á¢Ë÷ÒýÀ´¼õÉÙÌõ¼þÓï¾äµÄÈ«±íɨÃè¡£ÀýÈç¶ÔÓÚÏÂÃæµÄÓï¾ä£¬²»ÊÊÓÃË÷ÒýµÄÇé¿öÏÂÐèÒª½øÐÐÈ«±íɨÃ裬¶øÊ¹ÓÃË÷ÒýÖ»ÐèҪɨÃ輸ÐмǼ¼´¿É£¬Ê¹Óà Explain Óï¾ä¿ÉÒÔͨ¹ý¹Û²ì rows ×Ö¶ÎÀ´¿´³öÕâÖÖ²îÒì¡£ ```sql SELECT * FROM sakila.film_actor WHERE film_id = 1; ``` -## 4. 拆分大的 DELETE 或 INSERT 语å�¥ +## 4. ²ð·Ö´óµÄ DELETE »ò INSERT Óï¾ä -如果一次性执行的è¯�,å�¯èƒ½ä¸€æ¬¡é”�ä½�很多数æ�®ã€�å� æ»¡æ•´ä¸ªäº‹åŠ¡æ—¥å¿—ã€�耗尽系统资æº�ã€�阻塞很多å°�的但é‡�è¦�的查询。 +Èç¹ûÒ»´ÎÐÔÖ´Ðеϰ£¬¿ÉÄÜÒ»´ÎËø×¡ºÜ¶àÊý¾Ý¡¢Õ¼ÂúÕû¸öÊÂÎñÈÕÖ¾¡¢ºÄ¾¡ÏµÍ³×ÊÔ´¡¢×èÈûºÜ¶àСµÄµ«ÖØÒªµÄ²éѯ¡£ ```sql DELEFT FROM messages WHERE create < DATE_SUB(NOW(), INTERVAL 3 MONTH); @@ -349,74 +371,74 @@ do { } while rows_affected > 0 ``` -# 分库与分表 +# ·Ö¿âÓë·Ö±í -**1. 分表与分区的ä¸�å�Œ** +**1. ·Ö±íÓë·ÖÇøµÄ²»Í¬** -分表,就是讲一张表分æˆ�多个å°�表,这些å°�表拥有ä¸�å�Œçš„表å��;而分区是将一张表的数æ�®åˆ†ä¸ºå¤šä¸ªåŒºå�—,这些区å�—å�¯ä»¥å­˜å‚¨åœ¨å�Œä¸€ä¸ªç£�盘上,也å�¯ä»¥å­˜å‚¨åœ¨ä¸�å�Œçš„ç£�盘上,这ç§�æ–¹å¼�下表ä»�ç„¶å�ªæœ‰ä¸€ä¸ªã€‚ +·Ö±í£¬¾ÍÊǽ²Ò»Õűí·Ö³É¶à¸öС±í£¬ÕâЩС±íÓµÓв»Í¬µÄ±íÃû£»¶ø·ÖÇøÊǽ«Ò»ÕűíµÄÊý¾Ý·ÖΪ¶à¸öÇø¿é£¬ÕâÐ©Çø¿é¿ÉÒÔ´æ´¢ÔÚͬһ¸ö´ÅÅÌÉÏ£¬Ò²¿ÉÒÔ´æ´¢ÔÚ²»Í¬µÄ´ÅÅÌÉÏ£¬ÕâÖÖ·½Ê½Ï±íÈÔȻֻÓÐÒ»¸ö¡£ -**2. 使用分库与分表的原因** +**2. ʹÓ÷ֿâÓë·Ö±íµÄÔ­Òò** -éš�ç�€æ—¶é—´å’Œä¸šåŠ¡çš„å�‘展,数æ�®åº“中的表会越æ�¥è¶Šå¤šï¼Œå¹¶ä¸”表中的数æ�®é‡�也会越æ�¥è¶Šå¤§ï¼Œé‚£ä¹ˆè¯»å†™æ“�作的开销也会éš�ç�€å¢žå¤§ã€‚ +Ëæ×Åʱ¼äºÍÒµÎñµÄ·¢Õ¹£¬Êý¾Ý¿âÖеıí»áÔ½À´Ô½¶à£¬²¢ÇÒ±íÖеÄÊý¾ÝÁ¿Ò²»áÔ½À´Ô½´ó£¬ÄÇô¶Áд²Ù×÷µÄ¿ªÏúÒ²»áËæ×ÅÔö´ó¡£ -**3. 垂直切分** +**3. ´¹Ö±ÇзÖ** -将表按功能模å�—ã€�关系密切程度划分出æ�¥ï¼Œéƒ¨ç½²åˆ°ä¸�å�Œçš„库上。例如,我们会建立商å“�æ•°æ�®åº“ payDBã€�用户数æ�®åº“ userDB 等,分别用æ�¥å­˜å‚¨é¡¹ç›®ä¸Žå•†å“�有关的表和与用户有关的表。 +½«±í°´¹¦ÄÜÄ£¿é¡¢¹ØÏµÃÜÇг̶Ȼ®·Ö³öÀ´£¬²¿Êðµ½²»Í¬µÄ¿âÉÏ¡£ÀýÈ磬ÎÒÃǻὨÁ¢ÉÌÆ·Êý¾Ý¿â payDB¡¢Óû§Êý¾Ý¿â userDB µÈ£¬·Ö±ðÓÃÀ´´æ´¢ÏîÄ¿ÓëÉÌÆ·ÓйصıíºÍÓëÓû§ÓÐ¹ØµÄ±í¡£ -**4. 水平切分** +**4. ˮƽÇзÖ** -把表中的数æ�®æŒ‰ç…§æŸ�ç§�规则存储到多个结构相å�Œçš„表中,例如按 id 的散列值ã€�性别等进行划分, +°Ñ±íÖеÄÊý¾Ý°´ÕÕijÖÖ¹æÔò´æ´¢µ½¶à¸ö½á¹¹ÏàͬµÄ±íÖУ¬ÀýÈç°´ id µÄÉ¢ÁÐÖµ¡¢ÐÔ±ðµÈ½øÐл®·Ö£¬ -**5. 垂直切分与水平切分的选择** +**5. ´¹Ö±ÇзÖÓëˮƽÇзֵÄÑ¡Ôñ** -如果数æ�®åº“中的表太多,并且项目å�„项业务逻辑清晰,那么垂直切分是首选。 +Èç¹ûÊý¾Ý¿âÖеıíÌ«¶à£¬²¢ÇÒÏîÄ¿¸÷ÏîÒµÎñÂß¼­ÇåÎú£¬ÄÇô´¹Ö±ÇзÖÊÇÊ×Ñ¡¡£ -如果数æ�®åº“的表ä¸�多,但是å�•表的数æ�®é‡�很大,应该选择水平切分。 +Èç¹ûÊý¾Ý¿âµÄ±í²»¶à£¬µ«Êǵ¥±íµÄÊý¾ÝÁ¿ºÜ´ó£¬Ó¦¸ÃÑ¡ÔñˮƽÇз֡£ -**6. 水平切分的实现方å¼�** +**6. ˮƽÇзֵÄʵÏÖ·½Ê½** -最简å�•的是使用 merge 存储引擎。 +×î¼òµ¥µÄÊÇʹÓà merge ´æ´¢ÒýÇæ¡£ -**7. 分库与分表存在的问题** +**7. ·Ö¿âÓë·Ö±í´æÔÚµÄÎÊÌâ** -(1) 事务问题 +(1) ÊÂÎñÎÊÌâ -在执行分库分表之å�Žï¼Œç”±äºŽæ•°æ�®å­˜å‚¨åˆ°äº†ä¸�å�Œçš„库上,数æ�®åº“事务管ç�†å‡ºçŽ°äº†å›°éš¾ã€‚å¦‚æžœä¾�èµ–æ•°æ�®åº“本身的分布å¼�事务管ç�†åŠŸèƒ½åŽ»æ‰§è¡Œäº‹åŠ¡ï¼Œå°†ä»˜å‡ºé«˜æ˜‚çš„æ€§èƒ½ä»£ä»·ï¼›å¦‚æžœç”±åº”ç”¨ç¨‹åº�去å��助控制,形æˆ�程åº�逻辑上的事务,å�ˆä¼šé€ æˆ�编程方é�¢çš„负担。 +ÔÚÖ´Ðзֿâ·Ö±íÖ®ºó£¬ÓÉÓÚÊý¾Ý´æ´¢µ½Á˲»Í¬µÄ¿âÉÏ£¬Êý¾Ý¿âÊÂÎñ¹ÜÀí³öÏÖÁËÀ§ÄÑ¡£Èç¹ûÒÀÀµÊý¾Ý¿â±¾ÉíµÄ·Ö²¼Ê½ÊÂÎñ¹ÜÀí¹¦ÄÜÈ¥Ö´ÐÐÊÂÎñ£¬½«¸¶³ö¸ß°ºµÄÐÔÄÜ´ú¼Û£»Èç¹ûÓÉÓ¦ÓóÌÐòȥЭÖú¿ØÖÆ£¬ÐγɳÌÐòÂß¼­ÉϵÄÊÂÎñ£¬ÓÖ»áÔì³É±à³Ì·½ÃæµÄ¸ºµ£¡£ -(2) 跨库跨表连接问题 +(2) ¿ç¿â¿ç±íÁ¬½ÓÎÊÌâ -在执行了分库分表之å�Žï¼Œéš¾ä»¥é�¿å…�会将原本逻辑关è�”性很强的数æ�®åˆ’分到ä¸�å�Œçš„表ã€�ä¸�å�Œçš„库上。这时,表的连接æ“�作将å�—到é™�制,我们无法连接ä½�于ä¸�å�Œåˆ†åº“的表,也无法连接分表粒度ä¸�å�Œçš„表,导致原本å�ªéœ€è¦�一次查询就能够完æˆ�的业务需è¦�进行多次æ‰�能完æˆ�。 +ÔÚÖ´ÐÐÁË·Ö¿â·Ö±íÖ®ºó£¬ÄÑÒÔ±ÜÃâ»á½«Ô­±¾Âß¼­¹ØÁªÐÔºÜÇ¿µÄÊý¾Ý»®·Öµ½²»Í¬µÄ±í¡¢²»Í¬µÄ¿âÉÏ¡£Õâʱ£¬±íµÄÁ¬½Ó²Ù×÷½«Êܵ½ÏÞÖÆ£¬ÎÒÃÇÎÞ·¨Á¬½ÓλÓÚ²»Í¬·Ö¿âµÄ±í£¬Ò²ÎÞ·¨Á¬½Ó·Ö±íÁ£¶È²»Í¬µÄ±í£¬µ¼ÖÂÔ­±¾Ö»ÐèÒªÒ»´Î²éѯ¾ÍÄܹ»Íê³ÉµÄÒµÎñÐèÒª½øÐжà´Î²ÅÄÜÍê³É¡£ -# 故障转移和故障æ�¢å¤� +# ¹ÊÕÏ×ªÒÆºÍ¹ÊÕϻָ´ -故障转移也å�«å�šåˆ‡æ�¢ï¼Œå½“主库出现故障时就切æ�¢åˆ°å¤‡åº“,使备库æˆ�为主库。故障æ�¢å¤�顾å��æ€�义就是从故障中æ�¢å¤�过æ�¥ï¼Œå¹¶ä¸”ä¿�è¯�æ•°æ�®çš„æ­£ç¡®æ€§ã€‚ +¹ÊÕÏ×ªÒÆÒ²½Ð×öÇл»£¬µ±Ö÷¿â³öÏÖ¹ÊÕÏʱ¾ÍÇл»µ½±¸¿â£¬Ê¹±¸¿â³ÉΪÖ÷¿â¡£¹ÊÕϻָ´¹ËÃû˼Òå¾ÍÊÇ´Ó¹ÊÕÏÖлָ´¹ýÀ´£¬²¢ÇÒ±£Ö¤Êý¾ÝµÄÕýÈ·ÐÔ¡£ -## 1. 故障转移 +## 1. ¹ÊÕÏ×ªÒÆ -**1.1 æ��å�‡å¤‡åº“或切æ�¢è§’色** +**1.1 ÌáÉý±¸¿â»òÇл»½ÇÉ«** -æ��å�‡ä¸€å�°å¤‡åº“为主库,或者在一个主-主å¤�制结构中调整主动和被动角色。 +ÌáÉýһ̨±¸¿âΪÖ÷¿â£¬»òÕßÔÚÒ»¸öÖ÷-Ö÷¸´ÖƽṹÖе÷ÕûÖ÷¶¯ºÍ±»¶¯½ÇÉ«¡£ -**1.2 虚拟 IP 地å�€å’Œ IP 托管** +**1.2 ÐéÄâ IP µØÖ·ºÍ IP ÍйÜ** -为 MySQL 实例指定一个逻辑 IP 地å�€ï¼Œå½“ MySQL 实例失效时,å�¯ä»¥å°† IP 地å�€è½¬ç§»åˆ°å�¦ä¸€å�° MySQL æœ�务器上。 +Ϊ MySQL ʵÀýÖ¸¶¨Ò»¸öÂß¼­ IP µØÖ·£¬µ± MySQL ʵÀýʧЧʱ£¬¿ÉÒÔ½« IP µØÖ·×ªÒƵ½Áíһ̨ MySQL ·þÎñÆ÷ÉÏ¡£ -**1.3 中间件解决方案** +**1.3 Öмä¼þ½â¾ö·½°¸** -通过代ç�†ï¼Œå�¯ä»¥è·¯ç”±æµ�é‡�到å�¯ä»¥ä½¿ç”¨çš„æœ�务器上。 +ͨ¹ý´úÀí£¬¿ÉÒÔ·ÓÉÁ÷Á¿µ½¿ÉÒÔʹÓõķþÎñÆ÷ÉÏ¡£ ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/fabd5fa0-b75e-48d0-9e2c-31471945ceb9.jpg) -**1.4 在应用中处ç�†æ•…障转移** +**1.4 ÔÚÓ¦ÓÃÖд¦Àí¹ÊÕÏ×ªÒÆ** -将故障转移整å�ˆåˆ°åº”用中å�¯èƒ½å¯¼è‡´åº”用å�˜å¾—太过笨拙。 +½«¹ÊÕÏ×ªÒÆÕûºÏµ½Ó¦ÓÃÖпÉÄܵ¼ÖÂÓ¦ÓñäµÃÌ«¹ý±¿×¾¡£ -## 2. æ•…éšœæ�¢å¤� +## 2. ¹ÊÕϻָ´ -# å�‚考资料 +# ²Î¿¼×ÊÁÏ -- 高性能 MySQL -- [MySQL 索引背å�Žçš„æ•°æ�®ç»“æž„å�Šç®—法原ç�† ](http://blog.codinglabs.org/articles/theory-of-mysql-index.html) -- [MySQL 索引优化全攻略 ](http://www.runoob.com/w3cnote/mysql-index.html) -- [20+ æ�¡ MySQL 性能优化的最佳ç»�验 ](https://www.jfox.info/20-tiao-mysql-xing-nen-you-hua-de-zui-jia-jing-yan.html) +- ¸ßÐÔÄÜ MySQL +- [MySQL Ë÷Òý±³ºóµÄÊý¾Ý½á¹¹¼°Ëã·¨Ô­Àí ](http://blog.codinglabs.org/articles/theory-of-mysql-index.html) +- [MySQL Ë÷ÒýÓÅ»¯È«¹¥ÂÔ ](http://www.runoob.com/w3cnote/mysql-index.html) +- [20+ Ìõ MySQL ÐÔÄÜÓÅ»¯µÄ×î¼Ñ¾­Ñé ](https://www.jfox.info/20-tiao-mysql-xing-nen-you-hua-de-zui-jia-jing-yan.html) diff --git a/notes/算法.md b/notes/算法.md index c2d4fa60..f738b9c8 100644 --- a/notes/算法.md +++ b/notes/算法.md @@ -18,63 +18,63 @@ * [5. ¸÷ÖÖ union-find Ëã·¨µÄ±È½Ï](#5-¸÷ÖÖ-union-find-Ëã·¨µÄ±È½Ï) * [µÚ¶þÕ ÅÅÐò](#µÚ¶þÕÂ-ÅÅÐò) * [³õ¼¶ÅÅÐòËã·¨](#³õ¼¶ÅÅÐòËã·¨) - * [Ô¼¶¨](#Ô¼¶¨) - * [Ñ¡ÔñÅÅÐò](#Ñ¡ÔñÅÅÐò) - * [²åÈëÅÅÐò](#²åÈëÅÅÐò) - * [Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï](#Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï) - * [Ï£¶ûÅÅÐò](#Ï£¶ûÅÅÐò) + * [1. Ô¼¶¨](#1-Ô¼¶¨) + * [2. Ñ¡ÔñÅÅÐò](#2-Ñ¡ÔñÅÅÐò) + * [3. ²åÈëÅÅÐò](#3-²åÈëÅÅÐò) + * [4. Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï](#4-Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï) + * [5. Ï£¶ûÅÅÐò](#5-Ï£¶ûÅÅÐò) * [¹é²¢ÅÅÐò](#¹é²¢ÅÅÐò) - * [¹é²¢·½·¨](#¹é²¢·½·¨) - * [×Ô¶¥ÏòϹ鲢ÅÅÐò](#×Ô¶¥ÏòϹ鲢ÅÅÐò) - * [×Ôµ×ÏòÉϹ鲢ÅÅÐò](#×Ôµ×ÏòÉϹ鲢ÅÅÐò) + * [1. ¹é²¢·½·¨](#1-¹é²¢·½·¨) + * [2. ×Ô¶¥ÏòϹ鲢ÅÅÐò](#2-×Ô¶¥ÏòϹ鲢ÅÅÐò) + * [3. ×Ôµ×ÏòÉϹ鲢ÅÅÐò](#3-×Ôµ×ÏòÉϹ鲢ÅÅÐò) * [¿ìËÙÅÅÐò](#¿ìËÙÅÅÐò) - * [»ù±¾Ëã·¨](#»ù±¾Ëã·¨) - * [ÇзÖ](#ÇзÖ) - * [ÐÔÄÜ·ÖÎö](#ÐÔÄÜ·ÖÎö) - * [Ëã·¨¸Ä½ø](#Ëã·¨¸Ä½ø) - * [Çл»µ½²åÈëÅÅÐò](#Çл»µ½²åÈëÅÅÐò) - * [ÈýÈ¡Ñù](#ÈýÈ¡Ñù) - * [ÈýÏòÇзÖ](#ÈýÏòÇзÖ) + * [1. »ù±¾Ëã·¨](#1-»ù±¾Ëã·¨) + * [2. ÇзÖ](#2-ÇзÖ) + * [3. ÐÔÄÜ·ÖÎö](#3-ÐÔÄÜ·ÖÎö) + * [4. Ëã·¨¸Ä½ø](#4-Ëã·¨¸Ä½ø) + * [4.1 Çл»µ½²åÈëÅÅÐò](#41-Çл»µ½²åÈëÅÅÐò) + * [4.2 ÈýÈ¡Ñù](#42-ÈýÈ¡Ñù) + * [4.3 ÈýÏòÇзÖ](#43-ÈýÏòÇзÖ) * [ÓÅÏȶÓÁÐ](#ÓÅÏȶÓÁÐ) - * [¶Ñ](#¶Ñ) - * [Éϸ¡ºÍϳÁ](#Éϸ¡ºÍϳÁ) - * [²åÈëÔªËØ](#²åÈëÔªËØ) - * [ɾ³ý×î´óÔªËØ](#ɾ³ý×î´óÔªËØ) - * [¶ÑÅÅÐò](#¶ÑÅÅÐò) - * [·ÖÎö](#·ÖÎö) + * [1. ¶Ñ](#1-¶Ñ) + * [2. Éϸ¡ºÍϳÁ](#2-Éϸ¡ºÍϳÁ) + * [3. ²åÈëÔªËØ](#3-²åÈëÔªËØ) + * [4. ɾ³ý×î´óÔªËØ](#4-ɾ³ý×î´óÔªËØ) + * [5. ¶ÑÅÅÐò](#5-¶ÑÅÅÐò) + * [6. ·ÖÎö](#6-·ÖÎö) * [Ó¦ÓÃ](#Ó¦ÓÃ) - * [ÅÅÐòËã·¨µÄ±È½Ï](#ÅÅÐòËã·¨µÄ±È½Ï) - * [Java µÄÅÅÐòË㷨ʵÏÖ](#java-µÄÅÅÐòË㷨ʵÏÖ) - * [»ùÓÚÇзֵĿìËÙÑ¡ÔñËã·¨](#»ùÓÚÇзֵĿìËÙÑ¡ÔñËã·¨) + * [1. ÅÅÐòËã·¨µÄ±È½Ï](#1-ÅÅÐòËã·¨µÄ±È½Ï) + * [2. Java µÄÅÅÐòË㷨ʵÏÖ](#2-java-µÄÅÅÐòË㷨ʵÏÖ) + * [3. »ùÓÚÇзֵĿìËÙÑ¡ÔñËã·¨](#3-»ùÓÚÇзֵĿìËÙÑ¡ÔñËã·¨) * [µÚÈýÕ ²éÕÒ](#µÚÈýÕÂ-²éÕÒ) * [·ûºÅ±í](#·ûºÅ±í) - * [API](#api) - * [ÓÐÐò·ûºÅ±í](#ÓÐÐò·ûºÅ±í) - * [ÎÞÐòÁ´±íʵÏÖ](#ÎÞÐòÁ´±íʵÏÖ) - * [ÓÐÐòÊý×éµÄ¶þ·Ö²éÕÒ](#ÓÐÐòÊý×éµÄ¶þ·Ö²éÕÒ) - * [¶Ô¶þ·Ö²éÕҵķÖÎö](#¶Ô¶þ·Ö²éÕҵķÖÎö) + * [1. API](#1-api) + * [2. ÓÐÐò·ûºÅ±í](#2-ÓÐÐò·ûºÅ±í) + * [3. ÎÞÐòÁ´±íʵÏÖ](#3-ÎÞÐòÁ´±íʵÏÖ) + * [4. ÓÐÐòÊý×éµÄ¶þ·Ö²éÕÒ](#4-ÓÐÐòÊý×éµÄ¶þ·Ö²éÕÒ) + * [5. ¶Ô¶þ·Ö²éÕҵķÖÎö](#5-¶Ô¶þ·Ö²éÕҵķÖÎö) * [¶þ²æ²éÕÒÊ÷](#¶þ²æ²éÕÒÊ÷) - * [get()](#get) - * [put()](#put) - * [·ÖÎö](#·ÖÎö) - * [floor()](#floor) - * [rank()](#rank) - * [min()](#min) - * [deleteMin()](#deletemin) - * [delete()](#delete) - * [keys()](#keys) - * [ÐÔÄÜ·ÖÎö](#ÐÔÄÜ·ÖÎö) + * [1. get()](#1-get) + * [2. put()](#2-put) + * [3. ·ÖÎö](#3-·ÖÎö) + * [4. floor()](#4-floor) + * [5. rank()](#5-rank) + * [6. min()](#6-min) + * [7. deleteMin()](#7-deletemin) + * [8. delete()](#8-delete) + * [9. keys()](#9-keys) + * [10. ÐÔÄÜ·ÖÎö](#10-ÐÔÄÜ·ÖÎö) * [ƽºâ²éÕÒÊ÷](#ƽºâ²éÕÒÊ÷) * [2-3 ²éÕÒÊ÷](#2-3-²éÕÒÊ÷) - * [²åÈë²Ù×÷](#²åÈë²Ù×÷) - * [ÐÔÖÊ](#ÐÔÖÊ) + * [1. ²åÈë²Ù×÷](#1-²åÈë²Ù×÷) + * [2. ÐÔÖÊ](#2-ÐÔÖÊ) * [ºìºÚ¶þ²æ²éÕÒÊ÷](#ºìºÚ¶þ²æ²éÕÒÊ÷) - * [×óÐýת](#×óÐýת) - * [ÓÒÐýת](#ÓÒÐýת) - * [ÑÕɫת»»](#ÑÕɫת»») - * [²åÈë](#²åÈë) - * [ɾ³ý×îС¼ü](#ɾ³ý×îС¼ü) - * [·ÖÎö](#·ÖÎö) + * [1. ×óÐýת](#1-×óÐýת) + * [2. ÓÒÐýת](#2-ÓÒÐýת) + * [3. ÑÕɫת»»](#3-ÑÕɫת»») + * [4. ²åÈë](#4-²åÈë) + * [5. ɾ³ý×îС¼ü](#5-ɾ³ý×îС¼ü) + * [6. ·ÖÎö](#6-·ÖÎö) * [É¢Áбí](#É¢Áбí) * [É¢Áк¯Êý](#É¢Áк¯Êý) * [»ùÓÚÀ­Á´·¨µÄÉ¢Áбí](#»ùÓÚÀ­Á´·¨µÄÉ¢Áбí) @@ -96,12 +96,10 @@ ### 1. Êý×éʵÏÖ + ```java public class ResizeArrayStack implements Iterable { - - // ÐèÒªÓà Object Êý×éÈ»ºóתÐÍ£¬²»ÄÜÖ±½ÓʹÓà new Item[1]; private Item[] a = (Item[]) new Object[1]; - // Õ»ÖеÄÔªËØ¸öÊý private int N = 0; public void push(Item item) { @@ -158,6 +156,12 @@ public class ResizeArrayStack implements Iterable { } ``` +ÉÏÃæÊµÏÖʹÓÃÁË·ºÐÍ£¬Java ²»ÄÜÖ±½Ó´´½¨·ºÐÍÊý×飬ֻÄÜʹÓÃתÐÍÀ´´´½¨¡£ + +```java +Item[] arr = (Item[]) new Object[N]; +``` + ### 2. Á´±íʵÏÖ ÐèҪʹÓÃÁ´±íµÄÍ·²å·¨À´ÊµÏÖ£¬ÒòΪͷ²å·¨ÖÐ×îºóѹÈëÕ»µÄÔªËØÔÚÁ´±íµÄ¿ªÍ·£¬ËüµÄ next Ö¸ÕëÖ¸Ïòǰһ¸öѹÈëÕ»µÄÔªËØ£¬ÔÚµ¯³öÔªËØÊ¹¾Í¿ÉÒÔÈÃǰһ¸öѹÈëÕ»µÄÔªËØ³ÆÎªÕ»¶¥ÔªËØ¡£ @@ -497,7 +501,7 @@ public class WeightedQuickUnionUF { ## ³õ¼¶ÅÅÐòËã·¨ -### Ô¼¶¨ +### 1. Ô¼¶¨ ´ýÅÅÐòµÄÔªËØÐèҪʵÏÖ Java µÄ Comparable ½Ó¿Ú£¬¸Ã½Ó¿ÚÓÐ compareTo() ·½·¨¡£ @@ -517,7 +521,7 @@ private void exch(Comparable[] a, int i, int j){ } ``` -### Ñ¡ÔñÅÅÐò +### 2. Ñ¡ÔñÅÅÐò ÕÒµ½Êý×éÖеÄ×îÐ¡ÔªËØ£¬È»ºó½«ËüÓëÊý×éµÄµÚÒ»¸öÔªËØ½»»»Î»Öá£È»ºóÔÙ´ÓʣϵÄÔªËØÖÐÕÒµ½×îСµÄÔªËØ£¬½«ËüÓëÊý×éµÄµÚ¶þ¸öÔªËØ½»»»Î»Öᣲ»¶Ï½øÐÐÕâÑùµÄ²Ù×÷£¬Ö±µ½½«Õû¸öÊý×éÅÅÐò¡£ @@ -540,7 +544,7 @@ public class Selection { Ñ¡ÔñÅÅÐòÐèÒª \~N2/2 ´Î±È½ÏºÍ \~N ´Î½»»»£¬ËüµÄÔËÐÐʱ¼äÓëÊäÈëÎ޹أ¬Õâ¸öÌØµãʹµÃËü¶ÔÒ»¸öÒѾ­ÅÅÐòµÄÊý×éÒ²ÐèÒªÕâô¶àµÄ±È½ÏºÍ½»»»²Ù×÷¡£ -### ²åÈëÅÅÐò +### 3. ²åÈëÅÅÐò ½«Ò»¸öÔªËØ²åÈëµ½ÒÑÅÅÐòµÄÊý×éÖУ¬Ê¹µÃ²åÈëÖ®ºóµÄÊý×éÒ²ÊÇÓÐÐòµÄ¡£²åÈëÅÅÐò´Ó×óµ½ÓÒ²åÈëÿ¸öÔªËØ£¬Ã¿´Î²åÈëÖ®ºó×󲿵Ä×ÓÊý×éÊÇÓÐÐòµÄ¡£ @@ -563,11 +567,11 @@ public class Insertion { ²åÈëÅÅÐò¶ÔÓÚ²¿·ÖÓÐÐòÊý×éºÍС¹æÄ£Êý×éÌØ±ð¸ßЧ¡£ -### Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï +### 4. Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï ¶ÔÓÚËæ»úÅÅÐòµÄÎÞÖØ¸´Ö÷¼üµÄÊý×飬²åÈëÅÅÐòºÍÑ¡ÔñÅÅÐòµÄÔËÐÐʱ¼äÊÇÆ½·½¼¶±ðµÄ£¬Á½ÕßÖ®±ÈÊÇÒ»¸ö½ÏСµÄ³£Êý¡£ -### Ï£¶ûÅÅÐò +### 5. Ï£¶ûÅÅÐò ¶ÔÓÚ´ó¹æÄ£µÄÊý×飬²åÈëÅÅÐòºÜÂý£¬ÒòΪËüÖ»Äܽ»»»ÏàÁÚµÄÔªËØ£¬Èç¹ûÒª°ÑÔªËØ´ÓÒ»¶ËÒÆµ½ÁíÒ»¶Ë£¬¾ÍÐèÒªºÜ¶à´Î²Ù×÷¡£ @@ -605,7 +609,7 @@ public class Shell { ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/dcf265ad-fe35-424d-b4b7-d149cdf239f4.png) -### ¹é²¢·½·¨ +### 1. ¹é²¢·½·¨ ```java public class MergeSort { @@ -628,7 +632,7 @@ public class MergeSort { } ``` -### ×Ô¶¥ÏòϹ鲢ÅÅÐò +### 2. ×Ô¶¥ÏòϹ鲢ÅÅÐò ```java public static void sort(Comparable[] a) { @@ -653,7 +657,7 @@ public class MergeSort { ÒòΪСÊý×éµÄµÝ¹é²Ù×÷»á¹ýÓÚÆµ·±£¬Òò´ËʹÓòåÈëÅÅÐòÀ´´¦ÀíСÊý×齫»á»ñµÃ¸ü¸ßµÄÐÔÄÜ¡£ -### ×Ôµ×ÏòÉϹ鲢ÅÅÐò +### 3. ×Ôµ×ÏòÉϹ鲢ÅÅÐò Ïȹ鲢ÄÇЩ΢ÐÍÊý×飬Ȼºó³É¶Ô¹é²¢µÃµ½µÄ×ÓÊý×é¡£ @@ -673,7 +677,7 @@ public class MergeSort { ## ¿ìËÙÅÅÐò -### »ù±¾Ëã·¨ +### 1. »ù±¾Ëã·¨ ¹é²¢ÅÅÐò½«Êý×é·ÖΪÁ½¸ö×ÓÊý×é·Ö±ðÅÅÐò£¬²¢½«ÓÐÐòµÄ×ÓÊý×é¹é²¢Ê¹µÃÕû¸öÊý×éÅÅÐò£»¿ìËÙÅÅÐòͨ¹ýÒ»¸öÇзÖÔªËØ½«Êý×é·ÖΪÁ½¸ö×ÓÊý×飬×ó×ÓÊý×éСÓÚµÈÓÚÇзÖÔªËØ£¬ÓÒ×ÓÊý×é´óÓÚµÈÓÚÇзÖÔªËØ£¬½«ÕâÁ½¸ö×ÓÊý×éÅÅÐòÒ²¾Í½«Õû¸öÊý×éÅÅÐòÁË¡£ @@ -695,7 +699,7 @@ public class QuickSort { } ``` -### ÇÐ·Ö +### 2. ÇÐ·Ö È¡ a[lo] ×÷ΪÇзÖÔªËØ£¬È»ºó´ÓÊý×éµÄ×ó¶ËÏòÓÒɨÃèÖ±µ½ÕÒµ½µÚÒ»¸ö´óÓÚµÈÓÚËüµÄÔªËØ£¬ÔÙ´ÓÊý×éµÄÓÒ¶ËÏò×óɨÃèÕÒµ½µÚÒ»¸öСÓÚµÈÓÚËüµÄÔªËØ£¬½»»»ÕâÁ½¸öÔªËØ£¬²¢²»¶Ï¼ÌÐøÕâ¸ö¹ý³Ì£¬¾Í¿ÉÒÔ±£Ö¤×óÖ¸ÕëµÄ×ó²àÔªËØ¶¼²»´óÓÚÇзÖÔªËØ£¬ÓÒÖ¸Õë j µÄÓÒ²àÔªËØ¶¼²»Ð¡ÓÚÇзÖÔªËØ¡£µ±Á½¸öÖ¸ÕëÏàÓöʱ£¬½«ÇзÖÔªËØ a[lo] ºÍ×ó×ÓÊý×é×îÓÒ²àµÄÔªËØ a[j] ½»»»È»ºó·µ»Ø j ¼´¿É¡£ @@ -716,7 +720,7 @@ public class QuickSort { } ``` -### ÐÔÄÜ·ÖÎö +### 3. ÐÔÄÜ·ÖÎö ¿ìËÙÅÅÐòÊÇÔ­µØÅÅÐò£¬²»ÐèÒª¸¨ÖúÊý×飬µ«Êǵݹéµ÷ÓÃÐèÒª¸¨ÖúÕ»¡£ @@ -724,17 +728,17 @@ public class QuickSort { ×µÄÇé¿öÏ£¬µÚÒ»´Î´Ó×îСµÄÔªËØÇз֣¬µÚ¶þ´Î´ÓµÚ¶þСµÄÔªËØÇз֣¬Èç´ËÕâ°ã¡£Òò´Ë×µÄÇé¿öÏÂÐèÒª±È½Ï N2/2¡£ÎªÁË·ÀÖ¹Êý×é×ʼ¾ÍÊÇÓÐÐòµÄ£¬ÔÚ½øÐпìËÙÅÅÐòʱÐèÒªËæ»ú´òÂÒÊý×é¡£ -### Ëã·¨¸Ä½ø +### 4. Ëã·¨¸Ä½ø -#### Çл»µ½²åÈëÅÅÐò +#### 4.1 Çл»µ½²åÈëÅÅÐò ÒòΪ¿ìËÙÅÅÐòÔÚСÊý×éÖÐÒ²»áµ÷ÓÃ×Ô¼º£¬¶ÔÓÚСÊý×飬²åÈëÅÅÐò±È¿ìËÙÅÅÐòµÄÐÔÄܸüºÃ£¬Òò´ËÔÚСÊý×éÖпÉÒÔÇл»µ½²åÈëÅÅÐò¡£ -#### ÈýÈ¡Ñù +#### 4.2 ÈýÈ¡Ñù ×îºÃµÄÇé¿öÏÂÊÇÿ´Î¶¼ÄÜÈ¡Êý×éµÄÖÐλÊý×÷ΪÇзÖÔªËØ£¬µ«ÊǼÆËãÖÐλÊýµÄ´ú¼ÛºÜ¸ß¡£ÈËÃÇ·¢ÏÖÈ¡ 3 ¸öÔªËØ²¢½«´óС¾ÓÖеÄÔªËØ×÷ΪÇзÖÔªËØµÄЧ¹û×îºÃ¡£ -#### ÈýÏòÇÐ·Ö +#### 4.3 ÈýÏòÇÐ·Ö ¶ÔÓÚÓдóÁ¿Öظ´ÔªËصÄÊý×飬¿ÉÒÔ½«Êý×éÇзÖΪÈý²¿·Ö£¬·Ö±ð¶ÔӦСÓÚ¡¢µÈÓںʹóÓÚÇзÖÔªËØ¡£ @@ -764,7 +768,7 @@ public class Quick3Way { ÓÅÏȶÓÁÐÖ÷ÒªÓÃÓÚ´¦Àí×î´óÔªËØ¡£ -### ¶Ñ +### 1. ¶Ñ ¶¨Ò壺һ¿Å¶þ²æÊ÷µÄÿ¸ö½Úµã¶¼´óÓÚµÈÓÚËüµÄÁ½¸ö×ӽڵ㡣 @@ -801,7 +805,7 @@ public class MaxPQ { } ``` -### Éϸ¡ºÍϳÁ +### 2. Éϸ¡ºÍϳÁ ÔÚ¶ÑÖУ¬µ±Ò»¸ö½Úµã±È¸¸½Úµã´ó£¬ÄÇôÐèÒª½»»»Õâ¸öÁ½¸ö½Úµã¡£½»»»ºó»¹¿ÉÄܱÈËüеĸ¸½Úµã´ó£¬Òò´ËÐèÒª²»¶ÏµØ½øÐбȽϺͽ»»»²Ù×÷¡£°ÑÕâÖÖ²Ù×÷³ÆÎªÉϸ¡¡£ @@ -828,7 +832,7 @@ private void sink(int k) { } ``` -### ²åÈëÔªËØ +### 3. ²åÈëÔªËØ ½«ÐÂÔªËØ·Åµ½Êý×éĩβ£¬È»ºóÉϸ¡µ½ºÏÊʵÄλÖᣠ@@ -839,7 +843,7 @@ public void insert(Key v) { } ``` -### ɾ³ý×î´óÔªËØ +### 4. ɾ³ý×î´óÔªËØ ´ÓÊý×é¶¥¶Ëɾ³ý×î´óµÄÔªËØ£¬²¢½«Êý×éµÄ×îºóÒ»¸öÔªËØ·Åµ½¶¥¶Ë£¬²¢ÈÃÕâ¸öÔªËØÏ³Áµ½ºÏÊʵÄλÖᣠ@@ -853,9 +857,9 @@ public Key delMax() { } ``` -### ¶ÑÅÅÐò +### 5. ¶ÑÅÅÐò -ÓÉÓÚ¶Ñ¿ÉÒÔºÜÈÝÒ׵õ½×î´óµÄÔªËØ²¢É¾³ýËü£¬²»¶ÏµØ½øÐÐÕâÖÖ²Ù×÷¿ÉÒԵõ½Ò»¸öµÝ¼õÐòÁС£Èç¹û°Ñ×î´óÔªËØºÍµ±Ç°¶ÑÖÐÊý×éµÄ×îºóÒ»¸öÔªËØ½»»»Î»Ö㬲¢ÇÒ²»É¾³ýËü£¬ÄÇô¾Í¿ÉÒԵõ½Ò»¸ö´Óβµ½Í·µÄµÝ¼õÐòÁУ¬´ÓÕýÏòÀ´¿´¾ÍÊÇÒ»¸öµÝÔöÐòÁС£Òò´ËºÜÈÝÒ×ʹÓöÑÀ´½øÐÐÅÅÐò£¬²¢ÇÒ¶ÑÅÅÐòÊÇÔ­µØÅÅÐò£¬²»Õ¼ÓöîÍâ¿Õ¼ä¡£ +ÓÉÓÚ¶Ñ¿ÉÒÔºÜÈÝÒ׵õ½×î´óµÄÔªËØ²¢É¾³ýËü£¬²»¶ÏµØ½øÐÐÕâÖÖ²Ù×÷¿ÉÒԵõ½Ò»¸öµÝ¼õÐòÁС£Èç¹û°Ñ×î´óÔªËØºÍµ±Ç°¶ÑÖÐÊý×éµÄ×îºóÒ»¸öÔªËØ½»»»Î»Ö㬲¢ÇÒ²»É¾³ýËü£¬ÄÇô¾Í¿ÉÒԵõ½Ò»¸ö´Óβµ½Í·µÄµÝ¼õÐòÁУ¬´ÓÕýÏòÀ´¿´¾ÍÊÇÒ»¸öµÝÔöÐòÁС£Òò´ËºÜÈÝÒ×ʹÓöÑÀ´½øÐÐÅÅÐò£¬²¢ÇÒ¶ÑÅÅÐòÊÇÔ­µØÅÅÐò£¬²»Õ¼ÓöîÍâ¿Õ¼ä¡£ ¶ÑÅÅÐòÒª·ÖÁ½¸ö½×¶Î£¬µÚÒ»¸ö½×¶ÎÊǰÑÎÞÐòÊý×齨Á¢Ò»¸ö¶Ñ£»µÚ¶þ¸ö½×¶ÎÊǽ»»»×î´óÔªËØºÍµ±Ç°¶ÑµÄÊý×é×îºóÒ»¸öÔªËØ£¬²¢ÇÒ½øÐÐϳÁ²Ù×÷ά³Ö¶ÑµÄÓÐÐò״̬¡£ @@ -876,7 +880,7 @@ public static void sort(Comparable[] a){ } ``` -### ·ÖÎö +### 6. ·ÖÎö Ò»¸ö¶ÑµÄ¸ß¶ÈΪ lgN£¬Òò´ËÔÚ¶ÑÖвåÈëÔªËØºÍɾ³ý×î´óÔªËØµÄ¸´ÔӶȶ¼Îª lgN¡£ @@ -888,17 +892,17 @@ public static void sort(Comparable[] a){ ## Ó¦Óà -### ÅÅÐòËã·¨µÄ±È½Ï +### 1. ÅÅÐòËã·¨µÄ±È½Ï ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/be53c00b-2534-4dc6-ad03-c55995c47db9.jpg) -¿ìËÙÅÅÐòʱ×î¿ìµÄͨÓÃÅÅÐòËã·¨£¬ËüµÄÄÚÑ­»·µÄÖ¸ÁîºÜÉÙ£¬¶øÇÒËü»¹ÄÜÀûÓûº´æ£¬ÒòΪËü×ÜÊÇ˳ÐòµØ·ÃÎÊÊý¾Ý¡£ËüµÄÔËÐÐʱ¼äÔö³¤ÊýÁ¿¼¶Îª $\~cNlgN$£¬ÕâÀïµÄ c ±ÈÆäËûÏßÐÔ¶ÔÊý¼¶±ðµÄÅÅÐòËã·¨¶¼ÒªÐ¡¡£Ê¹ÓÃÈýÏòÇзÖÖ®ºó£¬Êµ¼ÊÓ¦ÓÃÖпÉÄܳöÏÖµÄijЩ·Ö²¼µÄÊäÈëÄܹ»´ïµ½ ÏßÐÔ¼¶±ð£¬¶øÆäËüÅÅÐòËã·¨ÈÔÈ»ÐèÒªÏßÐÔ¶ÔÊýʱ¼ä¡£ +¿ìËÙÅÅÐòʱ×î¿ìµÄͨÓÃÅÅÐòËã·¨£¬ËüµÄÄÚÑ­»·µÄÖ¸ÁîºÜÉÙ£¬¶øÇÒËü»¹ÄÜÀûÓûº´æ£¬ÒòΪËü×ÜÊÇ˳ÐòµØ·ÃÎÊÊý¾Ý¡£ËüµÄÔËÐÐʱ¼äÔö³¤ÊýÁ¿¼¶Îª \~cNlgN£¬ÕâÀïµÄ c ±ÈÆäËûÏßÐÔ¶ÔÊý¼¶±ðµÄÅÅÐòËã·¨¶¼ÒªÐ¡¡£Ê¹ÓÃÈýÏòÇзÖÖ®ºó£¬Êµ¼ÊÓ¦ÓÃÖпÉÄܳöÏÖµÄijЩ·Ö²¼µÄÊäÈëÄܹ»´ïµ½ÏßÐÔ¼¶±ð£¬¶øÆäËüÅÅÐòËã·¨ÈÔÈ»ÐèÒªÏßÐÔ¶ÔÊýʱ¼ä¡£ -### Java µÄÅÅÐòË㷨ʵÏÖ +### 2. Java µÄÅÅÐòË㷨ʵÏÖ Java ϵͳ¿âÖеÄÖ÷ÒªÅÅÐò·½·¨Îª java.util.Arrays.sort()£¬¶ÔÓÚԭʼÊý¾ÝÀàÐÍʹÓÃÈýÏòÇзֵĿìËÙÅÅÐò£¬¶ÔÓÚÒýÓÃÀàÐÍʹÓù鲢ÅÅÐò¡£ -### »ùÓÚÇзֵĿìËÙÑ¡ÔñËã·¨ +### 3. »ùÓÚÇзֵĿìËÙÑ¡ÔñËã·¨ ¿ìËÙÅÅÐòµÄ partition() ·½·¨£¬»á½«Êý×éµÄ a[lo] ÖÁ a[hi] ÖØÐÂÅÅÐò²¢·µ»ØÒ»¸öÕûÊý j ʹµÃ a[lo..j-1] СÓÚµÈÓÚ a[j]£¬ÇÒ a[j+1..hi] ´óÓÚµÈÓÚ a[j]¡£ÄÇôÈç¹û j=k£¬a[j] ¾ÍÊÇµÚ k ¸öÊý¡£ @@ -917,20 +921,19 @@ Java ϵͳ } ``` - # µÚÈýÕ ²éÕÒ ±¾ÕÂʹÓÃÈýÖÖ¾­µäµÄÊý¾ÝÀàÐÍÀ´ÊµÏÖ¸ßЧµÄ·ûºÅ±í£º¶þ²æ²éÕÒÊ÷¡¢ºìºÚÊ÷ºÍÉ¢ÁÐ±í¡£ ## ·ûºÅ±í -### API +### 1. API ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b69d7184-ab62-4957-ba29-fb4fa25f9b65.jpg) µ±Ò»¸ö¼üµÄֵΪ null ʱ£¬±íʾ²»´æÔÚÕâ¸ö¼ü£¬Òò´Ë¿ÉÒÔʹÓà put(key, null) ×÷Ϊ delete(key) µÄÒ»ÖÖÑÓ³ÙʵÏÖ¡£ -### ÓÐÐò·ûºÅ±í +### 2. ÓÐÐò·ûºÅ±í ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ba6ae411-82da-4d86-a434-6776d1731e8e.jpg) @@ -938,11 +941,11 @@ Java ϵͳ ²éÕҵijɱ¾Ä£ÐÍ£º¼üµÄ±È½Ï´ÎÊý£¬ÔÚ²»½øÐбȽÏʱʹÓÃÊý×éµÄ·ÃÎÊ´ÎÊý¡£ -### ÎÞÐòÁ´±íʵÏÖ +### 3. ÎÞÐòÁ´±íʵÏÖ ¸´ÔÓ¶È£ºÏòÒ»¸ö¿Õ±íÖвåÈë N ¸ö²»Í¬µÄ¼üÐèÒª \~N2/2 ´Î±È½Ï¡£ -### ÓÐÐòÊý×éµÄ¶þ·Ö²éÕÒ +### 4. ÓÐÐòÊý×éµÄ¶þ·Ö²éÕÒ Ê¹ÓÃÒ»¶ÔƽÐÐÊý×飬һ¸ö´æ´¢¼üÒ»¸ö´æ´¢Öµ¡£ @@ -1007,7 +1010,7 @@ public class BinarySearchST, Value> { } ``` -### ¶Ô¶þ·Ö²éÕҵķÖÎö +### 5. ¶Ô¶þ·Ö²éÕҵķÖÎö ¸´ÔÓ¶È£º¶þ·Ö²éÕÒ×î¶àÐèÒª lgN+1 ´Î±È½Ï£¬Ê¹Óöþ·Ö²éÕÒʵÏֵķûºÅ±íµÄ²éÕÒ²Ù×÷ËùÐèÒªµÄʱ¼ä×î¶àÊǶÔÊý¼¶±ðµÄ¡£µ«ÊDzåÈë²Ù×÷ÐèÒªÒÆ¶¯Êý×éÔªËØ£¬ÊÇÏßÐÔ¼¶±ðµÄ¡£ @@ -1027,7 +1030,8 @@ public class BST, Value> { private Key key; private Value val; private Node left, right; - private int N; // ÒԸýڵãΪ¸ùµÄ×ÓÊ÷Öнڵã×ÜÊý + // ÒԸýڵãΪ¸ùµÄ×ÓÊ÷Öнڵã×ÜÊý + private int N; public Node(Key key, Value val, int N) { this.key = key; @@ -1047,7 +1051,7 @@ public class BST, Value> { } ``` -### get() +### 1. get() Èç¹ûÊ÷Êǿյģ¬Ôò²éÕÒδÃüÖУ»Èç¹û±»²éÕҵļüºÍ¸ù½ÚµãµÄ¼üÏàµÈ£¬²éÕÒÃüÖУ¬·ñÔòµÝ¹éµØÔÚ×ÓÊ÷ÖвéÕÒ£ºÈç¹û±»²éÕҵļü½ÏС¾ÍÔÚ×ó×ÓÊ÷ÖвéÕÒ£¬½Ï´ó¾ÍÔÚÓÒ×ÓÊ÷ÖвéÕÒ¡£ @@ -1064,7 +1068,7 @@ private Value get(Node x, Key key) { } ``` -### put() +### 2. put() µ±²åÈëµÄ¼ü²»´æÔÚÓÚÊ÷ÖУ¬ÐèÒª´´½¨Ò»¸öнڵ㣬²¢ÇÒ¸üÐÂÉϲã½ÚµãµÄÁ´½ÓʹµÃ¸Ã½ÚµãÕýÈ·Á´½Óµ½Ê÷ÖС£ @@ -1083,7 +1087,7 @@ private Node put(Node x, Key key, Value val) { } ``` -### ·ÖÎö +### 3. ·ÖÎö ¶þ²æ²éÕÒÊ÷µÄËã·¨ÔËÐÐʱ¼äÈ¡¾öÓÚÊ÷µÄÐÎ×´£¬¶øÊ÷µÄÐÎ×´ÓÖÈ¡¾öÓÚ¼ü±»²åÈëµÄÏȺó˳Ðò¡£×îºÃµÄÇé¿öÏÂÊ÷ÊÇÍêȫƽºâµÄ£¬Ã¿Ìõ¿ÕÁ´½ÓºÍ¸ù½ÚµãµÄ¾àÀ붼Ϊ lgN¡£ÔÚ×µÄÇé¿öÏ£¬Ê÷µÄ¸ß¶ÈΪ N¡£ @@ -1091,7 +1095,7 @@ private Node put(Node x, Key key, Value val) { ¸´ÔÓ¶È£º²éÕҺͲåÈë²Ù×÷¶¼Îª¶ÔÊý¼¶±ð¡£ -### floor() +### 4. floor() Èç¹û key СÓÚ¸ù½ÚµãµÄ key£¬ÄÇôСÓÚµÈÓÚ key µÄ×î´ó¼ü½ÚµãÒ»¶¨ÔÚ×ó×ÓÊ÷ÖУ»Èç¹û key ´óÓÚ¸ù½ÚµãµÄ key£¬Ö»Óе±¸ù½ÚµãÓÒ×ÓÊ÷ÖдæÔÚСÓÚµÈÓÚ key µÄ½Úµã£¬Ð¡ÓÚµÈÓÚ key µÄ×î´ó¼ü½Úµã²ÅÔÚÓÒ×ÓÊ÷ÖУ¬·ñÔò¸ù½Úµã¾ÍÊÇСÓÚµÈÓÚ key µÄ×î´ó¼ü½Úµã¡£ @@ -1115,7 +1119,7 @@ private Node floor(Node x, Key key) { } ``` -### rank() +### 5. rank() ```java public int rank(Key key) { @@ -1130,7 +1134,7 @@ private int rank(Key key, Node x) { } ``` -### min() +### 6. min() ```java private Node min(Node x) { @@ -1139,7 +1143,7 @@ private Node min(Node x) { } ``` -### deleteMin() +### 7. deleteMin() ÁîÖ¸Ïò×îС½ÚµãµÄÁ´½ÓÖ¸Ïò×îС½ÚµãµÄÓÒ×ÓÊ÷¡£ @@ -1157,7 +1161,7 @@ public Node deleteMin(Node x) { } ``` -### delete() +### 8. delete() Èç¹û´ýɾ³ýµÄ½ÚµãÖ»ÓÐ×ÓÊ÷£¬ÄÇôֻÐèÒªÈÃÖ¸Ïò½ÚµãµÄÁ´½ÓÖ¸ÏòΨһµÄ×ÓÊ÷¼´¿É£»·ñÔò£¬ÈÃÓÒ×ÓÊ÷µÄ×îС½ÚµãÌæ»»¸Ã½Úµã¡£ @@ -1185,7 +1189,7 @@ private Node delete(Node x, Key key) { } ``` -### keys() +### 9. keys() ÀûÓöþ²æ²éÕÒÊ÷ÖÐÐò±éÀúµÄ½á¹ûΪÓÐÐòÐòÁеÄÌØµã¡£ @@ -1205,7 +1209,7 @@ private void keys(Node x, Queue queue, Key lo, Key hi) { } ``` -### ÐÔÄÜ·ÖÎö +### 10. ÐÔÄÜ·ÖÎö ¸´ÔÓ¶È£º¶þ²æ²éÕÒÊ÷ËùÓвÙ×÷ÔÚ×µÄÇé¿öÏÂËùÐèÒªµÄʱ¼ä¶¼ºÍÊ÷µÄ¸ß¶È³ÉÕý±È¡£ @@ -1217,13 +1221,13 @@ private void keys(Node x, Queue queue, Key lo, Key hi) { Ò»¿ÅÍêÃÀƽºâµÄ 2-3 ²éÕÒÊ÷µÄËùÓпÕÁ´½Óµ½¸ù½ÚµãµÄ¾àÀëÓ¦¸ÃÊÇÏàͬµÄ¡£ -#### ²åÈë²Ù×÷ +#### 1. ²åÈë²Ù×÷ µ±²åÈëÖ®ºó²úÉúÒ»¸öÁÙʱ 4- ½Úµãʱ£¬ÐèÒª½« 4- ½Úµã·ÖÁÑ³É 3 ¸ö 2- ½Úµã£¬²¢½«ÖмäµÄ 2- ½ÚµãÒÆµ½Éϲã½ÚµãÖУ¬Èç¹ûÉÏÒÆ²Ù×÷¼ÌÐø²úÉúÁÙʱ 4- ½ÚµãÔòÒ»Ö±½øÐзÖÁÑÉÏÒÆ£¬Ö±µ½²»´æÔÚÁÙʱ 4- ½Úµã¡£ ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/912174d8-0786-4222-b7ef-a611d36e5db9.jpg) -#### ÐÔÖÊ +#### 2. ÐÔÖÊ 2-3 ²éÕÒÊ÷²åÈë²Ù×÷µÄ±ä»»¶¼ÊǾֲ¿µÄ£¬³ýÁËÏà¹ØµÄ½ÚµãºÍÁ´½ÓÖ®Íâ²»±ØÐ޸ĻòÕß¼ì²éÊ÷µÄÆäËü²¿·Ö£¬¶øÕâЩ¾Ö²¿±ä»»²»»áÓ°ÏìÊ÷µÄÈ«¾ÖÓÐÐòÐÔºÍÆ½ºâÐÔ¡£ @@ -1272,7 +1276,7 @@ public class RedBlackBST, Value> { } ``` -#### ×óÐýת +#### 1. ×óÐýת ÒòΪºÏ·¨µÄºìÁ´½Ó¶¼Îª×óÁ´½Ó£¬Èç¹û³öÏÖÓÒÁ´½ÓΪºìÁ´½Ó£¬ÄÇô¾ÍÐèÒª½øÐÐ×óÐýת²Ù×÷¡£ @@ -1293,7 +1297,7 @@ public Node rotateLeft(Node h) { } ``` -#### ÓÒÐýת +#### 2. ÓÒÐýת ½øÐÐÓÒÐýתÊÇΪÁËת»»Á½¸öÁ¬ÐøµÄ×óºìÁ´½Ó£¬Õâ»áÔÚÖ®ºóµÄ²åÈë¹ý³ÌÖÐ̽ÌÖ¡£ @@ -1313,7 +1317,7 @@ public Node rotateRight(Node h) { } ``` -#### ÑÕɫת»» +#### 3. ÑÕɫת»» Ò»¸ö 4- ½ÚµãÔÚºìºÚÊ÷ÖбíÏÖΪһ¸ö½ÚµãµÄ×óÓÒ×ӽڵ㶼ÊǺìÉ«µÄ¡£·ÖÁÑ 4- ½Úµã³ýÁËÐèÒª½«×Ó½ÚµãµÄÑÕÉ«Óɺì±äºÚÖ®Í⣬ͬʱÐèÒª½«¸¸½ÚµãµÄÑÕÉ«Óɺڱäºì£¬´Ó 2-3 Ê÷µÄ½Ç¶È¿´¾ÍÊǽ«Öмä½ÚµãÒÆµ½Éϲã½Úµã¡£ @@ -1329,7 +1333,7 @@ void flipColors(Node h){ } ``` -#### ²åÈë +#### 4. ²åÈë ²åÈëËã·¨£º @@ -1365,7 +1369,7 @@ private Node put(Node x, Key key, Value val) { ¸ù½ÚµãÒ»¶¨ÎªºÚÉ«£¬ÒòΪ¸ù½ÚµãûÓÐÉϲã½Úµã£¬Ò²¾ÍûÓÐÉϲã½ÚµãµÄ×óÁ´½ÓÖ¸Ïò¸ù½Úµã¡£flipColors() ÓпÉÄÜ»áʹµÃ¸ù½ÚµãµÄÑÕÉ«±äΪºìÉ«£¬Ã¿µ±¸ù½ÚµãÓɺìÉ«±ä³ÉºÚɫʱÊ÷µÄºÚÁ´½Ó¸ß¶È¼Ó 1. -#### ɾ³ý×îС¼ü +#### 5. ɾ³ý×îС¼ü Èç¹û×îС¼üÔÚÒ»¸ö 2- ½ÚµãÖУ¬ÄÇôɾ³ý¸Ã¼ü»áÁôÏÂÒ»¸ö¿ÕÁ´½Ó£¬¾ÍÆÆ»µÁËÆ½ºâÐÔ£¬Òò´ËҪȷ±£×îС¼ü²»ÔÚ 2- ½ÚµãÖС£½« 2- ½Úµãת»»³É 3- ½Úµã»òÕß 4- ½ÚµãÓÐÁ½ÖÖ·½·¨£¬Ò»ÖÖÊÇÏòÉϲã½ÚµãÄÃÒ»¸ö key£¬»òÕßÏòÐֵܽڵãÄÃÒ»¸ö key¡£Èç¹ûÉϲã½ÚµãÊÇ 2- ½Úµã£¬ÄÇô¾Íû°ì·¨´ÓÉϲã½ÚµãÄà key ÁË£¬Òò´ËÒª±£Ö¤É¾³ý·¾¶ÉϵÄËùÓнڵ㶼²»ÊÇ 2- ½Úµã¡£ÔÚÏòÏÂɾ³ýµÄ¹ý³ÌÖУ¬±£Ö¤ÒÔÏÂÇé¿öÖ®Ò»·¢Éú£º @@ -1379,7 +1383,7 @@ private Node put(Node x, Key key, Value val) { ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/70b66757-755c-4e17-a7b7-5ce808023643.png) -#### ·ÖÎö +#### 6. ·ÖÎö Ò»¿Å´óСΪ N µÄºìºÚÊ÷µÄ¸ß¶È²»»á³¬¹ý 2lgN¡£×µÄÇé¿öÏÂÊÇËüËù¶ÔÓ¦µÄ 2-3 Ê÷Öй¹³É×î×ó±ßµÄ·¾¶½ÚµãÈ«²¿¶¼ÊÇ 3- ½Úµã¶øÆäÓà¶¼ÊÇ 2- ½Úµã¡£