NULL和NOT NULL有什么区别?什么时候应该使用?
答案 0 :(得分:52)
NULL表示您不必为字段提供值...
NOT NULL表示您必须为字段提供值。
例如,如果要为系统构建一个注册用户表,您可能需要确保user-id始终填充一个值(即NOT NULL),但可选的配偶名称字段可以是留空(NULL)
答案 1 :(得分:10)
我建议
如果空值偶然输入,那么对于NULL为空而言没有有意义含义的字段可能会引入错误。使用NOT NULL可以防止这种情况。
NULL字段的最常见原因是您有一个外键字段,它是“零或一”关系的选项,即并不总是链接。
如果你发现你有一个包含许多列的表,其中许多列可以为NULL,那么它开始听起来像反模式,考虑垂直分区在你的应用程序上下文中是否更有意义:)
NULL还有另一个有用的用法 - 使索引中的所有列为NULL将停止为该行创建的索引记录,从而优化索引;您可能只想索引一小部分行(例如,对于仅设置为1%的“活动”标志或其他内容) - 使得以通常为NULL的列开头的索引可以节省空间并优化该索引。
答案 2 :(得分:9)
NULL和NOT NULL有什么区别?
创建表格或向表格添加列时,您需要使用NULL
或NOT NULL
指定列值选项。 NOT NULL
表示该列的任何记录都不能具有NULL
值; NULL
表示NULL
是允许的值(即使列具有外键约束)。因为NULL
不是值,所以你可以看到为什么有些人称之为可选性 - 因为数据库表要求为了有一个列,所以表中的每条记录都必须有一个列的实例。
什么时候应该使用?
这取决于您的业务规则
通常,您希望尽可能多的列为NOT NULL
,因为您希望确保数据始终存在。
答案 3 :(得分:4)
NOT NULL
表示列中不能包含NULL
值 - 相反,如果在为该列插入行时未指定任何内容,则它将使用指定的任何默认值(或者如果没有默认值)指定,无论MySQL的默认类型是什么)。
非NOT NULL
的字段的值可能为NULL
(这实际上意味着缺少/未知/未指定的值)。 NULL
的行为与正常值see here for more info不同。
答案 4 :(得分:2)
NOT NULL
是一个列约束,如果您的列不在主键中(主键本身不为null,因此明确地说明NOT NULL
对于它们很愚蠢),则应该使用您知道值将始终是已知的(未知或缺失),因此该列中不需要空值。
NULL
是在许多上下文中出现的关键字 - 包括作为列约束,其中它表示与默认值相同(即,允许空值) - 但在许多其他上下文中,例如在列中插入null作为INSERT...VALUES
语句的一部分。
答案 5 :(得分:2)
另请注意,NULL不等于其他任何内容,即使不是NULL本身。
例如:
mysql> select if(NULL=NULL, "null=null", "null!=null");
+------------------------------------------+
| if(NULL=NULL, "null=null", "null!=null") |
+------------------------------------------+
| null!=null |
+------------------------------------------+
1 row in set (0.00 sec)
当您需要部分填充的列上的唯一键时,NULL的这个定义非常有用。在这种情况下,您可以将所有空值保留为NULL,并且不会导致任何违反唯一性键,因为NULL!= NULL。
以下是如何查看某些内容是否为NULL的示例:
mysql> select if(null is null, "null is null", "null is not null");
+------------------------------------------------------+
| if(null is null, "null is null", "null is not null") |
+------------------------------------------------------+
| null is null |
+------------------------------------------------------+
1 row in set (0.01 sec)
答案 6 :(得分:2)
正如其他人所回答的那样,NOT NULL
只是意味着NULL
不是允许的值。但是,您始终可以选择空字符串''
(适用于varchar
)或0
(适用于int
)等。
使用NOT NULL
时的一个不错的功能是,如果您忘记在INSERT
期间设置列的值,则会收到错误或警告。 (假设NOT NULL
列没有DEFAULT
)
允许NULL
列的主要打嗝是永远不会找到<>
(不等于)运算符。例如,使用以下category
s
Desktops
Mobiles
NULL -- probably embedded devices
=
运算符按预期工作
select * from myTable where category="Desktops";
但是,<>
运算符将排除任何NULL
条目。
select * from myTable where category<>"Mobiles";
-- returns only desktops, embedded devices were not returned
这可能是导致细微错误的原因,特别是如果列在测试初始期间没有NULL
数据,但后来由于后续开发而添加了一些NULL
值。因此,我将所有列设置为NOT NULL
。
但是,在使用NULL
UNIQUE
/ KEY
时允许INDEX
值会很有帮助。通常,唯一键要求列(或列的组合)对于整个表是唯一的。唯一键是数据库为您强制执行的一个很好的保护措施。
在某些情况下,您可能需要大多数行的安全措施,但也有例外。
如果该特定UNIQUE KEY
引用的任何列为NULL
,则不再对该行强制执行唯一性。显然,只有在你允许NULL
在该列上,理解我上面解释的打嗝时,这才有效。
如果您决定允许NULL
值,请考虑使用附加条件编写<>
语句来检测NULL
。
select * from myTable where category<>"Desktops" or category is null;
答案 7 :(得分:0)
尽管大家普遍认为,NOT NULL并不要求您填写所有字段;这只是意味着您忽略的任何内容都将具有默认值。所以不,这并不意味着痛苦。此外,NULL在索引方面的效率较低,并且在处理从查询中接收到的内容时会导致许多极端情况。
因此,尽管NULL值当然具有理论意义(在极少数情况下您可以从中受益),但大多数情况下,NOT NULL是可行的方法。 NOT NULL使您的字段像任何变量一样工作:它们始终具有一个值,然后您决定该值是否有意义。是的,如果您需要所有可能的值和一个额外的值来告诉您那里什么都没有,您仍然可以使用NULL。
因为它是描述性的。它具有语义上的含义,例如“ Nnah,等等,这不仅是一个空字符串,而且更具有异国情调-这是缺乏信息!”。他们将解释说“时间是00:00”和“我不知道现在是几点”。这是有效的;只需花费额外的精力即可解决此问题。因为系统将为信息“有任何价值”分配额外的空间,并且将不断地进行检验。因此,为了获得微小的语义美,您会浪费时间和存储空间。不多,但是仍然。
整个现象让我想起了一个古老的 isset 辩论,人们在某种程度上痴迷于查看不存在的数组索引并收到错误消息的美。这是完全没有意义的。实际的默认设置是幸运的,它们以“您知道我的意思”的方式简化了工作,并且您可以编写更具可读性,更简洁,更具表达力的代码,即使您在其他项目中呆了4年,该代码也仍然有意义。
如果有JOIN,则当您想加入另一行但不存在时,您迟早会遇到NULL。这是唯一没有NULL就无法生存的唯一有效情况。您必须知道这不仅是空记录,而且是完全没有记录。
否则? NOT NULL方便,高效,并且给您带来更少的惊喜。作为回报,某些语义强迫症患者会称其为愚昧无知。 (这不是问题,应该如此。)
您决定:)