Mysql性能优化(1) 从新建一个表开始

前方预警,本文不太适合老司机阅读,毕竟工作几年的老司机都有自己一套Mysql优化的套路,此文适合接触了Mysql但是不是很深入了解Mysql的人阅读。


当使用Mysql的时候,我们操作的单位就是表,而一个表的设计从一个开始就决定着Mysql的性能优化,有些貌似看起来合理的,却在蒙蔽自己的眼睛。只有一层层剥开,才会慢慢发现,最本质的才是最真的。

新建一个表最先想到的就是表名,最常见的命名方式为t_xxxx。其次是字段名。我习惯于使用FuiXxxxFstrXxxx这两种形式的命名方式。其中“F”是field的缩写,“ui” 是unsigned int的缩写,”str”自然是string的缩写。通过字段的前缀能够清楚知道短信的大概类型。当然有人会问,为什么没有标识浮点数。这是因为个人喜欢将浮点数放大n倍存储为一个较大的整形放在数据库,这样做的目的一方面是因为整形运算会比浮点运算快,另一方面是因为浮点运算会有精度丢失问题,有时候会造成严重影响,比如资金方面的运算可能会造成对账对不平。当然每个人或着每个公司都有自己的命名方案,一个好的命名在程序开发中将带来可观的效率。


开发中最长建的表就是用户基本信息表t_user,在这个表中一般包含的字段包括,用户ID,姓名,昵称,性别,年龄,邮箱,电话号码等。
很容易得到表的雏形。

CREATE TABLE IF NOT EXISTS `test`.`t_user` (
  `FstrUid` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '用户id',
  `FstrName` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '用户姓名',
  `FstrNick` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '用户昵称',
  `FuiSex` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0-男,1-女',
  `FuiAge` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',
  `FstrEmail` VARCHAR(48) NOT NULL DEFAULT '' COMMENT '邮箱',
  `FstrMobile` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '电话号码')
ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COMMENT '用户基本信息表'

在表的雏形中加入了 not null 约束,一般加入not null 约束的时候都需要给字段添加上DEFAULT,当然不加入也没有什么事,但是当数据库运行在严格模式的时候,插入会失败。还有人会问,为什么都要加入not null 约束?这是因为在mysql中,如果一列中含有null值的时候很难进行优化查询,它会使得索引(后续会有bolg)的计算变得很复杂。所以新建表的时候,最好都加上not null 和 DEFAULT,当然有的类型不能定义DEFAULT除外。


细心的人或许会发现,雏形表中少了很关键的主键约束。是的,关于一个表的主键约束定义,似乎很多很多字段都很合理,FstrUid一定可以,因为它绝对是唯一的。FstrMobile貌似也可以,很多平台都是一个电话号码注册的,也能保证唯一。但是如果用户换手机了呢,这一点,就能说明电话号码不太合适。FstrNick似乎可以,很多平台这个字段是不会变的,而且是唯一的。在我们的雏形表中适合做主键索引的貌似有FstrUid和FstrNick,如果我选的话,我还是选FstrUid合适。

实际上,真正的赢家一般都不会出场太早,适合做主键的是一个叫自增id的字段。why?我当时也这样懵圈过。经过一段时间站在巨人(google)肩膀上的学习,终于明白。在InnoDB引擎表中,它会选择主键作为聚集索引,其数据结构为B+树,当数据插入的时候,根据B+树的插入规则,会引起节点的分裂,造成开销。如果是自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。如果是非自增主键,每次插入主键的值近似于随机,新纪录都要被插到现有索引页的中间某个位置,造成巨大的开销。具体的说明,可以参考博客mysql中InnoDB表为什么要建议用自增列做主键。

终上所述,最终得到的t_user表的样式为

CREATE TABLE IF NOT EXISTS `test`.`t_user` (
  `FuiId` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `FuiStatus` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户状态,注销,冻结,正常...',
  `FstrUid` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '用户id',
  `FstrName` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '用户姓名',
  `FstrNick` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '用户昵称',
  `FstrMobile` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '电话号码',
  `FuiSex` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0-男,1-女',
  `FuiAge` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',
  `FstrEmail` VARCHAR(48) NOT NULL DEFAULT '' COMMENT '邮箱',
  `FuiCreateTime` INT(20) UNSIGNED NOT NULL DEFAULT '',
  `FuiUpdateTime` TIMESTAMP NOT NULL DEFAULT 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
  PRIMARY KEY (`FuiId`),
  UNIQUE INDEX `FstrUid_UNIQUE` (`FstrUid`))
ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COMMENT '用户基本信息表'

表建好了,对表的操作无非就是增,删,该,查。如果做到这些操作都高效的执行?优化之路漫漫,修行之路才刚刚开始。

你可能感兴趣的:(mysql,性能优化,mysql,性能优化)