此答案适用于 ISO/IEC/ANSI 标准 SQL,包括更好的免费软件假装 SQL。
第一个问题是您已经确定了两个类别,而不是一个,因此无法合理比较它们。
A. 第一类
(1) (4) 和 (5) 包含多个可能的值并且是一个类别。所有这些都可以在 WHERE 子句中轻松有效地使用。它们具有相同的存储空间,因此存储和读取性能都不是问题。因此,剩下的选择只是基于列的实际数据类型。
ENUM 是非标准的;更好或标准的方法是使用查找表;那么这些值在表格中是可见的,而不是隐藏的,并且可以被任何报告工具枚举。由于内部处理,ENUM 的读取性能会受到不小的影响。
B. 第二类
(2) 和 (3) 是二值元素:真/假;男/女;死/活。该类别与第一类不同。它在您的数据模型和每个平台中的处理方式都是不同的。BOOLEAN 只是 BIT 的同义词,它们是一回事。从法律上讲(SQL 方面),所有符合 SQL 的平台都处理相同的问题,并且在 WHERE 子句中使用它没有问题。
性能差异取决于平台。Sybase 和 DB2 将最多 8 个 BIT 打包到一个字节中(这里的存储并不重要),并动态映射 2 的幂,因此性能非常好。Oracle 在每个版本中做不同的事情,我看到建模者使用 CHAR(1) 而不是 BIT 来克服性能问题。MS 在 2005 年之前还不错,但他们在 2008 年打破了它,因为结果无法预测;所以简短的回答可能是将其实现为 CHAR(1)。
当然,假设您不会做一些愚蠢的事情,例如将 8 个单独的列打包到一个 TINYINT 中。这不仅是一个严重的规范化错误,而且是编码人员的噩梦。保持每列离散且具有正确的数据类型。
C. 多指标和可空列
这与(A)和(B)无关,并且独立于(A)和(B)。列正确的数据类型是什么,与您有多少以及它是否为 Nullable 是分开的。可空意味着(通常)该列是可选的。本质上,您还没有完成建模或规范化练习。功能依赖是模棱两可的。如果你完成了规范化练习,将没有 Nullable 列,没有可选列;它们要么明显存在于特定关系,要么不存在。这意味着使用超类型-子类型的普通关系结构。
当然,这意味着更多的表,但没有 Null。Enterprise DBMS 对更多表或更多连接没有问题,这就是它们的优化目标。规范化的数据库比非规范化或非规范化的数据库执行得更好,并且它们可以在没有“重构”的情况下进行扩展。您可以通过为每个子类型提供一个视图来简化使用。
如果您想了解有关此主题的更多信息,请查看此问题/答案。如果您在建模方面需要帮助,请提出一个新问题。在你的提问水平上,我建议你坚持使用 5NF。
D. 空值的表现
另外,如果性能对您很重要,则排除 Null。每个 Nullable 列都存储为可变长度;这需要对每一行/列进行额外处理。企业数据库对此类行使用“延迟”处理,以允许日志记录等在不妨碍固定行的情况下移动到队列中。特别是永远不要在索引中使用可变长度列(包括 Nullable 列):这需要在每次访问时解包。
E. 民意调查
最后,我认为这个问题的意义不是民意调查。公平地说,你会得到技术性的答案,甚至是意见,但民意调查是为了人气竞赛,而 SO 的响应者的技术能力涵盖的范围很广,所以最受欢迎的答案和技术上最正确的答案是在两个不同的光谱的末端。