2008-08-27 13 views
135

Ayer quise agregar un campo booleano a una tabla de Oracle. Sin embargo, en realidad no existe un tipo de datos booleanos en Oracle. ¿Alguien aquí sabe la mejor manera de simular un booleano? Googlear el tema descubrió varios enfoquesCampo booleano en Oracle

  1. utilizar un número entero y simplemente no se molestan en la asignación de otra cosa que no sea 0 o 1 a la misma.

  2. Utilice un campo de caracteres con 'S' o 'N' como los únicos dos valores.

  3. Usa una enumeración con la restricción CHECK.

¿Los desarrolladores de Oracle con experiencia saben qué enfoque es preferible/canónico?

+181

Ojalá Oracle tuviese un tipo de datos de "pared" para poder aplastar mi cabeza cuando use booleanos. – Greg

Respuesta

76

Encontré this enlace útil.

Este es el párrafo que resalta algunos de los pros/contras de cada enfoque.

El diseño que más se ve es imitar las muchas Boole- como banderas que los datos de Oracle vistas diccionario de uso, seleccionando 'Y' para la verdadera y 'N' para falso. Sin embargo, para interactuar correctamente con entornos host , como JDBC, OCCI y otros entornos de programación, es mejor seleccionar 0 para falso y 1 para verdadero, de modo que pueda funcionar correctamente con las funciones getBoolean y setBoolean.

Básicamente Ellos abogan método número 2, por el bien de la eficiencia, el uso de

  • valores de 0/1 (debido a la interoperabilidad con JDBC de getBoolean() etc.) con una restricción de comprobación
  • un tipo de CHAR (porque usa menos espacio que NUMBER).

Su ejemplo:

create table tbool (bool char check (bool in (0,1)); 
insert into tbool values(0); 
insert into tbool values(1);` 
+31

No recomiendo usar 'N' e 'Y' ya que depende del idioma. Los anglófonos a veces olvidan que la mayor parte del mundo no representa el concepto de verdad con la letra Y. Por el contrario, el significado de 0 y 1 es constante a través de las barreras del lenguaje. –

+6

0 y 1 como valores booleanos no son consistentes con la informática: los lenguajes de tipo shell script tienden a tener 0 como éxito y no cero a error, mientras que los lenguajes de tipo C tienden a tener 0 como error y no cero como éxito . – Phil

+40

Como valores * booleanos *, son impersonales. Los códigos de retorno de proceso no son valores booleanos. –

1

En nuestras bases de datos utilizamos una enumeración que asegura que la pasemos VERDADERO o FALSO. Si lo hace de las dos primeras maneras, es demasiado fácil comenzar a agregar un nuevo significado al entero sin pasar por un diseño apropiado, o terminar con ese campo de caracteres que tiene Y, y, N, n, T, t, F, f valores y tener que recordar qué sección de código usa qué tabla y qué versión de verdad está usando.

26

utilizar la menor cantidad de espacio que debe utilizar un campo CHAR limitado a 'Y' o 'N'. Oracle no es compatible con los tipos de datos BOOLEAN, BIT o TINYINT, por lo que el byte de CHAR es tan pequeño como se puede obtener.

4

La base de datos que hice la mayor parte de mi trabajo en 'Y'/'N' usado como booleanos.Con esa aplicación, se puede tirar algunos trucos como:

  1. el número de filas que son verdaderas:
    SELECT SUM (CASE CUANDO BOOLEAN_FLAG = 'Y' then 1 else 0) de X

  2. Cuando agrupar filas, hacer cumplir "Si una fila es verdadera, entonces todas son verdaderas" lógica:
    SELECCIONE MAX (BOOLEAN_FLAG) DE Y
    Por el contrario, use MIN para forzar la agrupación falsa si una fila es falsa.

+4

, de hecho, los ejemplos mostrados son útiles para el enfoque 0/1 también, y, en mi humilde opinión, más rápido. – igorsantos07

5

O bien 1/0 o S/N con una restricción de verificación en él. el éter está bien. Personalmente prefiero 1/0 ya que trabajo mucho en Perl, y hace que sea muy fácil hacer operaciones booleanas en campos de base de datos.

Si quieres realmente una discusión a fondo de esta cuestión con una de peces gordos oráculos, echa un vistazo a lo que Tom Kyte tiene que decir acerca de este Here

+0

1/0 se dice que es "menos eficiente en memoria" pero ... También me gusta más (e hibernación aparentemente requiere 1/0 para un booleano) – rogerdpack

+0

1/0 es el valor predeterminado de Hibernate para un booleano pero puede definir cualquier medida personalizada mapeo que te gusta –

+0

@rogerdpack eso es porque un campo char es de 1 byte, o 2 bytes para nchar, donde dependiendo de cómo se define un número puede ser de 1 a 22 bytes – MikeT

28

propio Oracle utiliza S/N de valores booleanos. Para completar, debe tenerse en cuenta que pl/sql tiene un tipo booleano, solo las tablas que no lo hacen.

Si está utilizando el campo para indicar si el registro debe procesarse o no, podría considerar usar Y y NULL como valores. Esto lo convierte en un índice muy pequeño (de lectura rápida) que ocupa muy poco espacio.

+7

+1 Buen punto acerca de las tablas y vistas internas de Oracle usando Y/N. Si Oracle lo hace de esa manera, ¡debe estar bien! :) –

+0

¿Puedes explicar cómo Y y NULL hacen un pequeño índice en comparación con Y y N? – styfle

+6

Los NULL no están indexados en Oracle, por lo que si su índice contiene unos pocos caracteres Y, pero principalmente NULL, tendrá un índice muy pequeño. –

19

La mejor opción es 0 y 1 (como números - otra respuesta sugiere 0 y 1 como CHAR para la eficiencia del espacio pero eso es demasiado retorcido), usando NOT NULL y una restricción de verificación para limitar el contenido a esos valores. (Si necesita la columna de ser anulable, entonces no es un valor lógico que está tratando con una enumeración, pero con tres valores ...)

Ventajas de 0/1:

  • lenguaje independiente. 'Y' y 'N' estarían bien si todos lo usaran. Pero ellos no. En Francia usan 'O' y 'N' (he visto esto con mis propios ojos). No he programado en Finlandia para ver si usan 'E' y 'K' allí; sin duda son más inteligentes que eso, pero no se puede estar seguro.
  • Congruente con la práctica en lenguajes de programación ampliamente utilizados (C, C++, Perl, Javascript)
  • Se juega mejor con la capa de aplicación, p. Hibernate
  • conduce a más sucinta SQL, por ejemplo, para averiguar cuántos plátanos están listos para comer select sum(is_ripe) from bananas en lugar de select count(*) from bananas where is_ripe = 'Y' o incluso (puaj) select sum(case is_ripe when 'Y' then 1 else 0) from bananas

Ventajas de la 'Y'/'N':

  • ocupa menos espacio que los 0/1
  • es lo que sugiere Oracle, por lo que podría ser lo que algunas personas están más acostumbrados a

Otro póster sugirió 'Y'/null para aumentar el rendimiento.Si ha probado que necesita el rendimiento, entonces es suficiente, pero evite lo contrario, ya que hace que las consultas sean menos naturales (some_column is null en lugar de some_column = 0) y en una combinación a la izquierda confundirá la falsedad con registros inexistentes.

+3

En estos días, muchos booleanos son TriState, es decir, verdaderos, falsos y desconocidos. que encaja perfectamente con la idea nula de la base de datos. simplemente porque muchas veces no se ha dado ninguna respuesta es de vital importancia – MikeT

+1

Sí, puede ser necesario verdadero-falso-desconocido, aunque si fuera exigente (lo cual soy), diría que no debería describirse como una Boolean, porque no lo es. –

+2

si va a ser tan quisquilloso, entonces puede hacer el mismo argumento para cada tipo de datos. como en definición estricta entero, doble (supongo que debería decir doble longitud complementan punto flotante), Binario, cadena, etc. todos suponen que se proporciona un valor pero las implementaciones de base de datos siempre agregan una opción de valor nulo Booleano no es diferente – MikeT

2

Un ejemplo de trabajo para poner en práctica la respuesta aceptada mediante la adición de una columna "booleano" a una tabla existente en una base de datos Oracle (usando number tipo):

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)) 
); 

Esto crea una nueva columna en my_table_name llamada my_new_boolean_column con valores predeterminados de 0. La columna no aceptará los valores NULL y restringe los valores aceptados a 0 o 1.

Cuestiones relacionadas