【MySQL】探究之null与not null
相信很多用了mysql很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问:
- 我字段类型是not null,为什么我可以插入空值
- 为毛not null的效率比null高
- 判断字段不为空的时候,到底要 select * from table where column <> '' 还是要用 select * from table where column is not null 呢。
带着上面几个疑问,我们来深入研究一下null 和 not null 到底有什么不一样。 首先,我们要搞清楚“空值” 和 “NULL” 的概念: 1. 空值是不占用空间的 2. mysql中的NULL其实是占用空间的,下面是来自于MYSQL官方的解释
“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”
打个比方来说,你有一个杯子,空值代表杯子是真空的,NULL代表杯子中装满了空气,虽然杯子看起来都是空的,但是区别是很大的。
搞清楚“空值”和“NULL”的概念之后,问题基本就明了了,我们搞个例子测试一下:
CREATE TABLE `test` (
`col1` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`col2` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
) ENGINE = MYISAM ;
插入测试
mysql> insert into test values(null,1);
ERROR 1048 (23000): Column 'col1' cannot be null mysql> insert into test values('',null);
Query OK, 1 row affected (0.00 sec) mysql> insert into test values('',1);
Query OK, 1 row affected (0.00 sec) mysql> insert into test values('NULL',1);
Query OK, 1 row affected (0.00 sec) mysql> select * from test;
+------+------+
| col1 | col2 |
+------+------+
| | NULL |
| | 1 |
| NULL | 1 |
+------+------+
3 rows in set (0.00 sec)
可见,NOT NULL 的字段是不能插入NULL的,只能插入“空值”,上面的问题1也就有答案了。读者需要注意的是,最后插入的NULL并非NULL,而是字符串"NULL"。并且对于InnoDB引擎的表具有相同的测试效果。
对于问题2,上面我们已经说过了,NULL 其实并不是空值,而是要占用空间,所以mysql在进行比较的时候,NULL 会参与字段比较,所以对效率有一部分影响。 而且B树索引(MyISAM 表)时不会存储NULL值的,所以如果索引的字段可以为NULL,索引的效率会下降很多。 值得注意的是:尽量避免NULL
- 很多表都包含可为NULL的列,即使应用程序并不需要保存NULL也是如此,这是因为可为NULL是列的默认属性(TIMESTAMP除外),然而通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。
- 如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引统计和值比较更加复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊的处理。当可为NULL的字段被索引时,每个索引记录需要一个额外的字节,在MyASIM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。
- 通常把可为NULL的列改为NOT NULL 带来的性能提升比较小,所以(调忧时)没有必要首先在现有schema中查找并修改这种情况,除非确定这会导致问题。但是,如果计划在列上建索引,就应该尽量避免设计为NULL的列。当然也有一些例外,例如值得一提的是,InnoDB使用单独的位(Bit)存储NULL值,所以对于稀疏数据(很多值为NULL,只有少数行是非NULL)有很好的空间效率。但这一点不适用于MyISAM。
---引用自《高性能MySQL-第三版》第四章 Schema与数据类型优化
解决最后一个疑问 现在根据需求,我要统计test表中col1不为空的所有数据,我是该用“<> ''” 还是 “IS NOT NULL” 呢,让我们来看一下结果的区别。
mysql> SELECT * FROM `test` WHERE col1 IS NOT NULL;
+------+------+
| col1 | col2 |
+------+------+
| NULL | 1 |
| | 1 |
| | NULL |
+------+------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM `test` WHERE col1 <> '';
+------+------+
| col1 | col2 |
+------+------+
| NULL | 1 |
+------+------+
1 row in set (0.00 sec)
可以看到,结果迥然不同,所以我们一定要根据业务需求,搞清楚到底是要用那种搜索条件。
【MySQL】探究之null与not null的更多相关文章
- mysql探究之null与not null
相信很多用了mysql很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问: 1.我字段类型是not null,为什么我可以插入空值 2.为毛not null的效率比null高 3.判断字段 ...
- MySQL中order by中关于NULL值的排序问题
MySQL中order by 排序遇到NULL值的问题 MySQL数据库,在order by排序的时候,如果存在NULL值,那么NULL是最小的,ASC正序排序的话,NULL值是在最前面的. 如果我们 ...
- Mysql报错java.sql.SQLException:null,message from server:"Host '27,45,38,132' is not allowed to connect
Mysql报错java.sql.SQLException:null,message from server:"Host '27,45,38,132' is not allowed to co ...
- MySQL null与not null和null与空值''的区别
参考连接:https://segmentfault.com/a/1190000009540449 相信很多用了MySQL很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问: 我字段类型是n ...
- MySQL学习笔记:少用Null
在实际编程中,Null容易引起很多问题,例如在Java里NullPointerException猝不及防的空指针异常,因此需要过多的if判断,甚是麻烦. 在MySQL数据库中也要少用Null,尽量保持 ...
- 转!!mysql 字段 is not null 和 字段 !=null
今天在查询数据时,查到包含一条某个时间startTime(该字段默认为null ) 为null的记录,想把它过滤,加了 startTime != null 的条件,结果记录都没了,应该用条件 is ...
- mysql 查询出的数组为null怎么转换成0
mysql 查询出的数组为null怎么转换成0 IFNULL(b.dayPay,0) as yesterdayPay,
- 面试官问我,为什么老司机建议MySQL列属性尽量用 NOT NULL ?
本文阅读时间大约6分钟. 其实写这篇文章,也是来自一个知识星球读者的提问,他在二面的过程中被问到了,由于他简历中写道有 MySQL 调优经验,但这个问题没有回答好,二面被刷了. 其实我们刚学习 C 语 ...
- mysql 设置字段是否可以为null
//不允许为null alter table table1 change id id ) not null; //允许为null alter table table1 change id id ) n ...
随机推荐
- Java Script 练习题
题目1:输入整数a和b,若a2+b2大于100,则输出a2+b2百位以上数字,否则输出两数之和 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...
- RHCE 系列(一):如何设置和测试静态网络路由
RHCE(Red Hat Certified Engineer,红帽认证工程师)是红帽公司的一个认证,红帽向企业社区贡献开源操作系统和软件,同时它还给公司提供训练.支持和咨询服务. 这个 RHCE 是 ...
- Linux 环境变量配置
linux 环境,用户通过shell 操作时,系统会为用户初使化环境变量, 比如系统公共资源路径: path , include , bin 等目录. shell 模式下,执行 export , 查看 ...
- C语言基础--for循环
for循环格式: for (初始化表达式;条件表达式;循环后增量表达式) { 语句; ... } 条件表达式: 和while, dowhile一样, 只有条件满足才会执行循环体 初始化表达式: 在整个 ...
- Learning with Trees
We are now going to consider a rather different approach to machine learning, starting with one of t ...
- 团队开发——冲刺1.e
冲刺阶段一(第五天) 冲刺阶段一(第五天) 1.昨天做了什么?优化界面细节. 查看C#资料,再解决自己电脑的问题. 2.今天准备做什么? 为解决自己电脑的问题,查找关于C#的资料,后期做准备.
- c#中各类日期的计算方法,收藏
DateTime startWeek = dt.AddDays(1 - Convert.ToInt32(dt.DayOfWeek.ToString("d"))); //本周周一D ...
- Opencv 2.4.10 +VS2010 项目配置记录
http://blog.csdn.net/scottly1/article/details/40978625?utm_source=tuicool 因为工作需要,小小的研究一下Opencv的图像处理, ...
- BZOJ 1500 Splay 全操作
好久没写splay了,写一发(写了一节课,调了一节课) #include <iostream> #include <cstring> #include <cstdio&g ...
- JS运动基础(二) 摩擦运动、缓冲运动
摩擦运动: 逐渐变慢,最后停止 缓冲运动: 与摩擦力的区别:可以精确的停到指定目标点距离越远速度越大速度由距离决定速度=(目标值-当前值)/缩放系数Bug:速度取整值取整: iSpeed = iSpe ...