作一个积极的人html
编码、改bug、提高本身mysql
我有一个乐园,面向编程,春暖花开!面试
做为后台开发,在平常工做中若是要接触Mysql数据库,那么不可避免会遇到Mysql中的NULL和空值。那你知道它们有什么区别吗?sql
学不动了,也不想知道它们有什么区别。大兄弟,不行啊,要面试!数据库
前些天个人好朋友小木去应聘工做,他面试完回来和我聊天回味了一道他的面试题。编程
面试官:你有用过MySQL吗?函数
小木:有!ui
面试官:那你能大概说一下Mysql中 NULL值和空值的区别吗?编码
小木:(思考...)NULL和空值都用过,你要我说它两有啥区别,这个我还真没仔细想过,反正实际开发中会用!spa
听了小木的这个回答。
我说:你这样回答确定是不妥的,这个问题你是必挂了。
小木说: NULL翻译过来不就是空吗?我是真的没有仔细想过,这个仍是挺迷惑人的。
为了其余的伙伴在遇到这个问题的时候不要像个人好友小木同样在此处跌倒,错过心仪的公司,下面简单整理聊聊这二者的一些区别和使用。
NULL也就是在字段中存储NULL值,空值也就是字段中存储空字符('')。
一、占用空间区别
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值就是一个装满空气的杯子,虽然看起来都是同样的,可是有着本质的区别。
二、插入/查询方式区别
建立一个表,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查询,而空值('')可使用=或者!=、<、>等算术运算符。
三、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
函数返回第二个参数的值(默认值)。
四、索引字段说明
看到网上有一些人说: 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。
若是你能够从上面的几个方面和面试官进行一个沟通,即便回答的不是那么的完美,但总比 “这两个都用过,具体有啥区别就不知道了” 这样的回答能好那么一点点。
一、空值不占空间,NULL值占空间。当字段不为NULL时,也能够插入空值。
二、当使用 IS NOT NULL 或者 IS NULL 时,只能查出字段中没有不为NULL的或者为 NULL 的,不能查出空值。
三、判断NULL 用IS NULL 或者 is not null,SQL 语句函数中可使用IFNULL()函数来进行处理,判断空字符用 =''或者<>''来进行处理。
四、在进行count()统计某列的记录数的时候,若是采用的NULL值,会别系统自动忽略掉,可是空值是会进行统计到其中的。
五、MySql中若是某一列中含有NULL,那么包含该列的索引就无效了。这一句不是很准确。
6:实际究竟是使用NULL值仍是空值(''),根据实际业务来进行区分。我的建议在实际开发中若是没有特殊的业务场景,能够直接使用空值。
以上就是个人对此问题的整理和思考,但愿能够在面试中帮助到你。若是你对此话题有本身的思考和理解,也欢迎留言一块儿探讨!
谢谢你的阅读,若是您以为这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你天天开心愉快!
无论作什么,只要坚持下去就会看到不同!在路上,不卑不亢!
愿你我在人生的路上能都变成最好的本身,可以成为一个独挡一面的人
© 天天都在变得更好的阿飞云