首页 > 代码库 > MySQL优化四(优化表结构)

MySQL优化四(优化表结构)

<style type="text/css">body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10px; padding-bottom: 10px; background-color: white; padding: 30px } body>*:first-child { margin-top: 0 !important } body>*:last-child { margin-bottom: 0 !important } a { color: #4183C4 } a.absent { color: #cc0000 } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0; left: 0; bottom: 0 } h1,h2,h3,h4,h5,h6 { margin: 20px 0 10px; padding: 0; font-weight: bold; cursor: text; position: relative } h1:hover a.anchor,h2:hover a.anchor,h3:hover a.anchor,h4:hover a.anchor,h5:hover a.anchor,h6:hover a.anchor { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==") no-repeat 10px center; text-decoration: none } h1 tt,h1 code { font-size: inherit } h2 tt,h2 code { font-size: inherit } h3 tt,h3 code { font-size: inherit } h4 tt,h4 code { font-size: inherit } h5 tt,h5 code { font-size: inherit } h6 tt,h6 code { font-size: inherit } h1 { font-size: 28px; color: black } h2 { font-size: 24px; border-bottom: 1px solid #cccccc; color: black } h3 { font-size: 18px } h4 { font-size: 16px } h5 { font-size: 14px } h6 { color: #777777; font-size: 14px } p,blockquote,ul,ol,dl,li,table,pre { margin: 15px 0 } hr { background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC") repeat-x 0 0; border: 0 none; color: #cccccc; height: 4px; padding: 0 } body>h2:first-child { margin-top: 0; padding-top: 0 } body>h1:first-child { margin-top: 0; padding-top: 0 } body>h1:first-child+h2 { margin-top: 0; padding-top: 0 } body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child { margin-top: 0; padding-top: 0 } a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6 { margin-top: 0; padding-top: 0 } h1 p,h2 p,h3 p,h4 p,h5 p,h6 p { margin-top: 0 } li p.first { display: inline-block } li { margin: 0 } ul,ol { padding-left: 30px } ul :first-child,ol :first-child { margin-top: 0 } dl { padding: 0 } dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px } dl dt:first-child { padding: 0 } dl dt>:first-child { margin-top: 0 } dl dt>:last-child { margin-bottom: 0 } dl dd { margin: 0 0 15px; padding: 0 15px } dl dd>:first-child { margin-top: 0 } dl dd>:last-child { margin-bottom: 0 } blockquote { border-left: 4px solid #dddddd; padding: 0 15px; color: #777777 } blockquote>:first-child { margin-top: 0 } blockquote>:last-child { margin-bottom: 0 } table { padding: 0; border-collapse: collapse } table tr { border-top: 1px solid #cccccc; background-color: white; margin: 0; padding: 0 } table tr:nth-child(2n) { background-color: #f8f8f8 } table tr th { font-weight: bold; border: 1px solid #cccccc; margin: 0; padding: 6px 13px } table tr td { border: 1px solid #cccccc; margin: 0; padding: 6px 13px } table tr th :first-child,table tr td :first-child { margin-top: 0 } table tr th :last-child,table tr td :last-child { margin-bottom: 0 } img { max-width: 100% } span.frame { display: block; overflow: hidden } span.frame>span { border: 1px solid #dddddd; display: block; float: left; overflow: hidden; margin: 13px 0 0; padding: 7px; width: auto } span.frame span img { display: block; float: left } span.frame span span { clear: both; color: #333333; display: block; padding: 5px 0 0 } span.align-center { display: block; overflow: hidden; clear: both } span.align-center>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: center } span.align-center span img { margin: 0 auto; text-align: center } span.align-right { display: block; overflow: hidden; clear: both } span.align-right>span { display: block; overflow: hidden; margin: 13px 0 0; text-align: right } span.align-right span img { margin: 0; text-align: right } span.float-left { display: block; margin-right: 13px; overflow: hidden; float: left } span.float-left span { margin: 13px 0 0 } span.float-right { display: block; margin-left: 13px; overflow: hidden; float: right } span.float-right>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: right } code,tt { margin: 0 2px; padding: 0 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8 } pre code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent } .highlight pre { background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px } pre { background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px } pre code,pre tt { background-color: transparent; border: none } sup { font-size: 0.83em; vertical-align: super; line-height: 0 } kbd { display: inline-block; padding: 3px 5px; font-size: 11px; line-height: 10px; color: #555; vertical-align: middle; background-color: #fcfcfc; border: solid 1px #ccc; border-bottom-color: #bbb } * { }</style>

MySQL优化四(优化表)

昨晚吃吃喝喝的太多,熬夜到凌晨二点。今天头发杂乱,脸庞憔悴,像是吸毒了。下午去买衣服,肚子一看大了不少。奈何女朋友还没有一个,就已经发福了。管不住口,迈不开腿。

一、优化表结构

1.尽量将表字段定义为NOT NULL约束,这时由于在MySQL中含有空值的列很难进行查询优化,NULL值会使索引以及索引的统计信息变得很复杂,可以使用0或者空字符串来代替。

2.可以使用enum、set 等符合数据类型。对于只包含特定类型的字段。不过在工作过程中一般就使用tinyint 来表示了。

3.数值型字段的比较比字符串的比较效率高得多,字段类型尽量使用最小、最简单的数据类型。IP地址可以使用int类型。

二、表拆分

1、垂直拆分

垂直拆分按照字段进行拆分,其实就是把组成一行的多个列分开放到不同的表中,这些表具有不同的结构,拆分后的表具有更少的列,例如用户表中的一些字段可能经常访问,可以把这些字段放进一张表里。另外一些不经常使用的信息就可以放进另外一张表里。插入的时候使用事务,也可以保证两表的数据一致。缺点也很明显,由于拆分出来的两张表存在1:1的关系,需要使用冗余字段,而且需要join操作,我们在使用的时候可以分别取两次,这样的来说既可以避免join操作,又可以提高效率。

2、水平拆分

水平拆分按照行进行拆分,常见的就是分库分表。以用户表为例,可以取用户ID,然后使用php的十进制转换16进制的方法 dechex,截取其中的第一个字符,将用户均匀的分配进这 0-9 、a-f 这16个表中。查找的时候也按照这种规则,又快又方便。当然类似的规则很多,也可以使用求余法,按照余数将数据分发进不同的表中。有些表业务关联比较强,那么可以使用按时间划分的。以我公司的某业务为例,每天都要新建一张表。这种业务类型就是需要高速插入,但是对于查询的效率不太关心。表越大,插入数据所需要索引维护的时间也就越长。

三、分区

分区这个概念,我第一次在实践中看到是在去年,数据中心的表按照时间一个月分成一个区。我从这些表中读取数据,然后继续做后续的业务处理。一般来说在主业务中很少使用这种分区概念,使用分区是大数据处理后的产物。比如系统用户的注册推广等等,会产生海量的日志,当然也可以按照时间去建立多张表,但在实际操作中,就发生过一次运维人员忘记切换表,导致数据报错的紧急事件。可见分区适用于日志记录,查询少,一般用于后台的数据报表分析。对于这些数据汇总需求,需要很多日志表去做数据聚合,我们能够容忍1s到2s的延迟,只要数据准确能够满足需求就可以。

MySQL主要支持4种模式的分区:range分区、list预定义列表分区,hash 分区,key键值分区。后几种没有看到数据中心的同事用过,可能是操作不方便,应用不广泛,所以就暂且不讲了。

-- 创建表
create table testpar
(
    f_userid int unsigned not null default 0,
    f_date datetime
)engine=innodb,charset=utf8;

-- 分区
alter table testpar  partition by range columns(f_date) (
    partition p0 values less than (‘2017-01-31‘),
    partition p2 values less than (‘2017-02-20‘)
);

-- 查看表结构
mysql> show create table testpar\G
*************************** 1. row ***************************
       Table: testpar
Create Table: CREATE TABLE `testpar` (
  `f_userid` int(10) unsigned NOT NULL DEFAULT ‘0‘,
  `f_date` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(f_date)
(PARTITION p0 VALUES LESS THAN (‘2017-01-31‘) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (‘2017-02-20‘) ENGINE = InnoDB) */
1 row in set (0.00 sec)

MySQL优化四(优化表结构)