MYSQL中建议使用NOT NULL原因[通俗易懂]

MYSQL中建议使用NOT NULL原因[通俗易懂]MySQL官网文档:NULLcolumnsrequireadditionalspaceintherowtorecordwhethertheirvaluesareNULL.ForMyISAMtables,eachNULLcolumntakesonebitextra,roundeduptothenearestbyte.Mysql难以…

大家好,又见面了,我是你们的朋友全栈君。

MySQL 官网文档:

NULL columns require additional space in the rowto record whether their values are NULL. For MyISAM tables, each NULL columntakes one bit extra, rounded up to the nearest byte.

Mysql难以优化引用可空列查询,它会使索引、索引统计和值更加复杂。可空列需要更多的存储空间,还需要mysql内部进行特殊处理。可空列被索引后,每条记录都需要一个额外的字节,还能导致MYisam 中固定大小的索引变成可变大小的索引。

—— 出自《高性能mysql第二版》

不使用NULL的原因

  • (1)所有使用NULL值的情况,都可以通过一个有意义的值的表示,这样有利于代码的可读性和可维护性,并能从约束上增强业务数据的规范性。

  • (2)NULL值到非NULL的更新无法做到原地更新,更容易发生索引分裂,从而影响性能。

注意:但把NULL列改为NOT NULL带来的性能提示很小,除非确定它带来了问题,否则不要把它当成优先的优化措施,最重要的是使用的列的类型的适当性。

  • (3)NULL值在timestamp类型下容易出问题,特别是没有启用参数explicit_defaults_for_timestamp

  • (4)NOT IN、!= 等负向条件查询在有 NULL 值的情况下返回永远为空结果,查询容易出错。

create table table_2 (`id` INT (11) NOT NULL,user_name varchar(20) NOT NULL)create table table_3 (`id` INT (11) NOT NULL,user_name varchar(20))insert into table_2 values (4,"zhaoliu_2_1"),(2,"lisi_2_1"),(3,"wangmazi_2_1"),(1,"zhangsan_2"),(2,"lisi_2_2"),(4,"zhaoliu_2_2"),(3,"wangmazi_2_2")insert into table_3 values (1,"zhaoliu_2_1"),(2, null)-- 
1、NOT IN子查询在有NULL值的情况下返回永远为空结果
2、单列索引不存null值,复合索引不存全为null的值,如果列允许为null,可能会得到“不符合预期”的结果集-- 如果name允许为null,索引不存储null值,结果集中不会包含这些记录。所以,请使用not null约束以及默认值。
3、如果在两个字段进行拼接:比如题号+分数,首先要各字段进行非null判断,否则只要任意一个字段为空都会造成拼接的结果为null。
4、如果有 Null column 存在的情况下,count(Null column)需要格外注意,null 值不会参与统计。
5、注意 Null 字段的判断方式, = null 将会得到错误的结果。
  • (5)Null 列需要更多的存储空间:需要一个额外字节作为判断是否为 NULL 的标志位。

alter table table_3 add index idx_user_name (user_name);alter table table_2 add index idx_user_name (user_name);explain select * from table_2 where user_name='zhaoliu_2_1';explain select * from table_3 where user_name='zhaoliu_2_1';

MySQL 不用 Null 的理由

可以看到同样的 varchar(20) 长度,table_2 要比 table_3 索引长度大,这是因为:

两张表的字符集不一样,且字段一个为 NULL 一个非 NULL。

MySQL 不用 Null 的理由

key_len 的计算规则和三个因素有关:数据类型、字符编码、是否为 NULL

key_len 62 == 20*3(utf8 3字节) + 2 (存储 varchar 变长字符长度 2字节,定长字段无需额外的字节)

key_len 83 == 20*4(utf8mb4 4字节) + 1 (是否为 Null 的标识) + 2 (存储 varchar 变长字符长度 2字节,定长字段无需额外的字节)

所以说索引字段最好不要为NULL,因为NULL会使索引、索引统计和值更加复杂,并且需要额外一个字节的存储空间。基于以上这些理由和原因,我想咱们不用 Null 的理由应该是够了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/134626.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python 转义字符(含用法)

    Python 转义字符(含用法)文章目录在 Python 字符串 一节中我们曾提到过转义字符 就是那些以反斜杠 开头的字符 ASCII 编码为每个字符都分配了唯一的编号 称为编码值 在 Python 中 一个 ASCII 字符除了可以用它的实体 也就是真正的字符 表示 还可以用它的编码值表示 这种使用编码值来间接地表示字符的方式称为转义字符 EscapeCharac 转义字符以 0 或者 x 开头 以 0 开头表示后跟八进制形式的编码值 以 x 开头表示后跟十六进制形式的编码值 Python 中的转义字符只能使用八进制或者十六

    2026年1月24日
    1
  • integer转换为string_go 字符串转int

    integer转换为string_go 字符串转intstr:=“123”//string转inti,err:=strconv.Atoi(str)iferr==nil{fmt.Printf(“i:%v\n”,i)}//string转int64i64,err:=strconv.ParseInt(str,10,64)iferr==nil{fmt.Printf(“i64:%v\n”,i64)…

    2026年2月1日
    7
  • 腾讯课堂视频下载_电脑腾讯会议不支持虚拟背景

    腾讯课堂视频下载_电脑腾讯会议不支持虚拟背景如果想把腾讯课堂里的视频下载到本地,这里提供一个方法。原理就是通过提取网页中的视频链接,进行下载。提取网页中的视频链接方法有很多。这里介绍通过浏览器插件的方式。1.我是在firefox附加组件里搜索“视频下载”找到的一款插件。flashvideodownloader,安装即可2.打开腾讯课堂网页版,播放想要下载的视频。浏览器会缓存你播放的视频,一般是5分钟一个。3.打开浏览器插件,它就会显示…

    2025年8月15日
    6
  • Linux最著名的文本编辑器,最优秀的5个Linux文本编辑器

    Linux最著名的文本编辑器,最优秀的5个Linux文本编辑器Vi/VimEditorVim以绝对优势获胜在大家的意料之中。如果你不熟悉最好的5个Linux文本编辑器中的任何一个,阅读本文剩下的部分对那些编辑器多点了解。1.VimEditor最新稳定版本:Vim7.2用C和Vimscript编写操作系统:跨平台(Unix,LinuxandWindows)阅读我们正在连载的Vi/Vim技巧和诀窍系列文章,掌握一些很棒的Vim绝…

    2022年7月26日
    18
  • 澳男星“雷神”发布健身App 好友与妻子齐助阵

    澳男星“雷神”发布健身App 好友与妻子齐助阵

    2021年6月29日
    150
  • OSPF路由协议_ospf协议是一种什么路由协议

    OSPF路由协议_ospf协议是一种什么路由协议OSPF:开放式最短路径优先协议无类别链路状态路由协议,组播更新224.0.0.5/6;跨层封装到三层,协议号89;基于拓扑工作,故更新量大—–需要结构化部署–区域划分、地址规划触发更新、每30min周期更新OSPF的数据包:Hello包DBD–数据库描述包LSR–链路状态请求LSU–链路状态更新携带各种LSALSack–链路状态确认状态机—-OSP…

    2025年6月25日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号