在每个数据库引擎中存储二进制标志/布尔值的最佳方法是什么?

xun*_*xun 6 flags database-design bitflags

我已经看到了一些可能的方法(在一些数据库引擎中,其中一些是同义词):

  1. TINYINT(1)
  2. BOOL
  3. BIT(1)
  4. ENUM(0,1)
  5. CHAR(0)NULL

应该注意PHP支持的所有主要数据库引擎,但是作为参考,如果还注意到其他引擎,它将会更好.

我要求的设计最适合阅读.例如,在WHERE条件中使用flag字段进行SELECT,或者使用GROUP BY进行标记.性能比存储空间重要得多(除非大小对性能有影响).

还有一些细节:

在创建表时,我不知道它是否会稀疏(如果大多数标志都打开或关闭),但我可以稍后更改表,所以如果有什么我可以优化,如果我知道,它应该是指出.

此外,如果每行只有一个标志(或几个),那么与许多(或许多)标志相比,它会产生影响.

顺便说一句,我在以下的某处读过以下内容:

使用boolean可能与使用tinyint做同样的事情,但是它具有在语义上传达你的意图的优点,这是值得的.

好吧,在我的情况下它并不值得,因为每个表都由我的应用程序中的类表示,并且所有内容都在类中明确定义并且记录良好.

Per*_*DBA 6

这个答案适用于ISO/IEC/ANSI标准SQL,包括更好的免费软件假装SQL.

第一个问题是你已经确定了两个类别,而不是一个,所以它们无法进行合理的比较.

A.第一类

(1)(4)和(5)包含多个可能的值,并且是一个类别.所有这些都可以在WHERE子句中轻松有效地使用.它们具有相同的存储空间,因此存储和读取性能都不是问题.因此,剩下的选择只是基于列的实际数据类型.

ENUM是非标准的; 更好或标准的方法是使用查找表; 然后,值在表中可见,而不是隐藏,并且可以由任何报表工具枚举.由于内部处理,ENUM的读取性能将受到轻微影响.

B.第二类

(2)和(3)是两值元素:真/假; 男/女; 死/活着.该类别与第一类不同.它在您的数据模型和每个平台中的处理方式都不同.BOOLEAN只是BIT的同义词,它们是同一个东西.合法(SQL-wise)所有符合SQL的平台都处理相同的问题,并且在WHERE子句中使用它没有问题.

性能的差异取决于平台.Sybase和DB2将最多8个BIT打包成一个字节(这里的存储不重要),并动态映射二次幂,因此性能非常好.Oracle在每个版本中都做了不同的事情,我看到建模者使用CHAR(1)而不是BIT来克服性能问题.MS在2005年之前很好,但他们已经打破了2008年,因为结果是不可预测的; 所以简短的回答可能是将其实现为CHAR(1).

当然,假设你不会做一些愚蠢的事情,比如把8个单独的列放到一个TINYINT中.这不仅是一个严重的规范化错误,对编码员来说也是一场噩梦.保持每列不连续且具有正确的数据类型.

C.多指标和可空栏目

这与(A)和(B)无关,并且独立于(A)和(B).列正确的数据类型是什么,与您拥有的数量以及它是否为Nullable是分开的.Nullable意味着(通常)该列是可选的.基本上你还没有完成建模或规范化练习.功能依赖性是模糊的.如果完成规范​​化练习,则不会有Nullable列,也不会有可选列; 要么它们显然存在于特定关系中,要么它们不存在.这意味着使用Supertype-Subtypes的普通Relational结构.

当然,这意味着更多的表,但没有空.Enterpise DBMS对于更多表或更多联接没有问题,这是他们优化的.规范化数据库比非规范化数据库或非规范化数据库执行得更好,并且可以在不"重新分解"的情况下扩展它们.您可以通过为每个子类型提供视图来简化使用.

如果您想了解有关此主题的更多信息,请查看此问题/答案.如果您需要建模方面的帮助,请提出一个新问题.在你的提问水平,我会建议你坚持使用5NF.

D.无效表现

另外,如果性能对您很重要,则排除Null.每个Nullable列都存储为可变长度; 这需要对每个行/列进行额外处理.企业数据库对这些行使用"延迟"处理,以允许日志记录等移动思想队列而不妨碍固定行.特别是从不在索引中使用可变长度列(包括Nullable列):需要在每次访问时解压缩.

E.民意调查

最后,我不认为这个问题的重点是民意调查.很公平,你会获得技术答案,甚至意见,但民意调查是针对人气竞赛,SO的响应者的技术能力涵盖范围很广,所以最流行的答案和技术上最正确的答案是两个不同的频谱的两端.

  • @RC.我没有链接,我有经验.Wiki尚未听说过它.具体的上述背景和其他一些背景,而不是所有背景的结果都是不可预测的; 如果您的代码在2005年表现良好.我已经发布了其他几个细节:删除溢出页面并损害集群索引上的所有性能等.随意阅读它们.修订版2中没有修复.至少在Rev 4之前,这些元素不可能被修复.MS用了3年时间来修复2005年. (2认同)