使用带有check约束的枚举。
经验丰富的Orac"/>

Oracle中的布尔字段

Oracle中的布尔字段

Boolean Field in Oracle

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

  • 使用一个整数,只需不为它分配除0或1以外的任何东西。

  • 使用带有"y"或"n"的char字段作为仅有的两个值。

  • 使用带有check约束的枚举。

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


    我发现这个链接很有用。

    这是一段重点介绍了每种方法的一些优缺点。

    The most commonly seen design is to imitate the many Boolean-like
    flags that Oracle's data dictionary views use, selecting 'Y' for true
    and 'N' for false. However, to interact correctly with host
    environments, such as JDBC, OCCI, and other programming environments,
    it's better to select 0 for false and 1 for true so it can work
    correctly with the getBoolean and setBoolean functions.

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

    • 值为0/1(由于与JDBC的getBoolean()等的互操作性),带有检查约束
    • 字符类型(因为它使用的空间小于数字)。

    他们的例子是:

    1
    2
    3
    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不支持布尔、位或tinyint数据类型,因此char的单字节尽可能小。


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

    0/1的优点:

    • 语言独立。"如果每个人都用的话,Y’和N’就可以了。但他们没有。在法国,他们使用"O"和"N"(我亲眼看到)。我还没有在芬兰编程,看他们是否在那里使用"e"和"k"——毫无疑问,他们比这更聪明,但你不能确定。
    • 与广泛使用的程序设计语言(C,C++,Perl,JavaScript)一致
    • 在应用程序层(如休眠)中更好地发挥作用
    • 例如,可以得到更简洁的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"(零)以提高性能。如果您已经证明您需要性能,那么就足够公平,但要避免这样做,因为它会使查询变得不自然(some_column is null而不是some_column = 0),并且在左连接中,您会将错误与不存在的记录混为一谈。


    1/0或是带有检查约束的Y/N。乙醚路很好。我个人更喜欢1/0,因为我在Perl中做了很多工作,这使得在数据库字段上执行Perl布尔操作非常容易。

    如果你想和一个神谕首领霍克斯深入讨论这个问题,看看汤姆·基特在这里要说些什么。


    我在数据库上做的大部分工作都是将"y"/"n"用作布尔值。通过这种实现,您可以获得一些技巧,例如:

  • 计算为真的行数:从x中选择SUM(布尔值_flag='y'时为1,否则为0)

  • 分组行时,强制执行"如果一行为真,则全部为真"逻辑:从y中选择max(布尔值_标志)相反,如果一行为假,则使用min强制分组为假。


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

    1
    2
    3
    4
    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


    在我们的数据库中,我们使用一个枚举来确保传递它是真的还是假的。如果您使用前两种方法中的任何一种,那么很容易要么开始向整数添加新的含义,而不进行适当的设计,要么结束时使用具有y、y、n、n、t、t、f、f值的char字段,并且必须记住代码的哪个部分使用哪个表以及使用哪个版本的true。


    推荐阅读