简明现代魔法 -> 数据库技术 -> 数据库中的空值

数据库中的空值

2010-03-19

往往很多人都认为空值与空白或0值是一样的,至少我在今天以前是这么认为的,其实空值并不与空白和0值是一回事。

Null值表示数值未知。没有两个相等的空值,比较两个空值或空值和任意一个数比较返回的均是未知。

下面有以下从SQL 联机丛书中的关于空值的信息:

如下数据库截图所示:

空值显示为 (null),而左下角则是空白,空白不代表没有数据,它是插入了空格数据而产生的。

又比如,下列语句是完全不同的:

mysql> INSERT INTO table (name) VALUES (NULL);
mysql> INSERT INTO table (name) VALUES ("");

两个语句把值插入到name列,但是第一个插入一个NULL值而第二个插入一个空字符串。第一个的含义可以认为是“名字不知道”,而第二个则可意味着“他没有没有”。

在SQL中,NULL值在于任何其他值甚至NULL值比较时总是假的(FALSE)。包含NULL的一个表达式总是产生一个NULL值,除非在包含在表达式中的运算符和函数的文档中指出。在下列例子,所有的列返回NULL:

mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL);

如果你想要寻找值是NULL的列,你不能使用=NULL测试。下列语句不返回任何行,因为对任何表达式,expr = NULL是假的:

mysql> SELECT * FROM my_table WHERE phone = NULL;

要想寻找NULL值,你必须使用IS NULL测试。下例显示如何找出NULL电话号码和空的电话号码:

mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";

在MySQL中,就像很多其他的SQL服务器一样,你不能索引可以有NULL值的列。你必须声明这样的列为NOT NULL,而且,你不能插入NULL到索引的列中。

当用LOAD DATA INFILE读取数据时,空列用''更新。如果你想要在一个列中有NULL值,你应该在文本文件中使用\N。字面上的词'NULL'也可以在某些情形下使用。见7.16 LOAD DATA INFILE句法。

当使用ORDER BY时,首先呈现NULL值。如果你用DESC以降序排序,NULL值最后显示。当使用GROUP BY时,所有的NULL值被认为是相等的。

为了有助于NULL的处理,你能使用IS NULL和IS NOT NULL运算符和IFNULL()函数。

对某些列类型,NULL值被特殊地处理。如果你将NULL插入表的第一个TIMESTAMP列,则插入当前的日期和时间。如果你将NULL插入一个AUTO_INCREMENT列,则插入顺序中的下一个数字。

在《SQL-3参考大全》中,作者这样解释NULL的含义:未知或未定义。对NULL来说,有很多有趣的特性。

NULL是一个数据值,而且它属于一个域(?)。是的,例如一个字符串字段,其中的空值只能是一个字符串。尽管它的内容没有定义,或者未知,但它是字符串,这一点无可置疑。

NULL不是非法数据,这一点SQL-3 标准也说的很清楚。我们没有办法保存零分之一,但可以保存空值。虽然它是空值,是未定义,是未知,可它也的确是一个合法的信息。

运算黑洞:对于NULL,一般的运算都会返回NULL。比如加减乘除,这简直就是一个黑洞一样。永远不会有什么数据等于NULL。当然,1不等于NULL,2也一样。可是,NULL也不等于NULL。说一个NULL等于NULL是错误的。所以我们只能比较它“是”或“不是”。为了避免混乱,SQL-3标准有一些约定。比如表达式 x=NULL,结果应当是UNKOWN 。 而表达式“x is NULL”,就得看情况,如果x是NULL或 False,就返回Ture(?);x是非NULL,返回False。有点奇怪是不是,它基于NULL不等于NULL。 这个规则的确为SQL标准所支持,遇到这样的数据库系统,可不要感到惊讶。

三值逻辑:《鹿鼎记》中的韦小宝,整人的秘诀之一就是“我问你话,是就点头,不是就摇头,不许你出声!”的确,通常我们的逻辑观点,总是基于这种二值逻辑体系,对就是对,错就是错。可在关系理论中,没有这么简单。有一种没有绝对是非的情况存在:NULL。这就是关系理论的三值逻辑。

还有一些常见的与NULL相关的情况。比如,统计函数(也有的文档称之为聚集函数、集函数)通常会忽略NULL。不过,假设有这样一个表T:

C
-----
1	
2
NULL
NULL	

我们分别执行两个查询:SELECT COUNT(*) FROM T和SELECT COUNT(C) FROM T, 猜猜会有什么不同?起初,我以为两个结果应当一样。结果,前一个是4,后一个是2。前一个等于4,显然基于NULL也是数据这个事实;而后一个结果为2,是由于统计C列时,COUNT忽略了NULL。

SQL-3标准中,搜索条件(WHERE和HAVING)只接受TRUE,而约束却只拒绝FALSE,二者对NULL的接受态度相反。所以我们前面见到的ROOMS表才可以把空值写入人员字段。而在排序时,却又没什么规律。SQL标准只作出了一个补充定义,所以每个DBMS的处理 ORDER BY的方法并不相同,当然NULL不是高于所有值就是低于所有值。

在《SQL-3参考大全》中介绍了更详细的关于NULL的内容。另外,书中还介绍了两位数据库专家C.J.Date和E.f.Codd关于NULL的不同论点(E.F.Codd甚至希望有四值逻辑)有兴趣的朋友可以找来一读。在实践中,我们还会遇到一些有趣的事,特别是联接查询中, NULL让我们的人生变得 “丰富多彩”。

随机文章推荐
网站分类


注:如需转载本文,请注明出处(原文链接),谢谢。更多精彩内容,请进入简明现代魔法首页。

进入新博客
喜欢本文,就分享它吧
给我留言
您的名字:
您的邮件:
您的网站:


 

copyright © 2009 简明现代魔法    学习、分享、进步

power by Gonn 感谢所有关心和支持本站的朋友们