代码之家  ›  专栏  ›  技术社区  ›  Martin Milan

Oracle缺少表列的位数据类型

  •  25
  • Martin Milan  · 技术社区  · 14 年前

    我是一个小开发团队的开发人员,有些事情让我很恼火,以至于我决定采取行动……

    Oracle不支持位数据类型,或者实际上不支持在真/假情况下有明显意义的任何其他数据类型。然而,在我加入这个团队之前,我的祖先决定使用char(1)字段,用一个特定的字母来表示是/真。不幸的是,我们的应用程序已经被世界各地的人们所使用,而且由于坦率地拒绝我所有的理解尝试的原因,使用的价值因本地化而异。

    是的,我知道对于用户从未见过的后端值来说,这是完全不必要的-但是…

    我注意到,这种做法似乎正在被推进到新的发展中,这让我觉得很疯狂,所以我想提出数字(1,0)来代替它-0被认为是错的/不的,任何其他的都被解释为真的/是的…

    简单的问题-有人能想到这可能是个坏主意的原因吗?

    当我们讨论它时,有人知道为什么Oracle不支持简单的布尔类型吗?这不是一个令人目眩的命令吗?

    期待喝彩,

    马丁。

    9 回复  |  直到 8 年前
        1
  •  11
  •   Jens Schauder    14 年前

    我更喜欢字符(1)而不是数字(1),因为在一些合理的字符选择中,很明显哪个字符具有哪个布尔值的含义。

    当然,您应该与所有不同的变量作斗争,选择一个变量,并通过对列设置检查约束来确保它的使用。

    尽管在您的案例中可能已经晚了,但是从另一个工具生成模式通常至少要注意一致性问题。我个人更喜欢冬眠,但这是非常具体的情况。

    当然,这是一个显而易见的目标。更糟糕的是,pl/sql有一个布尔值,但不能在SQL语句中使用它。

        2
  •  26
  •   Samuel    14 年前

    使用char(1)和约束仅允许“1”和“0”。

    col CHAR(1),
    CONSTRAINT cons_atable_col1 CHECK (col1 IN ('1','0'))
    
        3
  •  16
  •   Álvaro González    9 年前

    我不是英国人,所以我倾向于使用1和0或“1”和“0”。如果不是用英语编码,使用“y”和“n”就没什么意义了(是的,确实存在母语编码)。使用“si”和“no”或“s”和“n”看起来不专业(就像用重音字母命名变量一样)。相反,如果您使用C、PHP或JavaScript编码,那么1和0是相当标准的。在任何情况下,我总是添加适当的约束来禁止任何其他字符。除了主观问题,我认为在选择字符或数字时没有明显的性能提升。我更喜欢数字,因为我不需要引用它们:)

    我同意这是一个明显的遗漏,但我已经在一些甲骨文论坛上认真阅读了关于这个问题的激烈讨论;这是一种宗教问题。一些人声称布尔值属于应用程序数据类型,在数据库核心中没有位置。老实说,我相信这是我们长期以来没有的其中之一,所以我们最好说这是有目的的事情。

    顺便说一下,MySQL有一个布尔类型,但它是tinyint(1)的同义词,所以它最终等于1和0;这很好,因为它也有常量true和false,值分别为1和0。

        4
  •  8
  •   DCookie    14 年前

    这里是一个 Ask Tom 讨论这个话题。提供了一个以Oracle为中心的关于这个问题的视图。

    至于存储,char(1)实际上更有效(没有双关语的意思):

    SQL> CREATE TABLE xx (c CHAR(1), n NUMBER);
    
    Table created
    
    SQL> insert into xx values('T', 1);
    
    1 row inserted
    
    SQL> select dump(c), dump(n) from xx;
    
    DUMP(C)             DUMP(N)
    ------------------- -------------
    Typ=96 Len=1: 84    Typ=2 Len=2: 193,2
    
        5
  •  3
  •   GilesDMiddleton    9 年前

    根据这个Oracle指南,您应该使用数字(3)。疯狂,但真实。

    http://docs.oracle.com/cd/B19306_01/gateways.102/b14270/apa.htm

        6
  •  2
  •   Thilo    14 年前

    数字(1)不优于字符(1)。特别是如果它将是现有字符(1)的补充。这只会增加混乱。

    fwiw,Oracle在内部视图(如用户选项卡列)中使用varchar2(3)(是和否)。但不确定它们是否100%一致。

        7
  •  0
  •   SomeCoder    9 年前

    这个问题很古老,但在使用最新版本的Oracle之前,它仍然是一个有效的问题。

    我会这样解决这个问题: 创建一个表,其中包含true/false加上本地化显示文本f.e的可能值。 关键词: itemno itemtext itemtext_de itemtext_fe… 0错误错误错误 1真瓦赫

    也可以选择,而不是选择真/假,等等。

    然后将一个foreigh键添加到这个表的列中。这样,您只有有效的值,并且它们不会随本地化而更改。

    另一个好的解决方案imho是对数据列使用检查约束。如果您的值在同一数据库/列中可能不同,则此OFC不起作用,这取决于客户机的本地化。

    alter table tblLocations add flag number CONSTRAINT <constraintname> CHECK (flag IN (1,0));

        8
  •  0
  •   Tagar    8 年前

    Oracle在不同的数据字典视图中内部使用“位”(本身不是数据类型)。

    例如,“DBA用户”视图具有:

    ..
            , DECODE (BITAND (u.spare1, 128), 128, 'YES', 'NO')
    ..
            , DECODE (BITAND (u.spare1, 256), 256, 'Y', 'N')
    ..
    

    这显示了一种解决这一问题的方法。如果您不需要经常修改“布尔”位,那么您可以使用与Oracle6以来相同的方法(至少)。创建一个带有数字列的表,以及一个隐藏位和操作复杂性的视图。

    另一方面,OracleJDBC有一个“位”数据类型 https://docs.oracle.com/cd/E16338_01/appdev.112/e13995/oracle/jdbc/OracleTypes.html#BIT 正如您已经知道的,pl/sql具有布尔值。尽管这可能对你没什么帮助。如果它符合您的情况,请参阅上面的bitand方法。

        9
  •  -1
  •   Artem.Borysov    9 年前

    https://docs.oracle.com/cd/e17952_01/refman-5.5-en/char.html

    正如迪考基所说,char(1)更有效。 因为varchar2(varchar)empty包含1个字节,但是当我们存储1个字符时,空的1个字节大小+和字符1字节大小-->2字节需要在varchar中存储1个字符

    enter image description here

    正如迪考基所说,char(1)更有效。 因为varchar2(varchar)empty包含1个字节,但是当我们存储1个字符时,空的1个字节大小+和字符1字节大小-->2字节需要在varchar中存储1个字符