【发布时间】:2011-05-16 00:16:04
【问题描述】:
如果在我的表中的一列中,我希望值为是、否或可选,那么我需要使用什么数据类型?
【问题讨论】:
-
一个可以为空的位会起作用。
标签: sql sql-server tsql types
如果在我的表中的一列中,我希望值为是、否或可选,那么我需要使用什么数据类型?
【问题讨论】:
标签: sql sql-server tsql types
我很惊讶在这里看到如此多的“Bit”投票。这是一个糟糕的选择。
在语义上,NULL 表示“未知”,因此它不是第三个(已知)值的好选择。如果您以这种方式使用它,您可能会遇到很多问题。例如,聚合函数、GROUP BY 和联接的行为可能与您预期的不同。用户界面也可能无法很好地将 NULL 视为一个值(例如,MS Access 遇到了空位字段的问题)。您也无法通过定义字段 NOT NULL 来帮助保持数据完整性。
最后,您可能会混淆任何其他习惯于正常使用该值的数据库/应用程序开发人员。
使用 CHAR 或 TinyInt。
【讨论】:
我同意“OMG Ponies”提出的选项,但不同意他在这种情况下的结论。
使用位列!分配一个位来保存数据会免费提供一个六个其他 Y/N/O 和一个 Y/N 存储位置。当使用 Bit 数据类型时,始终将至少一个位定义为非空,因此 SQL 将在数据页中为这些值保留一个位置。
【讨论】:
所有选项都占用相同数量的空间,使得 JOIN/etc 的性能相当。
BIT 不是最明智的选择,如果可能的值有可能发生变化。 CHAR(1) 可立即读取 IE:Y、N、O。TINYINT 是您希望通过外键关联的表中的主键的不错选择,并将描述性文本存储在另一列中。
如果不使用外键关系,我会选择CHAR(1),否则TINYINT。
使用 CHAR(1),具有单个字符的自然主键是非常不可能的。如果您有 2 个以上的单词以相同的字符开头,则假设基于前导字符的自然键会失败,并且如果标签需要更改会导致悲伤,因为键也应该更改并永久存在(除非您很懒&喜欢解释为什么代码不遵循与其他代码相同的方案)。 CHAR(1) 还提供了 TINYINT 所做的大约五分之一的可能性(假设上限,52 个区分大小写的值)——人工/代理键与描述更改隔离。
【讨论】:
我会使用 char(1) 或带有检查约束的 INT。 只是为了尽量减少数据库与您用来访问它的任何抽象层之间的潜在不匹配。例如,JDBC 没有 TINYINT。
【讨论】:
Sergey 和 JonVD 都提供了很好的解决方案,但我同意 Sergey 的观点。可空位为您提供三个选项。如果它不为空,那么您知道用户选择了该选项。
【讨论】:
将 BIT 用于 True / False,或者在您的情况下使用 CHAR(1) Y/N 或 CHAR(3) Yes / No。
我真的会在这里使用 CHAR(1),因为额外的 2 个字符不会增加任何实际价值。
【讨论】: