MySQL中空值与NULL的区别

学习过关系型数据库的伙伴都知道,NULL是指不确定的值,在数据库中绝对是噩梦的存在;而空值,一般对字符串类型而言,指没有任何值的字符串类型。MySQL中的NULL值和空值区别:NULL值是未知的,占用空间,并且不走索引。相信很多用MySQL很久的人,对这两个字段属性的概念还不是很清楚:

1、我字段类型是not null,为什么我可以插入空值?

2、为什么not null的效率比null高?

3、判断字段不为空的时候,到底要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 = INNODB;

插入数据:

mysql> INSERT INTO `test` VALUES (NULL,1);

ERROR 1048 (23000): Column 'col1' cannot be null

MySQL发生错误,再来一条:

mysql> INSERT INTO `test` VALUES ('NULL',1);

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO `test` VALUES ('',1);

Query OK, 1 row affected (0.01 sec)

成功插入。

可见,NOT NULL的字段是不能插入NULL的,只能插入空值或有值,上面的问题1也就有答案了。另外,我这里是'NULL'相当于一个字符串了,不是NULL值,比如IS NULL是查不出来的。

mysql> select * from test where col1 is null;

Empty set (0.00 sec)

而等于’NULL’可以查询:

mysql> select * from test where col1='null';

+------+------+

| col1 | col2 |

+------+------+

| NULL | 1    |

+------+------+

1 row in set (0.00 sec)

对于问题2,上面我们已经说过了,NULL其实并不是空值,而是要占用空间,所以MySQL在进行比较的时候,NULL会参与字段比较,所以对效率有一部分影响。

而且对表索引时不会存储NULL值的,所以如果索引的字段可以为NULL,索引的效率会下降很多。

我们再向test的表中插入几条数据:

mysql> INSERT INTO `test` VALUES ('', NULL);

Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `test` VALUES ('1', '2');

Query OK, 1 row affected (0.00 sec)

现在表中数据:

现在根据需求,我要统计test表中col1不为空的所有数据,我是该用“<> ”” 还是 “IS NOT NULL” 呢,让我们来看一下结果的区别。

mysql> select * from test where col1 is not null;

Empty set (0.00 sec)

mysql> select * from test where col2 is null;

+------+------+

| col1 | col2 |

+------+------+

|      | NULL |

+------+------+

1 row in set (0.00 sec)

mysql> select * from test where col1 <> '';

+------+------+

| col1 | col2 |

+------+------+

| NULL | 1    |

| 1    | 2    |

+------+------+

2 rows in set (0.00 sec)

可以看到,结果迥然不同,所以我们一定要根据业务需求,搞清楚到底是要用那种搜索条件。

MySQL数据库是一个基于结构化数据的开源数据库,SQL语句是MySQL数据库中核心语言。不过在MySQL数据库中执行SQL语句,需要小心两个陷阱。

陷阱一:空值不一定为空

空值是一个比较特殊的字段。在MySQL数据库中,在不同的情形下,空值往往代表不同的含义。这是MySQL数据库的一种特性。如在普通的字段中(字符型的数据),空值就是表示空值。但是如果将一个空值的数据插入到TimesTamp类型的字段中,空值就不一定为空。此时为出现什么情况呢?

我先创建了一个表。在这个表中有两个字段:User_id(其数据类型是int)、Date(其数据类型是TimesTamp)。现在往这个表中插入一条记录,其中往Date字段中插入的是一个NULL空值。可是当我们查询时,其结果显示的却是插入记录的当前时间。这是怎么一回事呢?其实这就是在MySQL数据库中执行SQL语句时经常会遇到的一个陷阱:空值不一定为空。在操作时,明明插入的是一个空值的数据,但是最后查询得到的却不是一个空值。

在MySQL数据库中,NULL对于一些特殊类型的列来说,其代表了一种特殊的含义,而不仅仅是一个空值。对于这些特殊类型的列,主要是要记住两个。一个就是笔者上面举的TimesTamp数据类型。如果往这个数据类型的列中插入Null值,则其代表的就是系统的当前时间。另外一个是具有auto_increment属性的列。如果往这属性的列中插入Null值的话,则系统会插入一个正整数序列。而如果在其他数据类型中,如字符型数据的列中插入Null的数据,则其插入的就是一个空值。

陷阱二:空值不一定等于空字符

在MySQL中,空值(Null)与空字符(’’)相同吗?答案是否定的。

在同一个数据库表中,同时插入一个Null值的数据和一个’’空字符的数据,然后利用Select语句进行查询。显然其显示的结果是不相同的。从这个结果中就可以看出,空值不等于空字符。这就是在MySQL中执行SQL语句遇到的第二个陷阱。在实际工作中,空值数据与空字符往往表示不同的含义。数据库管理员可以根据实际的需要来进行选择。如对于电话号码等字段,可以默认设置为空值(表示根本不知道对方的电话号码)或者设置为空字符(表示后来取消了这个号码)等等。由于他们在数据库中会有不同的表现形式,所以数据库管理员需要区别对待。笔者更加喜欢使用空值,而不是空字符。这主要是因为针对空值这个数据类型有几个比较特殊的运算字符。如果某个字段是空字符,数据库中是利用字段名称来代替。相反,如果插入的是空值,则直接显示的是NULL。这跟其他数据库的显示方式也是不同的。

IS NULL和IS NOT NULL关键字。如果要判断某个字段是否含用空值的数据,需要使用特殊的关键字。其中前者表示这个字段为空,后者表示这个字段为非空。在Select语句的查询条件中这两个关键字非常的有用。如需要查询所有电话号码为空的用户(需要他们补充电话号码信息),就可以在查询条件中加入is not null关键字。判断NULL用is null或者is not null,SQL语句里可以用ifnull函数来处理。判断空字符串‘’,要用=”或者<>”,SQL语句里可以用if(col,col,0)处理,即:当col为true时(非null,及非”)显示,否则打印0。

一般情况下,除了count(0),count(*)之外,聚合函数都会忽略NULL值,而统计非NULL值。另外空表也会产生结果为NULL的聚合值。当聚合列值都是NULL值时,由于聚合函数忽略NULL值,因此,当计算聚合函数(max,min,avg和sum)的聚合值时,由于无值可以聚合,数据库引擎不能确定这些聚合函数的返回值,因此,数据库引擎返回NULL值。

mysql> create table temp(id int);

Query OK, 0 rows affected (0.06 sec)

mysql> insert into temp values(null);

Query OK, 1 row affected (0.01 sec)

mysql> select count(0),count(id),max(id),min(id),avg(id),sum(id) from temp;

+----------+-----------+---------+---------+---------+---------+

| count(0) | count(id) | max(id) | min(id) | avg(id) | sum(id) |

+----------+-----------+---------+---------+---------+---------+

|        1 |         0 |    NULL |    NULL |    NULL |    NULL |

+----------+-----------+---------+---------+---------+---------+

1 row in set (0.00 sec)

聚合函数(max,min,sum,avg和count)忽略null值,但不代表聚合函数不返回null值:如果数据表为空表,或聚合列值都是null,那么max,min,sum,avg聚合函数返回null值,而count 聚合函数返回0。聚合函数的共性:Null values are ignored。

不再迷惑:当不返回任何值时,数据库引擎不确定返回值,就把无值转换为NULL值。


转自:http://www.ywnds.com/?p=10295

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 什么是数据库? 数据库是存储数据的集合的单独的应用程序。每个数据库具有一个或多个不同的API,用于创建,访问,管理...
    chen_000阅读 4,032评论 0 19
  • MySQL 数据库常用命令 1、MySQL常用命令 create database name; 创建数据库 use...
    55lover阅读 4,780评论 1 57
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 如果风大,那么赶紧关窗。
    狮子岩蜘蛛阅读 83评论 0 0
  • 自己最信奉的一句话莫过于:民以食为天。如果说什么事情可以让我坚持一生,那也莫过于是美食。吃只是个代表,其中还包含...
    木由游阅读 262评论 0 0