首页 > 数据库 >MySQL 中NULL和空值的区别

MySQL 中NULL和空值的区别

时间:2022-10-12 15:36:15浏览次数:51  
标签:two 空值 索引 MySQL test NULL tb


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值还是空值(''),根据实际业务来进行区分。个人建议在实际开发中如果没有特殊的业务场景,可以直接使用空值。

标签:two,空值,索引,MySQL,test,NULL,tb
From: https://blog.51cto.com/u_15826214/5750923

相关文章

  • mysql 插入Timestamp 少8个小时
    转:mysql插入timeStamp类型数据时间相差8小时的解决办法 mysql插入时间少八个小时 MySQL插入时间差八小时问题的解决方法如果时间和你本地当前时间一致说明mysql的时......
  • Mysql中的MVCC
     Mysql到底是怎么实现MVCC的?这个问题无数人都在问,但google中并无答案,本文尝试从Mysql源码中寻找答案。 在Mysql中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都......
  • Mysql主主同步配置方法
    环境服务器a:172.16.0.123服务器b:172.16.0.132Mysql版本:5.6.22SystemOS:CentOSrelease6.3创建同步用户服务器a和b分别建立一个同步用户:mysql>grantreplications......
  • MySQL存储IP地址的方法
    IP转数字函数inet_aton()mysql>selectinet_aton('192.168.1.1');+--------------------------+|inet_aton('192.168.1.1')|+--------------------------+|3232......
  • MySQL的语句执行顺序
    MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FROM操作,最后执行的是LIMIT操作。其中每一个操作都会产生一张虚拟的表,这个虚拟的表作为一个处理的输入,只是这些虚......
  • 关于mysql archive存储引擎
    政府还有一个让数据库专家摊上更多事情的职能,就是安全控制和数据审计。那些管理着海量数据仓库的企业官员常常得回答诸如“何人何时修改了什么”或者“何人何时查看了什么”......
  • mysql给表的字段加索引
    1、添加普通索引ALTERTABLE`table_name`ADDINDEXindex_name(`column`)2、添加主键索引ALTERTABLE`table_name`ADDPRIMARYKEY(`column`)3、添加唯一索引(UNIQ......
  • MySQL5.7 添加用户、删除用户与授权
    mysql-uroot-prootMySQL5.7mysql.user表没有password字段改authentication_string;一.创建用户:命令:CREATEUSER'username'@'host'IDENTIFIEDBY'password';例子:C......
  • MYSQL explain详解
    xplain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。虽然这篇文章我写的很长,但看起来真的不会困啊,真的都是干货啊!!!!......
  • mysql事务处理用法与实例详解
    MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关1.MyISAM:不支持事务,用于只读程序提高性能2.InnoDB:支持ACID事务、行级锁、并发3.BerkeleyDB:支持事务  一......