mysql varchar not null_为什么建议MySQL列属性尽量用 NOT NULL

我们在设计表的时候,经常会有老司机这么告诉我们。

字段尽可能用NOT NULL,而不是NULL,除非特殊情况。

这句话到底有没有错?

可以负责任的告诉你这句话没有错,也不是以讹传讹,这句话首次出现在 MySQL 官网。

7bb9fc0b48f5b088f595b51817d85240.png

如果你读过《高性能 MySQL》这本书,你应该会看到这么一段,在 4.1 节提到。

bd89888eaca10ed1313265f59741ba6c.png

由此看来,把 NULL 改成 NOT NULL 对索引的性能并没有明显的提升。避免使用 NULL 的目的,是便于代码的可读性和可维护性。同时这种数据使用起来非常容易挖坑。很多时候,如果sql写得不规范,容易造成数据没有被筛选出来。

有这样一个案例。有一次交易系统出了故障,造成一些订单的没有赠品的数据错误,这个时候就想从数据库里面捞出数据补偿用户,结果订单状态这种核心字段竟然可以为空,加上操作者又是一个新人写得数据库查询sql不规范,导致很多订单都没有筛选出来,加上微博本已发出补偿公告,造成更大的用户投诉。

那么,这种为空的数据库列,筛选有什么坑或者需要注意的地方呢?

1、!=不等于查询异常

举个简单的例子,我们有一堆用户的基本数据,男生设置为1,女生设置为2,未知设置为空,当我们使用数据库查询语句,使用不等于的方式查询女生,最后只能够把男生筛选出来,而不能把未知的筛选出来。

最好的方法,就是把位置的默认设置为0。同样,使用not in等sql语法,也有同样的问题。

2、使用contact的时候异常

我们经常会用数据库存一些用户的收货地址,有时候会使用数据库的contact进行地址的拼接,例如数据库里面存在省份、城市、详细收货地址等字段,如果其中某一个为NULL的话,那么最终拼接出来的结果,也会是NULL。从而达不到预期的效果。

3、使用count可能有异常

如果我们使用count(字段名),如果这个字段刚好为空的时候,就不会被统计进去。

4、对 NULL 做加减操作,如 1 + NULL,结果仍是 NULL

5、order by 以升序检索字段的时候 NULL 会排在最前面(倒序相反)

6、数值类型 在 min / max / sum / avg 中 NULL 值会被直接忽略掉

7、group by / distinct 时,NULL 值被视为相同的值

8、如果你用 length 去统计一个 VARCHAR 的长度时,NULL 返回的将不是数字

select length(name) from t1 where name is null;

+--------------+

| length(name) |

+--------------+

| NULL |

+--------------+

NULL 列需要更多的存储空间,一般需要一个额外的字节作为判断是否为 NULL 的标志位。所以设置允许为空的列比非空字段需要一个额外的字节用于作为判断是否为 NULL 的标志位。

通过Mysql的explain查看key_len值。key_len的长度一般跟这三个因素有关,分别是数据类型,字符编码,是否为 NULL。

总结

如果不是特殊需求,我们尽可能的不要设置字段为空,虽然设置为空对性能的影响不大,但是,特别容易挖坑,毕竟程序员是一个团队协作的工作,少一些潜规则,少一些机关,头发会多一些。

参考文章:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值