mysql对null值如何理解(MySQL为Null会导致5个问题个个致命)
mysql对null值如何理解
MySQL为Null会导致5个问题个个致命目录
- 1.count 数据丢失
- 解决方案
- 2.distinct 数据丢失
- 3.select 数据丢失
- 解决方案
- 4.导致空指针异常
- 5.增加了查询难度
- 总结
正式开始之前,我们先来看下 mysql 服务器的配置和版本号信息,如下图所示:
“兵马未动粮草先行”,看完了相关的配置之后,我们先来创建一张测试表和一些测试数据。
|
-- 如果存在 person 表先删除 drop table if exists person; -- 创建 person 表,其中 username 字段可为空,并为其设置普通索引 create table person ( id int primary key auto_increment, name varchar (20), mobile varchar (13), index ( name ) ) engine= 'innodb' ; -- person 表添加测试数据 insert into person( name ,mobile) values ( 'java' , '13333333330' ), ( 'mysql' , '13333333331' ), ( 'redis' , '13333333332' ), ( 'kafka' , '13333333333' ), ( 'spring' , '13333333334' ), ( 'mybatis' , '13333333335' ), ( 'rabbitmq' , '13333333336' ), ( 'golang' , '13333333337' ), ( null , '13333333338' ), ( null , '13333333339' ); select * from person; |
构建的测试数据,如下图所示:
有了数据之后,我们就来看当列中存在 null
值时,究竟会导致哪些问题?
1.count 数据丢失
当某列存在 null
值时,再使用 co
unt
查询该列,就会出现数据“丢失”问题,如下 sql 所示:
|
select count (*), count ( name ) from person; |
查询执行结果如下:
从上述结果可以看出,当使用的是 count(name)
查询时,就丢失了两条值为 null
的数据丢失。
解决方案
如果某列存在 null
值时,就是用 count(*)
进行数据统计。
扩展知识:不要使用 count(常量)
阿里巴巴《java开发手册》强制规定:不要使用 count(列名) 或 count(常量) 来替代 count(),count() 是 sql92 定义的标准统计行数的语法,跟数据库无关,跟 null 和非 null 无关。
说明:count(*) 会统计值为 null 的行,而 count(列名) 不会统计此列为 null 值的行。
2.distinct 数据丢失
当使用 count(distinct col1, col2)
查询时,如果其中一列为 null
,那么即使另一列有不同的值,那么查询的结果也会将数据丢失,如下 sql 所示:
|
select count ( distinct name ,mobile) from person; |
查询执行结果如下:
数据库的原始数据如下:
从上述结果可以看出手机号一列的 10 条数据都是不同的,但查询的结果却为 8。
3.select 数据丢失
如果某列存在 null
值时,如果执行非等于查询(<>/!=)会导致为 null
值的结果丢失。比如以下这个数据:
我需要查询除 name 等于“java”以外的所有数据,预期返回的结果是 id 从 2 到 10 的数据,但当执行以下查询时:
|
select * from person where name <> 'java' order by id; -- 或 select * from person where name != 'java' order by id; |
查询结果均为以下内容:
可以看出为 null
的两条数据凭空消失了,这个结果并不符合我们的正常预期。
解决方案
要解决以上的问题,只需要在查询结果中拼加上为 null
值的结果即可,执行 sql 如下:
|
select * from person where name <> 'java' or isnull ( name ) order by id; |
最终的执行结果如下:
4.导致空指针异常
如果某列存在 null
值时,可能会导致 sum(column)
的返回结果为 null
而非 0,如果 sum
查询的结果为 null
就可以能会导致程序执行时空指针异常(npe),我们来演示一下这个问题。
首先,我们先构建一张表和一些测试数据:
|
-- 如果存在 goods 表先删除 drop table if exists goods; -- 创建 goods 表 create table goods ( id int primary key auto_increment, num int ) engine= 'innodb' ; -- goods 表添加测试数据 insert into goods(num) values (3),(6),(6),( null ); select * from goods; |
表中原始数据如下:
接下来我们使用 sum
查询,执行以下 sql:
|
select sum (num) from goods where id>4; |
查询执行结果如下:
当查询的结果为 null
而非 0 时,就可以能导致空指针异常。
解决空指针异常
可以使用以下方式来避免空指针异常:
|
select ifnull( sum (num), 0) from goods where id>4; |
查询执行结果如下:
5.增加了查询难度
当某列值中有 null
值时,在进行 null
值或者非 null
值的查询难度就增加了。
所谓的查询难度增加指的是当进行 null
值查询时,必须使用 null
值匹配的查询方法,比如 is null
或者 is not null
又或者是 ifnull(cloumn)
这样的表达式进行查询,而传统的 =、!=、<>...
等这些表达式就不能使用了,这就增加了查询的难度,尤其是对小白程序员来说,接下来我们来演示一下这些问题。
还是以 person
表为例,它的原始数据如下:
错误用法 1:
|
select * from person where name <> null ; |
执行结果为空,并没有查询到任何数据,如下图所示:
错误用法 2:
|
select * from person where name != null ; |
执行结果也为空,没有查询到任何数据,如下图所示:
正确用法 1:
|
select * from person where name is not null ; |
执行结果如下:
正确用法 2:
|
select * from person where ! isnull ( name ); |
执行结果如下:
推荐用法
阿里巴巴《java开发手册》推荐我们使用 isnull(cloumn)
来判断 null
值,原因是在 sql 语句中,如果在 null 前换行,影响可读性;而 isnull(column)
是一个整体,简洁易懂。从性能数据上分析 isnull(column)
执行效率也更快一些。
扩展知识:null 不会影响索引
细心的朋友可能发现了,我在创建 person
表的 name
字段时,为其创建了一个普通索引,如下图所示:
然后我们用 explain
来分析查询计划,看当 name
中有 null
值时是否会影响索引的选择。
explain
的执行结果如下图所示:
从上述结果可以看出,即使 name
中有 null
值也不会影响 mysql 使用索引进行查询。
总结
本文我们讲了当某列为 null
时可能会导致的 5 种问题:丢失查询结果、导致空指针异常和增加了查询的难度。因此在最后提倡大家在创建表的时候尽量设置 is not null
的约束,如果某列确实没有值,可以设置空值('')或 0 作为其默认值。
到此这篇关于mysql为null会导致5个问题(个个致命)的文章就介绍到这了,更多相关mysql为null导致问题内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
原文链接:https://blog.csdn.net/weixin_44742132/article/details/112057814
- mysql5.7.24rpm安装(MySQL系列-YUM及RPM包安装v5.7.34)
- mysqlsource命令作用(MySQL source命令的使用简介)
- docker安装mysql后无法连接(Docker 安装 MySQL 并实现远程连接教程)
- mysql安装时服务无法启动(MySQL 实例无法启动的问题分析及解决)
- mysql各种类型设置(MySQL sql_mode的使用详解)
- mysql删库操作记录(mysql常用sql与命令之从入门到删库跑路)
- mysql存储过程声明(MySQL存储过程的深入讲解in、out、inout)
- netcore连什么数据库好(.Net Core导入千万级数据至Mysql的步骤)
- mysql日志使用(MySQL 日志相关知识总结)
- mysql和utf8哪个好(为什么在MySQL中不建议使用UTF-8)
- mysql语句运行顺序(浅谈mysql执行过程以及顺序)
- 如何用wampserver打开自己写的php(WampServer下安装多个版本的PHP、mysql、apache图文教程)
- mysql 索引怎么实现(Mysql中索引和约束的示例语句)
- navicat连接mysql1045解决方法(Navicat 连接服务器端中的docker数据库的方法)
- mysql和navicat怎么用(如何用Navicat操作MySQL)
- mysql数据库如何删除重复记录(mysql数据库删除重复数据只保留一条方法实例)
- 苏志燮赵恩静结婚,韩国四大公共财产变三人,这么快就有替补了(苏志燮赵恩静结婚)
- 《内在美》后,一大波新韩剧来袭,李钟硕朴信惠宋慧乔玄彬回归(一大波新韩剧来袭)
- 给孩子选购保温杯,注意这4个步骤,比颜值更重要(给孩子选购保温杯)
- 保温好 容量大 颜值高 保温杯你给娃娃买对了吗(保温好容量大颜值高)
- 《道德经》 人生避开骄狂,才能免去祸患(道德经人生避开骄狂)
- 郭麒麟(郭麒麟)
热门推荐
- Python实现FTP弱口令扫描器的方法示例(Python实现FTP弱口令扫描器的方法示例)
- mysql完整整理(Mysql隔离性之Read View的用法说明)
- Visual Studio中 sln 和 suo 文件
- mariadb导入数据库命令(MySQL/MariaDB 如何实现数据透视表的示例代码)
- jsarray操作技巧(JS数组reduce你不得不知道的25个高级用法)
- 基于yii2框架的开源系统(Yii框架参数配置文件params用法实例分析)
- mysql数据表实例教程(mysql数据库入门第一步之创建表)
- 无法访问docker容器内的端口(docker端口映射及外部无法访问问题)
- webclient乱码
- mpp数据库的客户端工具(xampp默认mysql数据库root密码的修改)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9