作为后台开发,在日常工作中如果要接触Mysql数据库,那么不可避免会遇到Mysql中的NULL和空值。那你知道它们有什么区别吗?

学不动了,也不想知道它们有什么区别。大兄弟,不行啊,要面试!

前些天我的好朋友小木去应聘工作,他面试完回来和我聊天回味了一道他的面试题。

面试官:你有用过MySQL吗?

小木:有!

面试官:那你能大概说一下Mysql中 NULL值和空值的区别吗?

小木:(思考…)NULL和空值都用过,你要我说它两有啥区别,这个我还真没仔细想过,反正实际开发中会用!

听了小木的这个回答。

我说:你这样回答肯定是不妥的,这个问题你是必挂了。

小木说: NULL翻译过来不就是空吗?我是真的没有仔细想过,这个还是挺迷惑人的。

为了其他的伙伴在遇到这个问题的时候不要像我的好友小木一样在此处跌倒,错过心仪的公司,下面简单整理聊聊这两者的一些区别和使用。

02 NULL和空值

NULL也就是在字段中存储NULL值,空值也就是字段中存储空字符(’’)。

1、占用空间区别

mysql> select length(NULL), length(''), length('1');

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

| length(NULL) | length('') | length('1') |

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

| NULL | 0 | 1 |

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

1 row in set

小总结:从上面看出空值(’’)的长度是0,是不占用空间的;而的NULL长度是NULL,其实它是占用空间的,看下面说明。

NULL columns require additional space in the row to record whether their values are NULL.

NULL列需要行中的额外空间来记录它们的值是否为NULL。

通俗的讲:空值就像是一个真空转态杯子,什么都没有,而NULL值就是一个装满空气的杯子,虽然看起来都是一样的,但是有着本质的区别。

2、插入/查询方式区别

创建一个表,tb_test

CREATE TABLE `tb_test` (

`one` varchar(10) NOT NULL,

`two` varchar(255) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入进行验证:

-- 全部插入 NULL,失败

mysql> INSERT tb_test VALUES (NULL,NULL);

1048 - Column 'one' cannot be null

-- 全部插入 空值,成功

mysql> INSERT tb_test VALUES ('','');

Query OK, 1 row affected

模拟数据:

INSERT tb_test VALUES (1,NULL);

INSERT tb_test VALUES ('',2);

INSERT tb_test VALUES (3,3);

空值字段:

-- 使用 is null/is not null

mysql> SELECT * FROM tb_test where one is NULL;

Empty set

mysql> SELECT * FROM tb_test where one is not NULL;

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

| one | two |

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

| 1 | NULL |

| | 2 |

| 3 | 3 |

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

3 rows in set

-- 使用 = 、!=

mysql> SELECT * FROM tb_test where one = '';

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

| one | two |

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

| | 2 |

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

1 row in set

mysql> SELECT * FROM tb_test where one != '';

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

| one | two |

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

| 1 | NULL |

| 3 | 3 |

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

2 rows in set

NULL值字段:

-- 使用 is null/is not null

mysql> SELECT * FROM tb_test where two is not NULL;

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

| one | two |

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

| | 2 |

| 3 | 3 |

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

2 rows in set

mysql> SELECT * FROM tb_test where two is NULL;

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

| one | two |

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

| 1 | NULL |

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

1 row in set

-- 使用 = 、!=

mysql> SELECT * FROM tb_test where two = '';

Empty set

mysql> SELECT * FROM tb_test where two != '';

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

| one | two |

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

| | 2 |

| 3 | 3 |

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

2 rows in set

小总结:如果要单纯查NULL值列,则使用 is NULL去查,单纯去查空值(’’)列,则使用 =''。

建议查询方式:NULL值查询使用is null/is not null查询,而空值(’’)可以使用=或者!=、等算术运算符。

3、COUNT 和 IFNULL函数

使用COUNT函数:

mysql> SELECT count(one) FROM tb_test;

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

| count(one) |

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

| 3 |

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

1 row in set

mysql> SELECT count(two) FROM tb_test;

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

| count(two) |

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

| 2 |

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

1 row in set

mysql> SELECT count(*) FROM tb_test;

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

| count(*) |

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

| 3 |

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

1 row in set

使用IFNULL函数:

mysql> SELECT IFNULL(one,111111111) from tb_test WHERE one = '';

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

| IFNULL(one,111111111) |

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

| |

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

1 row in set

mysql> SELECT IFNULL(two,11111111) from tb_test where two is NULL;

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

| IFNULL(two,11111111) |

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

| 11111111 |

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

1 row in set

小总结:使用 COUNT(字段) 统计会过滤掉 NULL 值,但是不会过滤掉空值。

说明:IFNULL有两个参数。 如果第一个参数字段不是NULL,则返回第一个字段的值。 否则,IFNULL函数返回第二个参数的值(默认值)。

4、索引字段说明

看到网上有一些人说: MySql中如果某一列中含有NULL,那么包含该列的索引就无效了。

给one 和two 字段分别加上普通索引。之前有写过,在复习添加索引:Mysql索引整理总结

-- ALTER TABLE table_name ADD INDEX index_name(col_name);

ALTER TABLE tb_test ADD INDEX index_oat (one, two);

ALTER TABLE tb_test add INDEX index_two(two);

使用 show keys from 表名;或show indexes from 表名; ,查看这个表的所有索引信息。

一个普通索引,一个复合索引。

复合索引遵守“最左前缀”原则即在查询条件中使用了复合索引的第一个字段,索引才会被使用。因此,在复合索引中索引列的顺序至关重要。

可以看到,创建了两个索引,并且index_tow NULL 那一列是 YES。

使用EXPLAIN 来进行演示说明,EXPLAIN 的使用说明:Mysql中explain用法和结果字段的含义介绍

复合索引

普通索引

发现查询two字段 是可以正常使用索引的。我使用的MYSQL 5.7 ,InnoDB 引擎。也看了一些网上的资料,MySQL中NULL对索引的影响 这个文章中用例子验证,MySQL可以在含有null的列上使用索引。

备注:可能是其他条件下不行,看网上资料说使用空间索引会失效,具体我没有去验证,空间索引没有用到过。查询官网create-index-spatial,感兴趣的伙伴可以自行验证。

这里我想到一点,很多问题的答案都是在指定的条件和环境下才成立,多质疑,多验证。

小总结 :在有NULL值得字段上使用常用的索引,如普通索引、复合索引、全文索引等不会使索引失效。在官网查看在空间索引的情况下,说明了 索引列必须为NOT NULL。

03 总结提升

如果你可以从上面的几个方面和面试官进行一个沟通,即使回答的不是那么的完美,但总比 “这两个都用过,具体有啥区别就不知道了” 这样的回答能好那么一点点。

1、空值不占空间,NULL值占空间。当字段不为NULL时,也可以插入空值。

2、当使用 IS NOT NULL 或者 IS NULL 时,只能查出字段中没有不为NULL的或者为 NULL 的,不能查出空值。

3、判断NULL 用IS NULL 或者 is not null,SQL 语句函数中可以使用IFNULL()函数来进行处理,判断空字符用 =’‘或者<>’'来进行处理。

4、在进行count()统计某列的记录数的时候,如果采用的NULL值,会别系统自动忽略掉,但是空值是会进行统计到其中的。

5、MySql中如果某一列中含有NULL,那么包含该列的索引就无效了。这一句不是很准确。

6:实际到底是使用NULL值还是空值(’’),根据实际业务来进行区分。个人建议在实际开发中如果没有特殊的业务场景,可以直接使用空值。

以上就是我的对此问题的整理和思考。如果你对此话题有自己的思考和理解,也欢迎留言一起探讨!也欢迎私信我探讨交流哈,还有免费的学习资料赠送

mysql两个字段相减_MySQL 中NULL和空值的区别?相关推荐

  1. 不同数据库中两列字段相减(某列有空值)

    数据库中两个字段相减(某列有空值)处理方法: sql server中:select (isnull(字段1,0)-isnull(字段2,0)) as 结果 from 表 oracle中:select ...

  2. mysql两个时间相减的分钟数_mysql 俩个时间相减后取分钟

    CASE WHEN TIMESTAMPDIFF(MINUTE,o.createDate,o.chargingStartDate) != THEN 'APP解锁计费' ELSE '系统自动计费' END ...

  3. sql中两个表的某列相减_sql两个字段相减语句

    sql 两个字段相减语句本文章搜索了大量来自网络的关于sql 两个字段相减语句与函数代码,举例说明了两个字段相减做法. sql 两个字段相减语句 本文章搜索了大量来自网络的关于sql 两个字段相减语句 ...

  4. mysql 相同字段相减_mysql datetime 类型字段相减

    背景:今天测试一个mariadb中datatime类型的字段相减问题,直接用2个字段相减得到的数值并不是秒,很坑. 后面百度了一些方法,说是使用 DateDiff 函数,这个函数文档还说有3个参数,但 ...

  5. mysql 两个日期加减_mysql日期加减运算

    MySQL 日期类型 MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间       日期格式                 日期范围 -------- ...

  6. mysql 两个日期加减_mysql 日期加减

    mysql日期加减 一.MySQL 为日期增加一个时间间隔:date_add(). 1.  示例: set @dt = now(); select date_add(@dt, interval 1 d ...

  7. db2中null和空值的区别_MySQL数据库的表中 NULL 和 空值 到底有什么区别呢?

    作者:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! 知乎@极客小俊,官方首发原创文章 浅谈 NULL 和 空值的区别 NULL也就是在字段中 ...

  8. 数据库两时间类型相减_sql中两个时间类型相减得到的值

    今天有人把数据库两个time类型的字段查出来并做了减法,得到一个长形的数字.这个数字是什么? 首先在数据库里建立一张test表(mysql的数据库) CREATE TABLE `NewTable` ( ...

  9. mysql两个日期相减,得到相差的天数

    CURDATE()    获取当前服务器日期(YY-MM-DD) NOW()    获取当前服务器日期(YY-MM-DD hh:mm:ss) DATEDIFF(date1,date2)    两个日期 ...

最新文章

  1. android 跑分软件,跑分软件安兔兔公布了6月份Android手机性能榜TOP10
  2. Docker报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. ...
  3. 烟袋斜街-后海,印象已模糊
  4. linux执行.sql脚本 db2,DB2 如何执行sql脚本
  5. 基于FPGA的EEPROM读写(IIIC 接口协议)
  6. python是什么 自学-怎么自学python,大概要多久?
  7. rope 实用把一段区间的数字整体搬到序列中的一段的时候用
  8. Access Modify Change 三种时间戳详解
  9. 【转载】古诗背串了,可是会出大事的哟
  10. 【DevOps】在CentOS中安装Rancher2,并配置kubernetes集群
  11. win10易升_记一次因为升级 Win 10 到 2004 版导致的蓝屏问题的解决
  12. Vue 动态组件component
  13. 关于如何保持图片分辨率并压缩图片存储大小
  14. win10如何删除万能输入法
  15. 2023最新自助下单彩虹云商城系统源码+免授权无后
  16. CAD调试时抛出“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”异常的解决方法...
  17. Linux下dirname命令详解及C/C++代码实现
  18. BP神经网络隐层节点的个数设置方法
  19. Unity for Windows: II – Publishing Unity games to Windows Store
  20. 基础会计学原理重点整理(精编!!)

热门文章

  1. 设计模式示例_介体设计模式示例
  2. netflix测试能不能看_Netflix监管者测试–引入知事,准官员
  3. 为什么在生产中进行硒自动化测试对于您的下一个版本至关重要?
  4. jpa 实体映射视图_JPA教程:映射实体–第1部分
  5. Java:从Java 8开始受益于内联类属性
  6. jpa 测试_使用外星人进行测试:如何使用Arquillian测试JPA类型转换器
  7. 如何使用可外部化的接口在Java中自定义序列化
  8. 参数化测试 junit_参数化的JUnit测试
  9. 使用CUBA进行开发–是Spring的重大转变吗?
  10. apache camel_使用Java的Apache Camel入门