• 售前

  • 售后

热门帖子
入门百科

mysql 字段定义不要用null的缘故原由分析

[复制链接]
风来时狂放 显示全部楼层 发表于 2021-8-14 14:16:02 |阅读模式 打印 上一主题 下一主题
一 NULL 为什么这么常常用

(1) java的null
null是一个让人头疼的题目,好比java中的NullPointerException。为了避免猝不及防的空指针,需要警惕翼翼地各种if判定,贫苦又痴肥.
为此有很多的开源包都有诸多处理
common lang3的StringUtils.isBlank(); CollectionUtils.isEmpty();
guava的Optional
乃至java8也引入了Optional来避免这一题目(和guava的大同小异,用法稍有一点点变化)
(2) mysql的null为什么横行滥用
(a) 创建不规范 null是创建数据表时候默认的,一些mysql客户端的自动天生表语句里面大概也没有not null的指定。
(b) 错误熟悉 会有人以为not null需要更多的空间
(c) 图省事 null在开发中不消判定插入数据,写sql更方便
二 官方文档

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第二版》
云云看来,不指定not null并没有性能上的上风。
三 mysql不消null的理由

(1)所有利用NULL值的环境,都可以通过一个故意义的值的表现,如许有利于代码的可读性和可维护性,并能从束缚上加强业务数据的规范性。
(2)NULL值到非NULL的更新无法做到原地更新,更容易发生索引分裂,从而影响性能。(null -> not null性能提升很小,除非确定它带来了题目,否则不要当成优先的优化步调)
(3)NULL值在timestamp范例下容易出题目,特殊是没有启用参数explicit_defaults_for_timestamp
(4)NOT IN、!= 等负向条件查询在有 NULL 值的环境下返回永久为空结果,查询容易堕落
四 null引发的bad case

数据初始化:
  1. create table table1 (
  2.     `id` INT (11) NOT NULL,
  3.     `name` varchar(20) NOT NULL
  4. )
  5. create table table2 (
  6.     `id` INT (11) NOT NULL,
  7.     `name`  varchar(20)
  8. )
  9. insert into table1 values (4,"zhaoyun"),(2,"zhangfei"),(3,"liubei")
  10. insert into table2 values (1,"zhaoyun"),(2, null)
复制代码
(1)NOT IN子查询在有NULL值的环境下返回永久为空结果,查询容易堕落
select name from table1 where name not in (select name from table2 where id!=1)
  1. +-------------+
  2. |      name   |
  3. |-------------|
  4. +-------------+
复制代码
(2) 列值允许为空,索引不存储null值,结果集中不会包罗这些记录。
select * from table2 where name != 'zhaoyun'
  1. +------+-------------+
  2. |   id |      name   |
  3. |------+-------------|
  4. |      |             |
  5. +------+-------------+
复制代码
select * from table2 where name != 'zhaoyun1'
  1. +------+-------------+
  2. |   id |      name   |
  3. |------+-------------|
  4. |   1  |  zhaoyun    |
  5. +------+-------------+
复制代码
(3) 利用concat拼接时,起首要对各个字段进行非null判定,否则只要任何一个字段为空都会造成拼接的结果为null
select concat("1", null) from dual;
  1. +--------------------+
  2. |   concat("1", null)|
  3. |--------------------|
  4. |               NULL |
  5. +--------------------+
复制代码
(4) 当盘算count时候null column不管帐入统计
select count(name) from table2;
  1. +--------------------+
  2. |   count(user_name) |
  3. |--------------------|
  4. |                  1 |
  5. +--------------------+
复制代码
五 索引长度对比
  1. alter table table1 add index idx_name (name);
  2. alter table table2 add index idx_name (name);
  3. explain select * from table1 where name='zhaoyun';
  4. explain select * from table2 where name='zhaoyun';
复制代码
table1的key_len = 82
table2的key_len = 83
key_len 的盘算规则和三个因素有关:数据范例、字符编码、是否为 NULL
key_len 82 = 20 * 4(utf8mb4 - 4字节, utf8 - 3字节) + 2(存储varchar变长字符长度为2字节,定长字段无需额外的字节)
key_len 83 = 20 * 4(utf8mb4 - 4字节, utf8 - 3字节) + 2(存储varchar变长字符长度为2字节,定长字段无需额外的字节) + 1(是否为null的标志)
以是说索引字段最好不要为NULL,由于NULL会使索引、索引统计和值更加复杂,而且需要额外一个字节的存储空间。
到此这篇关于mysql 字段定义不要用null的分析的文章就介绍到这了,更多相干mysql 字段定义null内容请搜索草根技术分享以前的文章或继承浏览下面的相干文章盼望各人以后多多支持草根技术分享!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作