【问题标题】:About choosing Data type关于选择数据类型
【发布时间】:2011-05-16 00:16:04
【问题描述】:

如果在我的表中的一列中,我希望值为是、否或可选,那么我需要使用什么数据类型?

【问题讨论】:

  • 一个可以为空的位会起作用。

标签: sql sql-server tsql types


【解决方案1】:

我很惊讶在这里看到如此多的“Bit”投票。这是一个糟糕的选择。

在语义上,NULL 表示“未知”,因此它不是第三个(已知)值的好选择。如果您以这种方式使用它,您可能会遇到很多问题。例如,聚合函数、GROUP BY 和联接的行为可能与您预期的不同。用户界面也可能无法很好地将 NULL 视为一个值(例如,MS Access 遇到了空位字段的问题)。您也无法通过定义字段 NOT NULL 来帮助保持数据完整性。

最后,您可能会混淆任何其他习惯于正常使用该值的数据库/应用程序开发人员。

使用 CHAR 或 TinyInt。

【讨论】:

    【解决方案2】:

    我同意“OMG Ponies”提出的选项,但不同意他在这种情况下的结论。

    使用位列!分配一个位来保存数据会免费提供一个六个其他 Y/N/O 和一个 Y/N 存储位置。当使用 Bit 数据类型时,始终将至少一个位定义为非空,因此 SQL 将在数据页中为这些值保留一个位置。

    【讨论】:

      【解决方案3】:

      位:

      • 占用 1 个字节,但在 SQL Server 中最多可以将 8 个 BIT 字段合并为一个 BYTE。
      • 存储以下两个值之一:1(表示真)和 0(表示假),因此该列需要可以为空,以便 NULL 作为您的第三个值传递

      CHAR(1)

      • 占用 1 个字节
      • 26 个字符(如果不区分大小写 ASCII)与 52 个字符(如果区分大小写)

      TINYINT

      • 占用 1 个字节
      • 值 0 到 255

      性能

      所有选项都占用相同数量的空间,使得 JOIN/etc 的性能相当。

      比较

      BIT 不是最明智的选择,如果可能的值有可能发生变化。 CHAR(1) 可立即读取 IE:Y、N、O。TINYINT 是您希望通过外键关联的表中的主键的不错选择,并将描述性文本存储在另一列中。

      结论:

      如果不使用外键关系,我会选择CHAR(1),否则TINYINT
      使用 CHAR(1),具有单个字符的自然主键是非常不可能的。如果您有 2 个以上的单词以相同的字符开头,则假设基于前导字符的自然键会失败,并且如果标签需要更改会导致悲伤,因为键也应该更改并永久存在(除非您很懒&喜欢解释为什么代码不遵循与其他代码相同的方案)。 CHAR(1) 还提供了 TINYINT 所做的大约五分之一的可能性(假设上限,52 个区分大小写的值)——人工/代理键与描述更改隔离。

      【讨论】:

      • 实际上,BIT 占用 1 个字节 - 但在 SQL Server 中最多可以将 8 个 BIT 字段合并为单个 BYTE。
      • 使用 CHAR(1) 时,请记住添加检查约束,以便只有您想要的值才能放入字段中。例如我的列 IN('Y','N','O')
      • “TINYINT 是您想通过外键关联的表中的主键的不错选择,并将描述性文本存储在另一列中”为什么 CHAR(1) 对它不利?
      • @vgv8:我更新了结论来解决这个问题。两者都不是“坏”,只是取决于业务规则和使用——一个比另一个更谨慎。
      【解决方案4】:

      我会使用 char(1) 或带有检查约束的 INT。 只是为了尽量减少数据库与您用来访问它的任何抽象层之间的潜在不匹配。例如,JDBC 没有 TINYINT。

      【讨论】:

        【解决方案5】:

        Sergey 和 JonVD 都提供了很好的解决方案,但我同意 Sergey 的观点。可空位为您提供三个选项。如果它不为空,那么您知道用户选择了该选项。

        【讨论】:

        • 此外,您需要在 CHAR 列上添加一个约束,以确保这些值仅是例如'Y'、'N' 或 NULL,否则会冒着随机输入随机字符的风险。
        【解决方案6】:

        将 BIT 用于 True / False,或者在您的情况下使用 CHAR(1) Y/N 或 CHAR(3) Yes / No。

        我真的会在这里使用 CHAR(1),因为额外的 2 个字符不会增加任何实际价值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-30
          • 1970-01-01
          • 1970-01-01
          • 2011-08-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-31
          • 2021-02-25
          相关资源
          最近更新 更多