为什么在Microsoft SQL Server中使用“Y”/“N”而不是位字段?

时间:2008-11-02 05:56:34

标签: sql sql-server boolean

我正在研究由另一个暴徒开发的应用程序,并且对于数据库中所有布尔列使用char字段而不是bit而感到困惑。它使用“Y”表示true,使用“N”表示false(这些必须为大写)。然后,类型名称本身会出现一些模糊的名称,例如 ybln

由于很多原因,这非常令人讨厌,其中最重要的是它只是看起来非常不美观。

但也许我的愚蠢 - 为什么有人会这样做?它是数据库兼容性问题还是我不​​知道的一些设计模式?

任何人都可以启发我吗?

12 个答案:

答案 0 :(得分:18)

我经常在较旧的数据库模式中看到这种做法。我看到的一个优点是使用CHAR(1)字段可以提供超过Y / N选项的支持,例如“是”,“否”,“可能”。

其他海报提到可能已经使用过Oracle。我所提到的模式实际上部署在Oracle和SQL Server上。它将数据类型的使用限制为两个平台上可用的公共子集。

他们在Oracle和SQL Server之间的几个地方确实存在分歧,但在大多数情况下,他们使用数据库之间的通用模式来最小化支持两个数据库所需的开发工作。

答案 1 :(得分:11)

欢迎来到棕色地带。你继承了一个由老同学设计的应用程序。它不是一种设计模式(至少不是一种设计模式,它有一些好的东西),它是编码人员的遗迹,他们在数据类型有限的数据库上切割。没有重构数据库和大量的代码,咬紧牙关,直接通过它(并注意你的情况)!

答案 2 :(得分:10)

其他平台(例如Oracle)没有一点SQL类型。在这种情况下,它是NUMBER(1)和单个字符字段之间的选择。也许他们是从不同的平台开始,或者想要跨平台兼容性。

答案 3 :(得分:2)

我不喜欢Y / N char(1)字段作为位列的替代,但是表中的位字段有一个主要的缺点:你无法创建位列的索引或将其包含在复合索引中(至少不在SQL Server 2000中)。

当然,您可以讨论是否需要这样的索引。请参阅此request on a SQL Server forum

答案 4 :(得分:1)

原因如下(顺便说一下,它们不是很好的理由):

1)Y / N可以快速变为“X”(对于未知),“L”(对于可能)等等。 - 我的意思是我亲自与那些习惯于不收集的程序员一起工作正确的要求,他们刚开始使用Y / N作为一种“标志”,它可能需要扩展的迷信(他们应该使用int作为状态ID)。

2)“性能” - 但如上所述,如果SQL索引不够“选择性”,则排除SQL索引......只有2个可能值的字段永远不会使用该索引。

3)懒惰。 - 有时开发人员希望直接输出一些带有字母“Y”或“N”的可视化显示器以供人类阅读,他们不想自己转换它:)

我之前听过/见过的有三个不好的理由。

答案 5 :(得分:1)

我无法想象不能索引“BIT”列的任何缺点,因为根本不可能有足够的不同值来帮助执行查询。

我还想象在大多数情况下,BIT和CHAR(1)之间的存储差异可以忽略不计(CHAR a NCHAR?它存储16位,24位或32位unicode char吗?我们真的关心吗?)

答案 6 :(得分:1)

他们可能已经开始使用Microsoft SQl 6.5进行开发

当时,在现有数据库中添加一个位字段,数据到位是后方的皇家痛苦。位字段不能为空,因此将一个字段添加到现有表的唯一方法是创建一个临时表,其中包含目标表的所有现有字段和位字段,然后复制数据,填充位字段使用默认值。然后,您必须删除原始表并将临时表重命名为原始名称。抛出一些关键的关系,你有一个很长的脚本要写。

话虽如此,总有第三方工具来帮助完成这个过程。如果前一个开发人员选择使用char字段代替位字段,那么简而言之,原因可能是懒惰。

答案 7 :(得分:1)

这在大型机文件,COBOL等中非常常见。

如果你在表中只有一个这样的列,那在实践中并不是那么糟糕(没有真正的比特浪费);毕竟SQL Server不会让你说出自然的WHERE BooleanColumn,你必须说WHERE BitColumn = 1IF @BitFlag = 1而不是更自然的IF @BooleanFlag。当您有多个位列时,SQL Server将打包它们。如果使用区分大小写的排序规则,Y / N的情况应该只是一个问题,并且为了停止无效数据,总会有约束选项。

说了这么多,我个人的偏好是用于比特,经过仔细考虑后才允许NULL

显然,位列aren't a good idea in MySQL

答案 8 :(得分:0)

他们可能习惯使用Oracle,但没有正确读取SQL Server的可用数据类型。我自己就是这种情况(而且Y / N领域让我疯狂)。

答案 9 :(得分:0)

我看得更糟......

我有机会使用一个O / R映射器使用'true'和'false',因为它们可以干净地转换为Java布尔值。

此外,在诸如数据仓库的报告数据库上,DB是用户界面(尽管有基于元数据的报告工具)。您可能希望这样做,以帮助人们开发报告。此外,具有两个值的索引仍将由星型模式上的索引交叉操作使用。

答案 10 :(得分:0)

有时候这种怪癖与应用程序的关系比数据库更多。例如,处理PHP和MySQL之间的布尔值有点昙花一现,并且会产生非直观的代码。使用CHAR(1)字段和'Y'和'N'可以实现更易于维护的代码。

答案 11 :(得分:0)

无论如何,我都没有任何强烈的感情。我不能看到以一种方式做到另一种方式有什么好处。我知道哲学上比特字段更适合存储。我的现实是,我只有很少的数据库在一条记录中包含许多逻辑字段。如果我有很多,那么我肯定会想要比特字段。如果你只有一些我不认为这很重要。我目前使用的是Oracle和SQL服务器数据库,我从Cullinet的IDMS数据库(1980)开始,我们将各种数据打包到记录中,并担心比特和字节。虽然我仍然担心数据的大小,但我很久以前就不再担心一些问题了。