Maniero Asked: 2011-01-04 15:05:38 +0800 CST2011-01-04 15:05:38 +0800 CST 2011-01-04 15:05:38 +0800 CST 何时使用 NULL 以及何时使用空字符串? 772 我主要对 MySQL 和 PostgreSQL 感兴趣,但您一般可以回答以下问题: 是否存在将空字符串与 NULL 区分开来的逻辑场景? 将空字符串存储为...的物理存储含义是什么? 无效的? 空字符串? 另一个领域? 还有什么办法吗? null feature-comparison 11 个回答 Voted Best Answer Larry Coleman 2011-01-04T16:18:01+08:002011-01-04T16:18:01+08:00 假设记录来自收集姓名和地址信息的表单。如果用户不住在公寓里,地址的第 2 行通常为空白。在这种情况下,空字符串是完全有效的。我倾向于使用 NULL 来表示该值未知或未给出。 我不相信物理存储差异在实践中值得担心。作为数据库管理员,我们有更大的鱼可炒! bernd_k 2011-01-05T01:00:13+08:002011-01-05T01:00:13+08:00 我不了解 MySQL 和 PostgreSQL,但让我概括一下。 有一个 DBMS,即 Oracle,它不允许在 NULL 和 '' 之间选择它的用户。这清楚地表明没有必要区分两者。有一些烦人的后果: 您将 varchar2 设置为一个空字符串,如下所示: Update mytable set varchar_col = ''; 以下导致相同的结果 Update mytable set varchar_col = NULL; 但是要选择值为空或 NULL 的列,您必须使用 select * from mytable where varchar_col is NULL; 使用 select * from mytable where varchar_col = ''; 在语法上是正确的,但它永远不会返回一行。 另一方面,在 Oracle 中连接字符串时。NULL varchars 被视为空字符串。 select NULL || 'abc' from DUAL; 产生abc。在这些情况下,其他 DBMS 将返回 NULL。 当你想明确表达一个值被赋值时,你必须使用像''这样的东西。 而且您必须担心修剪不为空是否会导致 NULL select case when ltrim(' ') is null then 'null' else 'not null' end from dual 确实如此。 现在看看 '' 与 NULL 不同的 DBMS(例如 SQL-Server) 使用 '' 通常更容易,并且在大多数情况下,实际上不需要区分两者。我知道的一个例外情况是,当您的列代表某些设置并且您没有为它们设置空默认值时。当您可以区分 '' 和 NULL 时,您可以表示您的设置为空并避免应用默认值。 Gan 2011-01-04T17:58:55+08:002011-01-04T17:58:55+08:00 这取决于您正在处理的域。NULL表示没有值(即没有值),而空字符串表示存在长度为零的字符串值。 例如,假设您有一个表来存储一个人的数据,并且它包含一Gender列。您可以将值保存为“男性”或“女性”。如果用户能够选择不提供性别数据,则应将其另存为NULL(即用户未提供值)而不是空字符串(因为没有值为 '' 的性别)。 Matthew Schinckel 2011-01-04T17:47:21+08:002011-01-04T17:47:21+08:00 值得记住的一件事是,当您有一个不需要的字段时,但存在的任何值都必须是唯一的,这将要求您将空值存储为 NULL。否则,您将只能在该字段中拥有一个具有空值的元组。 关系代数和 NULL 值也有一些区别:例如,NULL != NULL。 Abie 2011-01-06T21:26:46+08:002011-01-06T21:26:46+08:00 您还可以考虑 Date 对 NULL 的批评以及SQL 和关系理论中 3VL 的问题(以及 Rubinson 对 Date 的批评、Null、三值逻辑和 SQL 中的歧义的批评:Critiqueing Date's Critique)。 两者都在相关的 SO 线程中进行了详细的引用和讨论,Options for removal NULLable columns from a DB model。 Patrick 2011-01-04T17:17:43+08:002011-01-04T17:17:43+08:00 NULL一个新的想法,对你选择/的一个很大影响NOT NULL是你是否使用了一个框架。我经常使用 symfony,NULL并且在操作数据时使用允许字段简化了一些代码和数据检查。 如果您没有使用框架,或者您使用的是简单的 sql 语句和处理,我会选择您认为更容易跟踪的任何选择。我通常更喜欢 NULL,这样执行INSERT语句就不会因为忘记将空字段设置为NULL. Martin 2011-10-04T05:07:30+08:002011-10-04T05:07:30+08:00 不得不与 Oracle 合作(这不允许你区分)我得出了以下结论: 从逻辑 POV 来看,这并不重要。我真的想不出任何引人注目的例子,其中区分 NULL 和零长度字符串会在 DBMS 中增加任何价值。 从中可以看出:您要么有一个NULL不允许零长度''的列,要么有一个允许零长度的NOT NULL列。(这两者在 Oracle 中都是不可能的,就像'' === NULL那里一样。) 根据我的经验,在处理数据''时更有意义,因为通常您希望将缺少字符串作为空字符串处理:连接、比较等。 回到我的 Oracle 体验:假设您要为搜索请求生成查询。如果您(在非Oracle 中)使用''您可以只生成WHERE columnX = <searchvalue>,它将适用于相等搜索。如果你使用NULL你必须这样做WHERE columnX=<searchvalue> or (columnX is NULL and searchvalue is NULL)。 第二个,更复杂的逻辑,确实是你在 Oracle 中必须做的,作为 NULL 并且''在那里是一样的。 Guy Birkbeck 2015-02-04T11:45:33+08:002015-02-04T11:45:33+08:00 从设计的角度来看,它们也有所不同: 例如 CREATE TABLE t ( id INTEGER NOT NULL, name CHARACTER(40), CONSTRAINT t_PK PRIMARY KEY (id) ); CREATE UNIQUE INDEX t_AK1 ON t (name); 好像: \d t Table "public.t" Column | Type | Modifiers --------+---------------+----------- id | integer | not null name | character(40) | Indexes: "t_pk" PRIMARY KEY, btree (id) "t_ak1" UNIQUE, btree (name) 让我们插入一些数据: op=# insert into t(id, name ) values ( 1, 'Hello'); INSERT 0 1 op=# insert into t( id, name) values ( 2, ''); INSERT 0 1 op=# insert into t( id, name) values ( 3, ''); ERROR: duplicate key value violates unique constraint "t_ak1" 现在让我们尝试使用 null: op=# insert into t( id, name) values (4, null ); INSERT 0 1 op=# insert into t( id, name) values (5, null); INSERT 0 1 这是允许的。 Soooooo:空值不是微不足道的字符串,也不是相反的。 干杯 noonex 2017-06-08T08:56:02+08:002017-06-08T08:56:02+08:00 如果我们谈论理论,那么 Codd 规则说 RDBMS 必须NULL以特殊的方式处理值。 具体如何使用取决于数据库架构师,具体取决于实际的域 - 任务 - 项目 - 应用程序 - 区域。 Riccardo Manfrin 2020-08-13T00:54:13+08:002020-08-13T00:54:13+08:00 取决于意义。举个例子:你的列存储了一个人在 2020 年 8 月 12 日上午 8 点到 9 点之间所说的内容。机会是 一个人说了些什么(非空字符串) 一个人什么也没说(空字符串) 你不知道一个人说了什么(空值) 您可以通过展示(或不展示)提供给您的内容来使您的数据意味着对您更方便的内容
假设记录来自收集姓名和地址信息的表单。如果用户不住在公寓里,地址的第 2 行通常为空白。在这种情况下,空字符串是完全有效的。我倾向于使用 NULL 来表示该值未知或未给出。
我不相信物理存储差异在实践中值得担心。作为数据库管理员,我们有更大的鱼可炒!
我不了解 MySQL 和 PostgreSQL,但让我概括一下。
有一个 DBMS,即 Oracle,它不允许在 NULL 和 '' 之间选择它的用户。这清楚地表明没有必要区分两者。有一些烦人的后果:
您将 varchar2 设置为一个空字符串,如下所示:
以下导致相同的结果
但是要选择值为空或 NULL 的列,您必须使用
使用
在语法上是正确的,但它永远不会返回一行。
另一方面,在 Oracle 中连接字符串时。NULL varchars 被视为空字符串。
产生abc。在这些情况下,其他 DBMS 将返回 NULL。
当你想明确表达一个值被赋值时,你必须使用像''这样的东西。
而且您必须担心修剪不为空是否会导致 NULL
确实如此。
现在看看 '' 与 NULL 不同的 DBMS(例如 SQL-Server)
使用 '' 通常更容易,并且在大多数情况下,实际上不需要区分两者。我知道的一个例外情况是,当您的列代表某些设置并且您没有为它们设置空默认值时。当您可以区分 '' 和 NULL 时,您可以表示您的设置为空并避免应用默认值。
这取决于您正在处理的域。
NULL
表示没有值(即没有值),而空字符串表示存在长度为零的字符串值。例如,假设您有一个表来存储一个人的数据,并且它包含一
Gender
列。您可以将值保存为“男性”或“女性”。如果用户能够选择不提供性别数据,则应将其另存为NULL
(即用户未提供值)而不是空字符串(因为没有值为 '' 的性别)。值得记住的一件事是,当您有一个不需要的字段时,但存在的任何值都必须是唯一的,这将要求您将空值存储为 NULL。否则,您将只能在该字段中拥有一个具有空值的元组。
关系代数和 NULL 值也有一些区别:例如,NULL != NULL。
您还可以考虑 Date 对 NULL 的批评以及SQL 和关系理论中 3VL 的问题(以及 Rubinson 对 Date 的批评、Null、三值逻辑和 SQL 中的歧义的批评:Critiqueing Date's Critique)。
两者都在相关的 SO 线程中进行了详细的引用和讨论,Options for removal NULLable columns from a DB model。
NULL
一个新的想法,对你选择/的一个很大影响NOT NULL
是你是否使用了一个框架。我经常使用 symfony,NULL
并且在操作数据时使用允许字段简化了一些代码和数据检查。如果您没有使用框架,或者您使用的是简单的 sql 语句和处理,我会选择您认为更容易跟踪的任何选择。我通常更喜欢 NULL,这样执行
INSERT
语句就不会因为忘记将空字段设置为NULL
.不得不与 Oracle 合作(这不允许你区分)我得出了以下结论:
从逻辑 POV 来看,这并不重要。我真的想不出任何引人注目的例子,其中区分 NULL 和零长度字符串会在 DBMS 中增加任何价值。
从中可以看出:您要么有一个
NULL
不允许零长度''
的列,要么有一个允许零长度的NOT NULL
列。(这两者在 Oracle 中都是不可能的,就像'' === NULL
那里一样。)根据我的经验,在处理数据
''
时更有意义,因为通常您希望将缺少字符串作为空字符串处理:连接、比较等。回到我的 Oracle 体验:假设您要为搜索请求生成查询。如果您(在非Oracle 中)使用
''
您可以只生成WHERE columnX = <searchvalue>
,它将适用于相等搜索。如果你使用NULL
你必须这样做WHERE columnX=<searchvalue> or (columnX is NULL and searchvalue is NULL)
。第二个,更复杂的逻辑,确实是你在 Oracle 中必须做的,作为 NULL 并且
''
在那里是一样的。从设计的角度来看,它们也有所不同:
例如
好像:
让我们插入一些数据:
现在让我们尝试使用 null:
这是允许的。
Soooooo:空值不是微不足道的字符串,也不是相反的。
干杯
如果我们谈论理论,那么 Codd 规则说 RDBMS 必须
NULL
以特殊的方式处理值。具体如何使用取决于数据库架构师,具体取决于实际的域 - 任务 - 项目 - 应用程序 - 区域。
取决于意义。举个例子:你的列存储了一个人在 2020 年 8 月 12 日上午 8 点到 9 点之间所说的内容。机会是
您可以通过展示(或不展示)提供给您的内容来使您的数据意味着对您更方便的内容