SQL Server:空VS空字符串


69

SQL Server中的空VarcharNULL值如何存储。并且如果我在UI上没有用于字段的用户输入,是否应该存储a或a ?stringNULL''



如果您使用空字符串路线,请确保其为空!修剪任何空间!如有必要,请对其进行两次修剪以确保其为空!请。
Airn5475

Answers:


64

有一个很好的文章在这里,其中讨论了这一点。要消除的关键问题是表大小没有区别,但是某些用户更喜欢使用空字符串,因为它可以使查询更加容易,因为无需执行NULL检查。您只需检查字符串是否为空。要注意的另一件事是NULL在关系数据库的上下文中的含义。这意味着在行标题中指向字符字段的指针设置为0x00,因此没有数据可访问。

更新 有一个详细的文章在这里它什么是真正发生连续的基础上谈判

每行对于允许为空的列都有一个空位图。如果该列中的行为空,则位图中的一位为1,否则为0。

对于可变大小的数据类型,实际大小为0字节。

对于固定大小的数据类型,实际大小是设置为默认值的默认数据类型大小(以字节为单位)(数字为0,字符为”)。

DBCC PAGE的结果表明NULL和空字符串都占用零字节


1
这并不是真正意义上的讨论。实际上,只是有人表达了自己的观点而没有任何依据可以支持。他们提出的唯一一点是空间需求是相同的,并且这两种方法都不支持。
MikeKulls 2012年

更新以提供有关行/列正在发生的事情的更多详细信息。
openshac 2012年

8
“要注意的另一件事是,在关系数据库的上下文中,NULL的含义是什么。这意味着指向字符字段的指针在行的标题中设置为0x00,因此没有数据可访问。” NULL并不表示在关系数据库的上下文中。它仅表示在一个特定供应商的关系数据库中的实现。
塔纳托斯(Thanatos)

7
第一个链接断开。
Spivonious

1
@Spivonious-链接现已修复。
openshac

38

注意使用null并检查sql server中的不相等性。

例如

select * from foo where bla <> 'something' 

将不会返回bla为null的记录。即使在逻辑上应该如此。

所以正确的检查方法是

select * from foo where isnull(bla,'') <> 'something' 

人们当然会忘记哪一个,然后会得到怪异的错误。


10
很难接受“ null = null”返回false,但是让“ null <>'something'”也返回false只会让人感到残酷。
MikeTeeVee 2011年

13
@MikeTeeVee:FALSE两种情况都不是。它UNKNOWN通过且不通过该条件(仅TRUE结果通过)。
ypercubeᵀᴹ

2
上面的查询可以优化一点,并且速度会更快一些。不用做select * from foo where isnull(bla,'') <> 'something',您可以做select * from foo where (bla <> 'something') or (bla is null)
Nicolas

14

空字符串是长度为零或没有字符的字符串。 Null没有数据。


那是对NULL的一种解释。在某些情况下,这显然是正确的。但是当涉及到NULL时,SQL是不一致的,因此在某些上下文中NULL表示未知。例如,“ NULL!='x'”返回NULL,因为在这种情况下NULL表示未知。如果是缺席,那就没有意义,因为“ x”不等于缺席。
Federico Razzoli

12

NULL和“空字符串”之间的概念差异在数据库设计中是真实且非常重要的,但经常会被误解和应用不正确-这是对两者的简短描述:

NULL-表示我们不知道该值是什么,它可能存在,但可能不存在,我们只是不知道。

空字符串-表示我们知道值是什么,什么都不是。

这是一个简单的示例:假设您有一个包含人名的表,其中包括first_namemiddle_namelast_name的单独列。在first_name ='John',last_name ='Doe'和middle_name为NULL的情况下,这意味着我们不知道中间名是什么,甚至不存在。更改该方案,使middle_name =''(即空字符串),这意味着我们知道没有中间名。

我曾经听过一位SQL Server讲师提倡将数据库中的每个字符类型列都设置为必需,然后为每个''(空字符串)或“未知”分配一个DEFAULT VALUE。在说明这一点时,讲师证明他对NULL和空字符串之间的区别没有清楚的了解。诚然,这些差异似乎令人困惑,但是对我来说,上面的示例有助于弄清差异。同样,理解编写SQL代码时的区别,正确处理NULL和空字符串也很重要。


3
我想指出,这不是普遍的客观意见。
industryworker3595112

1
您在这里认为NULL表示“未知”,而不应该表示“无” /“不适用”。但是其他数据类型呢?如果我们有表CONTRACTS,其列为DATE类型的“ maturity_date”。如果我们有没有到期日的合同(例如,直到要求的存款),该怎么办?在这种情况下,完全可以接受的处理方法是保留“ maturity_date = NULL”。(即,对于其他所有数据类型,在“无” /“不适用”的情况下,以NULL为宜)(我的观点:null与空字符串vs特殊值只是协议约定的问题)
Industryworker3595112

是的,我必须同意这是两者的单一实现。这是合理的,但其他实现也是如此。
Mike M

2

NULL值分别存储在所有列的特殊位图空间中。

如果您不区分应用程序NULL''应用程序,则建议您将其存储''在表中(除非string列是外键,在这种情况下,最好禁止该列存储空字符串并允许使用NULL(如果与您的应用程序逻辑兼容)。


1

NULL是非值,例如undefined。''是一个包含0个字符的空字符串。
数据库中字符串的值取决于您在UI中的值,但是通常,''如果您在查询或存储过程中指定参数,则该字符串为空字符串。


1

如果不是外键字段,则不使用空字符串可以为您节省一些麻烦。仅当您将null表示不同于空字符串的内容时才允许null。例如,如果您具有密码字段,则空值可能表示新用户尚未创建其密码,而空varchar可能表示空密码。对于诸如“ address2”之类的允许空值的字段,只会使生活变得困难。需要注意的事情包括空引用以及Vagif Verdi提到的=和<>运算符的意外结果,而注意这些事情通常是不必要的程序员开销。

编辑:如果性能是一个问题,请参阅以下相关问题:可空与非空varchar数据类型-查询速度更快?


-1

如何在SQL Server中存储“ NULL”和“空varchar”值。你为什么想知道呢?换句话说,如果您知道答案,您将如何使用该信息?

并且如果我在UI上没有用于字符串字段的用户条目,是否应该存储NULL或''?这取决于您所在领域的性质。问问自己,空字符串是否对您的字段有效。

如果是(例如,地址中的房屋名称),则可能是您要存储的内容(取决于您是否知道该地址没有房屋名称)。

如果不是(例如,一个人的名字),那么您应该存储一个null,因为人们没有空白的名字(就我所知,在任何文化中)。


1
我知道那不是那么重要。但是,我想得到它。
Akram Shahda
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.