【问题标题】:Can Microsoft store three-valued fields in a single bit?Microsoft 可以在一个位中存储三值字段吗?
【发布时间】:2011-02-26 15:17:50
【问题描述】:

我对 SQL/数据库一无所知,但我正在和一位从事大量数据库工作的朋友聊天,讨论了一些数据库如何使用“布尔”字段,该字段除了 true 和 false 之外还可以取 NULL 值.

对此,他发表了如下评论:“值得微软称赞的是,他们从来没有将这种字段称为布尔值,他们只是稍微称呼它。而且它是一个真实的位 - 如果你有八个或一条记录中的位域较少,只需要一个字节就可以全部存储。”

当然这对我来说似乎是不可能的 - 如果该字段可以保存三个值,那么您不会将其中的八个值放入一个字节中。我的朋友同意这看起来很奇怪,但恳求对底层内部的无知,并说据他所知,从 SQL 端看,这样的字段可以保存三个值,并且确实需要一个字节的存储空间.我想我们中的一个人有一根电线交叉。谁能解释一下这里到底发生了什么?

【问题讨论】:

  • Jon Skeet 可以将三值字段存储在一个位中。
  • 呸呸呸我早该看到的!

标签: sql-server database null boolean bit-fields


【解决方案1】:

其他人已经说过BIT需要2位,而不是1。

另一个经常被遗忘的重要点:SQL Server 中的位不是布尔或逻辑数据类型;它是数字(整数)数据类型。 "An integer data type that can take a value of 1, 0, or NULL"。 Bit 仅支持数字运算符(、+、-)。它不支持任何逻辑运算符(AND、OR、NOT 等)。

【讨论】:

    【解决方案2】:

    我推荐阅读这篇文章以获得对空存储的一个很好的解释:How does SQL Server really store NULL-s。简而言之,空/非空位存储在不同的位置,即行的空位图。

    来自文章:

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

    因此,虽然 8 位列的实际 存储在 1 个字节中,但行的空位图中还有额外的位指示该列是否为 NULL...所以取决于如何你在数。为了完全准确,8 位列使用 2 个字节,只是分成 2 个不同的位置。

    【讨论】:

    • 啊,我还以为是这样的。感谢您提供指向血腥细节的链接!
    • 您的声望增长必须是 SO 上任何人中增长最高的之一。我对你的代表图的斜率很感兴趣!
    • @Mitch - 哈哈我有一段时间没检查了,这很酷,谢谢你指出:)
    【解决方案3】:

    你的朋友是对的,但同时也是错的。 BIT 字段可能被认为能够维护三个不同的值,但根据定义 NULL 是没有值。

    此外,在位字段上允许 NULL 意味着该字段将使用 2 个位(一个用于值,一个用于是否为 NULL)。但是字段的 NULL 状态(NULL 位)存储在行的位图中,而不是存储在给定列的确切内存空间中。

    【讨论】:

      【解决方案4】:

      你是对的。您可以将八个真/假值打包到一个字节中,但您仍然需要额外的存储空间来指示它是否为 NULL。仅用 28 表示 38 个不同的状态是不可能的。

      【讨论】:

        【解决方案5】:

        空指示符是分开存储的,所以一个可空位实际上需要两个位。严格来说,“null”不是第三个值;它有点像一个占位符,上面写着“这里可能有一个值,但我们不知道它是什么。”所以如果某位为空,你可以将其与true进行比较,则比较失败,但你也可以将其与false进行比较,则比较失败。

        【讨论】:

          猜你喜欢
          • 2016-02-07
          • 2011-09-23
          • 2015-12-19
          • 1970-01-01
          • 2011-02-21
          • 2011-12-22
          • 1970-01-01
          • 1970-01-01
          • 2020-05-16
          相关资源
          最近更新 更多