表的优化与列类型选择

表的优化

0.定长与变长分离
如:id int 占四个字节 ,char(4)占四个字节 ,也叫定长,time等
即每一单元值占用字节是固定的,
核心常用字段建成定长放在一张表内,
而varchar text 这种变长字段,适合放单一一张表,用主键与核心关联起来。

1.反范式建表(添加冗余字段)
如:论坛类别表中添加统计 帖子数量 字段 来减少频繁连表查询

列选择原则

  • 字段类型优先级: 整型 > date,time > enum,char > varchar >blob.text
    列的特点:
    整型:
    定长 没有国家,地区之分,没有字符集差异
    比如:tinyint 1,2.3.4.5 <–> char(1) a,b,c,d,e
    从空间上都是一个字节,但是order by 前者块 ,
    因为后者要考虑字符集跟校对集(就是排序规则)
    time:
    定长, 运算快 节省空间 ,考虑时区,写SQL是不方便, 如: where > ‘2019-5-17’
    enum:
    enum 在内部使用整型来存储,
    enum 与enum 列进行关联查询时最快
    enum 比 (var)char 优势在于 当(var)char 非常长时 , enum 依然是 整型固定长度,
    劣势在于 再碰到与char 关联时,要转化 ,要花时间
    enum 与(var)char关联 ,因为要转化 速度要比 char->char enum->enum 速度慢
    enum 能起到约束值的目的,内部用整型来存储,但与char 联查时,内部要经过字符串与值得转化
    如: 设置一个字段为 enum(‘男’,‘女’) 那么这个字段只能接受这两个值
    char:
    char 定长 考虑字符集 与排序校对集
    varchar
    不定长 考虑字符集 与排序校对集 速度慢

text,blob
无法使用内存临时表(排序等只能在磁盘上进行)

以性别为例 ,字符集为utf8时,
char(1) //占用三个字节,
enum('男','女‘) //内部转换成数字,多了一个转换过程
tinyint() //0 1 2  定长一个字节 最快

关于date time 的选择 大师的明确意见 直接选 int unsgined not null 存储时间戳 ,
http://www.xaprb.com/blog/2014/01/30/timestamps-in-mysql

  • 尽量设立合理的字段 够用就行
    原因: 大的字段浪费内存越多 影响速度
    以年龄为例 如果 只存储 人的年龄 可以使用 tinyint unsgined not null 足够, 用int 浪费了三个字节
    varchar(10)与varcchar(300) 存储相同的内容 ,但是表联查时,varchar(300)会耗用更长的时间
  • 尽量避免使用null,因为null不利于索引,要用特殊字节来标记,在磁盘上占用的空间更大,不过MySQL5.5之后已对null 做了优化,大小区别已不明显,但查询还是不便