`

(转)MySQL中NULL和空值的区别

 
阅读更多
MySQL中NULL和空值的区别

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

学习过关系型数据库的伙伴都知道,NULL是指不确定的值,在数据库中绝对是噩梦的存在;而空值,一般对字符串类型而言,指没有任何值的字符串类型,为字符类型的变量设置为空值:set @vs=”,空值跟无值不同。有人可能会问,无值是什么?无值,是指数据表中没有任何数据。无值和不确定值,单从字面意思上来看,两者之间的定义很清楚,一旦深究,这两者之间的关系,有时令人十分迷惑(confused)。

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;

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
1
2
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)

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 test1 where col1 is null;
Empty set (0.00 sec)
1
2
mysql> select * from test1 where col1 is null;
Empty set (0.00 sec)
而等于’NULL’可以查询:


mysql> select * from test1 where col1='null';
+------+------+
| col1 | col2 |
+------+------+
| NULL | 1    |
+------+------+
1 row in set (0.00 sec)

mysql> select * from test1 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)

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 test1 where col1 is null;
Empty set (0.00 sec)

mysql> select * from test1 where col2 is null;
+------+------+
| col1 | col2 |
+------+------+
|      | NULL |
+------+------+
1 row in set (0.00 sec)

mysql> select * from test1 where col1 is null;
Empty set (0.00 sec)

mysql> select * from test1 where col2 is null;
+------+------+
| col1 | col2 |
+------+------+
|      | NULL |
+------+------+
1 row in set (0.00 sec)

mysql> select * from test1 where col1 <> '';
+------+------+
| col1 | col2 |
+------+------+
| NULL | 1    |
| 1    | 2    |
+------+------+
2 rows in set (0.00 sec)

mysql> select * from test1 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)

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值。
分享到:
评论

相关推荐

    MySQL null与not null和null与空值的区别详解

    MySQL数据库在设计表结构时,`NULL` 和 `NOT NULL` 是两个重要的字段约束,它们在数据存储和查询中有着显著的区别。理解这些差异对于优化数据库性能和编写正确的SQL语句至关重要。 首先,我们需要明确“空值”和...

    区分MySQL中的空值(null)和空字符()

    日常开发中,一般都会涉及到数据库增删改查,那么不可避免会遇到Mysql中的NULL和空字符。 空字符(”)和空值(null)表面上看都是空,其实存在一些差异: 定义: 空值(NULL)的长度是NULL,不确定占用了多少存储...

    详解MySQL中的NULL值

    在MySQL数据库中,`NULL`值是一个特殊的存在,表示数据未知或者不存在。处理`NULL`值时,需要注意一些特定的规则和操作符。本篇文章将深入解析MySQL中的`NULL`值及其相关的查询方法。 首先,当尝试使用`= NULL`或`!...

    MySQL数据库:空值比较.pptx

    MySQL有一个特殊的等于运算符“”,当两个表达式彼此相等或都等于空值时,它的值为TRUE,其中有一个空值或都是非空值但不相等,这个条件就是FALSE。 【例】 查询Sell表中还未收货的订单情况。 SELECT * FROM Sell ...

    NOT NULL 和NULL

    如果既不指定NULL也不指定NOT NULL,列被认为指定了NULL 在 MySQL 中, 为一个 NOT NULL 字段设置 NULL 值 , 它并不会出错, MySQL 会自动将 NULL值转化为该字段的默认值, 那怕是你在表定义时没有...

    mysql 转换NULL数据方法(必看)

    使用mysql查询数据库,当执行left join时,有些关联的字段内容是NULL,因此获取记录集后,需要对NULL的数据进行转换操作。 本文将提供一种方法,可以在查询时直接执行转换处理。使获取到的记录集不需要再进行转换。 ...

    MySQL NULL 值处理实例详解

    我们已经知道MySQL使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。 为了处理这种情况,MySQL提供了三大运算符: IS NULL: 当列的值是NULL,...

    oracle和MySQL区别手册

    `NULL`和空字符串在MySQL中的处理方式有所不同,例如使用`IS NULL`进行判断时,两者的返回结果是不同的。 #### 基本语法使用 - **日期时间函数格式**: - **Oracle**: 默认的时间格式为`yyyy-MM-dd hh:mi:ss`。 -...

    详解mysql不等于null和等于null的写法

    在SQL语言中,`NULL`是一个特殊的值,它表示未知或者未定义。处理`NULL`值时,需要注意其与...在MySQL中,使用`IS NULL`和`IS NOT NULL`来处理`NULL`值,同时了解相关的函数和约束,能帮助我们更有效地管理和操作数据。

    datax抽取数据到hdfs的null值变成''(引号)的问题

    mysql的null值通过datax抽取到hdfs,会变成引号,这不是我们所需要的,所以需要修改一下datax的源码

    mysql转换到oracle数据库

    ### MySQL到Oracle数据库转换的关键知识点 #### 一、MySQL到Oracle数据库...通过以上详细步骤和技术要点,我们可以有效地将MySQL数据库中的数据及其相关的应用程序迁移至Oracle数据库,同时确保应用的兼容性和稳定性。

    如何将数据库中的NUll写入到数据库中去

    例如,整型和日期时间类型通常不允许NULL,除非明确声明为允许NULL的(如MySQL的NOT NULL DEFAULT NULL)。在创建表时,要确保允许NULL的列使用了正确的数据类型。 6. NULL vs. 空字符串: 值得注意的是,NULL和空...

    MySQL中可为空的字段设置为NULL还是NOT NULL

    在MySQL数据库中,字段的可为空性是一个重要的设计决策,主要涉及到`NULL`和`NOT NULL`两种约束。这两种约束不仅影响数据的存储方式,还直接影响到查询性能和数据的一致性。 首先,理解`NULL`和“空值”的概念至关...

    Mysql NULL导致的神坑

    本篇文章将深入探讨MySQL中`NULL`值与比较运算符之间的交互及其可能带来的问题。 1. **NULL与任何比较运算符的结果** 当我们尝试用比较运算符(如`&gt;`、`、`&gt;=`、`、`=`、`&lt;&gt;`或`!=`)来比较`NULL`值时,结果并不会...

    MySQL操作手册v1.0.pdf

    手册中首先提到了Linux平台下的MySQL安装方法,包括Ubuntu和CentOS两种主流Linux发行版的安装命令,并提到了配置文件目录的所在位置。接着,手册详细介绍了密码的修改过程,以及登录MySQL服务器的方法,强调了在...

    小心陷阱!MySQL中处理Null时需注意两点

    在MySQL数据库中,在不同的情形下,空值往往代表不同的含义。这是MySQL数据库的一种特性。如在普通的字段中(字符型的数据),空值就是表示空值。但是如果将一个空值的数据插入到TimesTamp类型的字段中,空值就不一定...

    MySQL SQL高级特性 字段约束-索引-视图-外键学习实践

    在本部分内容中,重点介绍了NULL和NOT NULL修饰符的使用和区别。在MySQL中,NULL意味着该字段可以没有值,即空值;而NOT NULL修饰的字段则必须在插入记录时给出值,不能为NULL。对于NOT NULL字段的效率之所以比NULL...

    MySQL 字段约束 mysql学习笔记

    今天我们来看一下 MySQL 的字段约束:NULL 和 NOT NULL 修饰符、DEFAULT 修饰符、AUTO_INCREMENT 修饰符。 NULL 和 NOT NULL 修饰符 NULL 和 NOT NULL 修饰符可以在每个字段后面添加,以指定该字段是否可以为空...

    MySQL非空约束(not null)案例讲解.doc

    MySQL 非空约束(NOT NULL)案例讲解 MySQL 非空约束(NOT NULL)是指字段的值不能为空,这种约束可以在创建表时或修改表时添加。非空约束的作用是确保字段的值不能为空,否则数据库系统就会报错。 创建表时设置...

Global site tag (gtag.js) - Google Analytics