mysql5.7字段设计需要为非null,尤其是索引列,原理讲述
mysql官方文档地址: https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html
在mysql5.7官方文档描述中,可以使用innodb_stat_method来区别处理列的null值,处理方式有3种:
1、nulls_equal 所有的null值都是相等的 (mysql在官方doc文档中,理论上默认采用此策略)
2、nulls_unequal 所有的null值都是不相等的,都是需特殊处理的
3、nulls_ignored 完全忽略
由于mysql在连上采用的是 nulls_unequal 策略,但是在列值计算时,又采用了nulls_equal 这个null 值都相等的(默认)策略,所以mysql本身对null值的处理也是很分裂的。
所以建立索引列时,一定不要允许null值,因为null的原因会使查询从const高性能变成其他更低性能的。
性能变低的原因参考《为什么数据库中要使用B+tree索引,而不用hash索引?MySQL中的B+tree索引介绍》 和 《mysql5.7版本的explain解析》
注意:虽然mysql提供了innodb_stat_method的3个可选值,但是有证据表明,更改值是不起作用的,因为默认值已经写死到代码里了。
null值弊端
1)null值容易使索引失效。 在SQL中,is not null 容易导致索引失效,is null则会区分被检索的列是否为null,如果是null则会走ref类型的索引访问,如果不为null,也是全表扫描。
2)count列容易失误。如果一个列username有四行数据,值分别为: null、null、zhangsan、lisi,那么select count(*) from t_user 的值为4,但是 select count(username) from t_user 的值则为2,所以要谨慎使用 null.
3) MySQL处理null值很分裂。首先,mysql认为nul 是一个不确定的值:null = null 返回null, null != null 还是返回 null。但是在上面的count例子中,mysql又认为null值完全无意义,统计的时候直接忽略不统计。
4)允许null值可能会使索引失效。null值太多的时候,mysql 在认为所有null值都是同一份时,会认为该索引列离散性不高,会放弃走索引而走全表扫描。
end.