149

昨天我想在 Oracle 表中添加一个布尔字段。但是,Oracle 中实际上没有布尔数据类型。这里有人知道模拟布尔值的最佳方法吗?谷歌搜索主题发现了几种方法

  1. 使用一个整数,不要费心为它分配除 0 或 1 以外的任何东西。

  2. 使用带有 'Y' 或 'N' 作为仅有的两个值的 char 字段。

  3. 使用带有 CHECK 约束的枚举。

经验丰富的 Oracle 开发人员是否知道首选/规范的方法?

4

8 回答 8

84

我发现这个链接很有用。

这是强调每种方法的一些优点/缺点的段落。

最常见的设计是模仿 Oracle 的数据字典视图使用的许多类似布尔值的标志,选择“Y”代表真,“N”代表假。但是,要与主机环境(例如 JDBC、OCCI 和其他编程环境)正确交互,最好选择 0 代表 false 和 1 代表 true,以便它可以正确使用 getBoolean 和 setBoolean 函数。

基本上他们提倡方法 2,为了效率,使用

  • getBoolean()具有检查约束的 0/1(因为与 JDBC 等的互操作性)
  • 一种CHAR(因为它使用的空间比 NUMBER 少)。

他们的例子:

create table tbool (bool char check (bool in (0,1));
insert into tbool values(0);
insert into tbool values(1);`
于 2008-08-27T13:23:06.247 回答
28

Oracle 本身使用 Y/N 作为布尔值。为了完整起见,应该注意 pl/sql 具有布尔类型,只有表没有。

如果您使用该字段来指示是否需要处理记录,您可以考虑使用 Y 和 NULL 作为值。这使得索引非常小(读取速度快),占用的空间非常小。

于 2008-10-21T19:23:39.050 回答
25

要使用最少的空间,您应该使用限制为“Y”或“N”的 CHAR 字段。Oracle 不支持 BOOLEAN、BIT 或 TINYINT 数据类型,因此 CHAR 的一个字节尽可能小。

于 2008-08-27T13:29:07.233 回答
19

最好的选择是 0 和 1(作为数字 - 另一个答案建议 0 和 1 作为CHAR以提高空间效率,但这对我来说有点太扭曲了),使用 NOT NULL 和检查约束将内容限制为这些值。(如果您需要该列可以为空,那么它不是您正在处理的布尔值,而是具有三个值的枚举......)

0/1 的优点:

  • 语言无关。如果每个人都使用它,“Y”和“N”就可以了。但他们没有。在法国,他们使用“O”和“N”(我亲眼目睹了这一点)。我没有在芬兰编程看看他们是否在那里使用“E”和“K”——毫无疑问他们比那更聪明,但你不能确定。
  • 与广泛使用的编程语言(C、C++、Perl、Javascript)的实践一致
  • 与应用程序层(例如 Hibernate)配合得更好
  • 导致更简洁的 SQL,例如,找出有多少香蕉可以吃select sum(is_ripe) from bananas而不是select count(*) from bananas where is_ripe = 'Y'甚至 (yuk)select sum(case is_ripe when 'Y' then 1 else 0) from bananas

“Y”/“N”的优点:

  • 占用空间小于 0/1
  • 这是甲骨文建议的,所以可能是一些人更习惯的

另一张海报建议使用“Y”/null 来提高性能。如果您已经证明您需要性能,那么就足够公平了,但要避免,因为它会使查询不那么自然(some_column is null而不是some_column = 0),并且在左连接中,您会将错误与不存在的记录混为一谈。

于 2013-05-06T12:25:21.113 回答
5

带有检查约束的 1/0 或 Y/N。以太方式很好。我个人更喜欢 1/0,因为我在 perl 中做了很多工作,它使得对数据库字段进行 perl 布尔运算变得非常容易。

如果您想与 Oracle 的一位大佬深入讨论这个问题,请查看 Tom Kyte 对此有何评论

于 2008-08-31T17:11:47.073 回答
4

我完成大部分工作的数据库使用“Y”/“N”作为布尔值。通过该实现,您可以完成一些技巧,例如:

  1. 计算正确的行数:
    SELECT SUM(CASE WHEN BOOLEAN_FLAG = 'Y' THEN 1 ELSE 0) FROM X

  2. 对行进行分组时,强制执行“如果一行为真,则全部为真”逻辑:
    SELECT MAX(BOOLEAN_FLAG) FROM Y
    相反,如果一行为假,则使用 MIN 强制分组为假。

于 2008-08-27T13:36:23.533 回答
2

通过将“布尔”列添加到 oracle 数据库中的现有表(使用number类型)来实现接受的答案的工作示例:

ALTER TABLE my_table_name ADD (
my_new_boolean_column number(1) DEFAULT 0 NOT NULL
CONSTRAINT my_new_boolean_column CHECK (my_new_boolean_column in (1,0))
);

my_table_name这将在调用中创建一个my_new_boolean_column默认值为 0 的新列。该列将不接受NULL值并将接受的值限制为01

于 2016-10-03T21:57:09.773 回答
1

在我们的数据库中,我们使用一个枚举来确保我们将它传递给 TRUE 或 FALSE。如果您使用前两种方法中的任何一种,那么很容易在没有经过适当设计的情况下开始为整数添加新含义,或者以具有 Y、y、N、n、T、t 的 char 字段结束, F,f 值,并且必须记住哪段代码使用哪个表以及它使用的是哪个版本的 true。

于 2008-08-27T13:22:06.610 回答