MySQL 中NULL和空值的区别?

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,那么包含该列的索引就无效了。

onetwo字段分别加上普通索引、符合索引。之前有写过索引: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_two NULL那一列是YES。
使用EXPLAIN来进行演示说明,EXPLAIN的使用说明Mysql中explain用法和结果字段的含义介绍
复合索引
在这里插入图片描述
普通索引
在这里插入图片描述
发现查询two字段 是可以正常使用索引的。我使用的MYSQL 5.7 ,InnoDB 引擎。也看了一些网上的资料,MySQL中NULL对索引的影响 这个文章中用例子验证,MySQL可以在含有null的列上使用索引。

备注:可能是其他条件下不行,看网上资料说使用空间索引会失效,具体我没有去验证,空间索引没有用到过。查询官网create-index-spatial,感兴趣的伙伴可以自行验证。
在这里插入图片描述
这里我想到一点,很多问题的答案都是在指定的条件和环境下才成立,多质疑,多验证。

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

总结提升

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

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中 NULL和空值的区别

dev.mysql.com/doc/refman/…

作者:阿飞云
链接:https://juejin.im/post/5d1c32bf51882551253e483d
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

MySQL空值NULL是有区别的。空值是指已经被定义了的值,但在具体情况下没有实际的值填入。而NULL值表示该值不存在或未知,也即没有定义。当使用IS NOT NULL或者IS NULL进行判断时,只能查出字段没有不为NULL的或者为NULL的,不能查出空值。判断NULL可以使用IS NULL或者IS NOT NULL,判断空字符可以使用"="、"<"、">"等运算符。在进行COUNT()统计某列的记录数的时候,如果采用NULL值,会被系统自动忽略掉,但是空值会进行统计。在使用ORDER BY进行排序时,对于升序排序,NULL值会排在其他值之前;对于降序排序,NULL值会排在其他值之后。在SQLNULL值与任何其他值进行比较时都不会为真,即使是NULLNULL进行比较也是如此。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [深入理解mysql空值NULL值](https://blog.csdn.net/Ru_yin_hai/article/details/102782639)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [MySqlNULL值和空值](https://blog.csdn.net/qq_40371773/article/details/130245114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值