表的优化与列类型选择
表的优化
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 做了优化,大小区别已不明显,但查询还是不便