AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 59
Accepted
Maniero
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 11 个回答
  • 119839 Views

11 个回答

  • Voted
  1. Best Answer
    Larry Coleman
    2011-01-04T16:18:01+08:002011-01-04T16:18:01+08:00

    假设记录来自收集姓名和地址信息的表单。如果用户不住在公寓里,地址的第 2 行通常为空白。在这种情况下,空字符串是完全有效的。我倾向于使用 NULL 来表示该值未知或未给出。

    我不相信物理存储差异在实践中值得担心。作为数据库管理员,我们有更大的鱼可炒!

    • 82
  2. 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 时,您可以表示您的设置为空并避免应用默认值。

    • 27
  3. Gan
    2011-01-04T17:58:55+08:002011-01-04T17:58:55+08:00

    这取决于您正在处理的域。NULL表示没有值(即没有值),而空字符串表示存在长度为零的字符串值。

    例如,假设您有一个表来存储一个人的数据,并且它包含一Gender列。您可以将值保存为“男性”或“女性”。如果用户能够选择不提供性别数据,则应将其另存为NULL(即用户未提供值)而不是空字符串(因为没有值为 '' 的性别)。

    • 17
  4. Matthew Schinckel
    2011-01-04T17:47:21+08:002011-01-04T17:47:21+08:00

    值得记住的一件事是,当您有一个不需要的字段时,但存在的任何值都必须是唯一的,这将要求您将空值存储为 NULL。否则,您将只能在该字段中拥有一个具有空值的元组。

    关系代数和 NULL 值也有一些区别:例如,NULL != NULL。

    • 12
  5. 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。

    • 7
  6. Patrick
    2011-01-04T17:17:43+08:002011-01-04T17:17:43+08:00

    NULL一个新的想法,对你选择/的一个很大影响NOT NULL是你是否使用了一个框架。我经常使用 symfony,NULL并且在操作数据时使用允许字段简化了一些代码和数据检查。

    如果您没有使用框架,或者您使用的是简单的 sql 语句和处理,我会选择您认为更容易跟踪的任何选择。我通常更喜欢 NULL,这样执行INSERT语句就不会因为忘记将空字段设置为NULL.

    • 4
  7. 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 并且''在那里是一样的。

    • 3
  8. 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:空值不是微不足道的字符串,也不是相反的。

    干杯

    • 3
  9. noonex
    2017-06-08T08:56:02+08:002017-06-08T08:56:02+08:00

    如果我们谈论理论,那么 Codd 规则说 RDBMS 必须NULL以特殊的方式处理值。

    具体如何使用取决于数据库架构师,具体取决于实际的域 - 任务 - 项目 - 应用程序 - 区域。

    • 1
  10. Riccardo Manfrin
    2020-08-13T00:54:13+08:002020-08-13T00:54:13+08:00

    取决于意义。举个例子:你的列存储了一个人在 2020 年 8 月 12 日上午 8 点到 9 点之间所说的内容。机会是

    1. 一个人说了些什么(非空字符串)
    2. 一个人什么也没说(空字符串)
    3. 你不知道一个人说了什么(空值)

    您可以通过展示(或不展示)提供给您的内容来使您的数据意味着对您更方便的内容

    • 0

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve