数据库允许空值(null),往往是悲剧的开始 (转)
数据库字段允许空值,会遇到一些问题,此处包含的一些知识点,和大家聊一聊。
数据准备:
create table user (
id int,
name varchar(20),
index(id)
)engine=innodb; insert into user values(1,'shenjian');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
说明:
id为索引,非唯一(non unique),允许空(null)。
知识点1(热身):负向查询不能命中索引,会导致全表扫描。
explain select * from user where id!=1;
索引字段id上的不等于查询,如上图所示:
(1)type=ALL,全表扫描;
(2)rows=3,全表只有3行;
知识点2(划重点):允许空值,不等于(!=)查询,可能导致不符合预期的结果。
insert into user(name) values('wangwu');
先构造一条id为NULL的数据,可以看到共有4条记录。
select * from user where id!=1;
再次执行不等于查询。
你猜结果集有几条记录(共4条,不等于排除1条)?
答错了!
结果集只有2条记录,空值记录记录并未出现在结果集里。
select * from user where id!=1 or id is null;
如果想到得到符合预期的结果集,必须加上一个or条件。
画外音:恶心不恶心,这个大坑你踩过没有?
知识点3(附加):某些or条件,又可能导致全表扫描,此时应该优化为union。
explain select * from user where id=1;
索引字段id上的等值查询,能命中索引,如上图所示:
(1)type=ref,走非唯一索引;
(2)rows=1,预估扫描1行;
explain select * from user where id is null;
索引字段id上的null查询,也能命中索引,如上图所示:
(1)type=ref,走非唯一索引;
(2)rows=1,预估扫描1行;
explain select * from user where id=1 or id is null;
如果放到一个SQL语句里用or查询,则会全表扫描,如上图所示:
(1)type=ALL,全表扫描;
(2)rows=4,全表只有4行;
explain select * from user where id=1
union
select * from user where id is null;
此时应该优化为union查询,又能够命中索引了,如上图所示:
(1)type=ref,走非唯一索引;
(2)rows=1,预估扫描1行;
画外音:第三行临时表的ALL,是两次结果集的合并。
总结
(1)负向比较(例如:!=)会引发全表扫描;
(2)如果允许空值,不等于(!=)的查询,不会将空值行(row)包含进来,此时的结果集往往是不符合预期的,此时往往要加上一个or条件,把空值(is null)结果包含进来;
(3)or可能会导致全表扫描,此时可以优化为union查询;
(4)建表时加上默认(default)值,这样能避免空值的坑;
(5)explain工具是一个好东西;
出处:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651962495&idx=1&sn=74e9e0dc9d03a872fd5bce5769f6c22a&chksm=bd2d09a38a5a80b50da3b67c03da8417426cbb201427557959fa91e9094a848a14e0db214370&scene=21#wechat_redirect
数据库允许空值(null),往往是悲剧的开始 (转)的更多相关文章
- 数据库允许空值(null),往往是悲剧的开始(1分钟系列)
数据库字段允许空值,会遇到一些问题,此处包含的一些知识点,和大家聊一聊. 数据准备: create table user ( id int, name varchar(20), index(id) ) ...
- 数据库允许空值(null),往往是悲剧的开始
原文: 58沈剑 架构师之路 https://mp.weixin.qq.com/s/XRSPITgWWK-2Ee-cSIqw1w 数据库字段允许空值,会遇到一些问题,此处包含的一些知识点,和大 ...
- SQL Serve数据库排序空值null始终前置的方法
[转:http://blog.knowsky.com/233986.htm] [sqlserver]: sqlserver 认为 null 最小. 升序排列:null 值默认排在最前. 要想排后面,则 ...
- sqlserver、oracle数据库排序空值null问题解决办法
转:https://www.cnblogs.com/pacer/archive/2010/03/02/1676371.html [sqlserver]: sqlserver 认为 null 最小. 升 ...
- SQL学习之空值(Null)检索
在创建表表,我们可以指定其中的列包不包含值,在一列不包含值时,我们可以称其包含空值null. 确定值是否为null,不能简单的检查是否=null.select语句有一个特殊的where子句,可用来检查 ...
- 浅谈MDX处理空值NULL及格式化结果
MDX查询结果中往往会含有"NULL"值,这是某维度下对应的的量值不存在导致的,为了让报表呈现更好的效果,在有些情况下,需要将"NULL"的切片值置换成0,这些 ...
- 数据库中的null问题
在数据库中有些列的值可以为null,这一篇,我们围绕数据库中的null来讲述. 1. null与 “”.0的区别 数据库中的null表示——不知道,“”——一个空字符串,0则是一个数值. 所以n ...
- MDX Cookbook 03 - MDX 查询中负数,零和空值 NULL 的格式化处理
FORMAT_STRING 属性在处理计算成员(通常是度量值成员)的时候会经常使用到,比如指定标准 Standard, 货币 Currency 或者 Percent 百分比格式.除此之外,还可以自定义 ...
- C#向Sql数据库插入空值的控制
string name = textBox1.Text; int age = Convert.ToInt32(textBox2.Text.Trim()); ? null : (int?)Convert ...
随机推荐
- 选择vim编辑器的7个理由
当我刚刚开始用 vi 文本编辑器的时候,我讨厌它!我认为这是有史以来设计上最痛苦和反人类的编辑器.但我还是决定我必须学会它,因为如果你使用的是 Unix,vi 无处不在并且是唯一一个保证你可以使用的编 ...
- 杨辉三角 x
杨辉三角是美丽的数学结晶,其结论往往多蕴含自然之美. ——以下内容均摘抄自题解. 例题: 洛谷P1762 偶数 正如这题所示,数据在n<=10^15的范围内则引导我们去寻找空间更节省,速率更高 ...
- docker-compose进行部署容器的时候,报错权限不足
刚刚用docker-compose部署elk的时候,没有起来,查看日志的时候,发现在数据卷挂载的时候,报错权限不足. 由于日志不在了,这里就直接贴出解决办法. 问题原因及解决办法 原因是CentOS7 ...
- Spring Boot教程(十八)构建RESTful API
首先,回顾并详细说明一下在快速入门中使用的@Controller.@RestController.@RequestMapping注解.如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建 ...
- D2. Equalizing by Division (hard version)
D2. Equalizing by Division (hard version) 涉及下标运算一定要注意下标是否越界!!! 思路,暴力判断以每个数字为到达态最小花费 #include<bits ...
- HBase调优案例(三)——Spark访问HBase慢
负载信息:RegionServer:3个 Region:5400多个 现象:在使用Spark对HBase进行scan操作时发现有些task执行比较慢 原因分析:查看Spark应用的executor日志 ...
- python之新式类与经典类
经典类与新式类 经典类:P 或 P()--深度查找,向上查父节点 新式类 :P(object)---广度查找,继承object,新式类的方法较多
- 读取hibernate.cfg.xml文件
new Configuration().configure().buildSessionFactory() new Configuration()默认是读取hibernate.properties 所 ...
- jdbcType="DATE"和jdbcType=" TIMESTAMP"的区别
原文: https://www.cnblogs.com/fswhq/p/jdbcType.html 当传入null值时,jdbcType 会防止null空指针异常报错 Mybatis 中jdbcTyp ...
- 分布式工作流任务调度系统Easy Scheduler正式开源
分布式工作流任务调度系统Easy Scheduler正式开源 1.背景 在多位技术小伙伴的努力下,经过近2年的研发迭代.内部业务剥离及重构,也经历一批种子用户试用一段时间后,EasyScheduler ...