欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

数据库中容易混淆空值

程序员文章站 2022-04-12 20:53:29
...

往往很多人都认为空值与空白或0值是一样的,至少我在今天以前是这么认为的,其实空值并不与空白和0值是一回事。 Null值表示数值未知。没有两个相等的空值,比较两个空值或空值和任意一个数比较返回的均是未知。 下面有以下从SQL 联机丛书中的关于空值的信息

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

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

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

  • 若要测试查询中的空值,在where 子句中使用IS NULL 或 IS NOT NULL
  • 在SQL查询结果时,空值在结果集内显示为(null)
  • 可通过以下方法在列中插入NULL,在INSERT 或UPDATE中显式声明NULL,或不使此列进入INSERT
  • 不能将空值用于区分表中两行所需的信息。

如下数据库截图所示:

数据库中容易混淆空值

空值显示为 (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让我们的人生变得 “丰富多彩”。