13

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

由于很多原因,使用它非常烦人,其中最重要的是它看起来完全不美观。

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

任何人都可以启发我吗?

4

12 回答 12

18

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

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

它们在 Oracle 和 SQL Server 之间的一些地方确实存在分歧,但在大多数情况下,它们在数据库之间使用通用模式,以最大限度地减少支持这两个数据库所需的开发工作。

于 2008-11-02T05:59:49.047 回答
12

欢迎来到棕地。您继承了由老学生设计的应用程序。它不是一种设计模式(至少不是一种有好处的设计模式),它是编码人员在数据类型有限的数据库上的残余。没有重构数据库和大量代码,咬紧牙关,通过它(并注意你的案例)!

于 2008-11-02T06:01:09.077 回答
10

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

于 2008-11-02T06:01:11.320 回答
2

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

当然,您可以讨论是否需要这样的索引。请在 SQL Server 论坛上查看此请求。

于 2008-11-02T08:09:28.160 回答
1

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

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

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

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

我以前听过/看过的所有 3 个不好的原因。

于 2008-11-02T12:30:31.597 回答
1

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

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

于 2008-11-02T12:34:35.317 回答
1

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

那时,在现有的数据表中添加一个位字段是一件非常痛苦的事情。位字段不能为空,因此向现有表添加一个的唯一方法是创建一个临时表,其中包含目标表的所有现有字段加上位字段,然后将数据复制过来,填充位字段具有默认值。然后您必须删除原始表并将临时表重命名为原始名称。加上一些外键关系,你就有了一个很长的脚本要写。

话虽如此,总有 3rd 方工具可以帮助完成这个过程。如果之前的开发者选择使用 char 字段代替 bit 字段,简单地说,原因可能是懒惰。

于 2008-11-02T14:13:03.700 回答
1

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

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

说了这么多,我个人的偏好是位,只有NULL在仔细考虑后才允许。

显然,位列在 MySQL 中不是一个好主意

于 2008-11-03T16:29:57.260 回答
0

他们可能习惯于使用 Oracle,并且没有正确阅读 SQL Server 的可用数据类型。我自己也正是这种情况(Y/N 字段让我抓狂)。

于 2008-11-02T06:04:02.143 回答
0

我见过更糟糕的...

我有机会使用的一个 O/R 映射器使用了“真”和“假”,因为它们可以干净地转换为 Java 布尔值。

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

于 2008-11-02T23:23:34.510 回答
0

有时,此类怪癖与应用程序的相关性比与数据库的相关性更高。例如,处理 PHP 和 MySQL 之间的布尔值有点偶然,并且会导致代码不直观。使用 CHAR(1) 字段和 'Y' 和 'N' 使得代码更易于维护。

于 2008-11-05T01:28:50.997 回答
0

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

于 2008-11-05T01:43:52.120 回答