昨天我想在 Oracle 表中添加一个布尔字段。但是,Oracle 中实际上没有布尔数据类型。这里有人知道模拟布尔值的最佳方法吗?谷歌搜索主题发现了几种方法
使用一个整数,不要费心为它分配除 0 或 1 以外的任何东西。
使用带有 'Y' 或 'N' 作为仅有的两个值的 char 字段。
使用带有 CHECK 约束的枚举。
经验丰富的 Oracle 开发人员是否知道首选/规范的方法?
昨天我想在 Oracle 表中添加一个布尔字段。但是,Oracle 中实际上没有布尔数据类型。这里有人知道模拟布尔值的最佳方法吗?谷歌搜索主题发现了几种方法
使用一个整数,不要费心为它分配除 0 或 1 以外的任何东西。
使用带有 'Y' 或 'N' 作为仅有的两个值的 char 字段。
使用带有 CHECK 约束的枚举。
经验丰富的 Oracle 开发人员是否知道首选/规范的方法?
我发现这个链接很有用。
这是强调每种方法的一些优点/缺点的段落。
最常见的设计是模仿 Oracle 的数据字典视图使用的许多类似布尔值的标志,选择“Y”代表真,“N”代表假。但是,要与主机环境(例如 JDBC、OCCI 和其他编程环境)正确交互,最好选择 0 代表 false 和 1 代表 true,以便它可以正确使用 getBoolean 和 setBoolean 函数。
基本上他们提倡方法 2,为了效率,使用
getBoolean()
具有检查约束的 0/1值(因为与 JDBC 等的互操作性)他们的例子:
create table tbool (bool char check (bool in (0,1)); insert into tbool values(0); insert into tbool values(1);`
Oracle 本身使用 Y/N 作为布尔值。为了完整起见,应该注意 pl/sql 具有布尔类型,只有表没有。
如果您使用该字段来指示是否需要处理记录,您可以考虑使用 Y 和 NULL 作为值。这使得索引非常小(读取速度快),占用的空间非常小。
要使用最少的空间,您应该使用限制为“Y”或“N”的 CHAR 字段。Oracle 不支持 BOOLEAN、BIT 或 TINYINT 数据类型,因此 CHAR 的一个字节尽可能小。
最好的选择是 0 和 1(作为数字 - 另一个答案建议 0 和 1 作为CHAR以提高空间效率,但这对我来说有点太扭曲了),使用 NOT NULL 和检查约束将内容限制为这些值。(如果您需要该列可以为空,那么它不是您正在处理的布尔值,而是具有三个值的枚举......)
0/1 的优点:
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”的优点:
另一张海报建议使用“Y”/null 来提高性能。如果您已经证明您需要性能,那么就足够公平了,但要避免,因为它会使查询不那么自然(some_column is null
而不是some_column = 0
),并且在左连接中,您会将错误与不存在的记录混为一谈。
带有检查约束的 1/0 或 Y/N。以太方式很好。我个人更喜欢 1/0,因为我在 perl 中做了很多工作,它使得对数据库字段进行 perl 布尔运算变得非常容易。
如果您想与 Oracle 的一位大佬深入讨论这个问题,请查看 Tom Kyte 对此有何评论
我完成大部分工作的数据库使用“Y”/“N”作为布尔值。通过该实现,您可以完成一些技巧,例如:
计算正确的行数:
SELECT SUM(CASE WHEN BOOLEAN_FLAG = 'Y' THEN 1 ELSE 0) FROM X
对行进行分组时,强制执行“如果一行为真,则全部为真”逻辑:
SELECT MAX(BOOLEAN_FLAG) FROM Y
相反,如果一行为假,则使用 MIN 强制分组为假。
通过将“布尔”列添加到 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
值并将接受的值限制为0
或1
。
在我们的数据库中,我们使用一个枚举来确保我们将它传递给 TRUE 或 FALSE。如果您使用前两种方法中的任何一种,那么很容易在没有经过适当设计的情况下开始为整数添加新含义,或者以具有 Y、y、N、n、T、t 的 char 字段结束, F,f 值,并且必须记住哪段代码使用哪个表以及它使用的是哪个版本的 true。