web-dev-qa-db-fra.com

Absence de type de données Bit pour les colonnes de table dans Oracle

Je travaille en tant que développeur dans une petite équipe de développement, et quelque chose m'a agacé au point où j'ai décidé d'agir ...

Oracle ne prend pas en charge les types de données Bit - ni même tout autre élément ayant un sens évident dans les scénarios vrai/faux. Sans me laisser décourager, cependant, avant de rejoindre l'équipe, mes ancêtres ont décidé d'utiliser les champs char (1) à la place, en utilisant une lettre spécifique pour indiquer oui/vrai. Malheureusement, notre application est utilisée par de nombreuses personnes partout dans le monde et, pour des raisons qui contredisent franchement toutes mes tentatives de compréhension, la valeur utilisée varie selon la localisation. 

Oui, je sais que c'est totalement inutile pour les valeurs du back-end que l'utilisateur ne voit jamais - cependant ...

J'ai remarqué que cette pratique semble se perpétuer dans de nouveaux développements, ce qui me frappe comme un fou. Je pense donc à proposer Number (1,0) pour cela à la place. comme vrai/oui ...

Question simple - quelqu'un peut-il penser à une raison pour laquelle cela pourrait être une mauvaise idée?

Pendant que nous y sommes, quelqu'un sait-il pourquoi Oracle ne prend pas en charge un type booléen simple? N'est-ce pas une commission de GLARING?

Salut à l'avance,

Martin.

25
Martin Milan

Je préfère le caractère (1) au numéro (1), car avec un choix raisonnable de caractères, il est évident quel caractère a quelle signification booléenne.

Bien sûr, vous devriez combattre toutes les variantes, en choisir une et en garantir l’utilisation en appliquant des contraintes de vérification aux colonnes.

Bien qu'il soit probablement trop tard dans votre cas, la génération du schéma à partir d'un autre outil tient souvent compte au moins du problème de cohérence. Personnellement, je préfère hiberner à cette fin, mais cela dépend de la situation.

Et bien sûr, c'est une obmission flagrante. Pour aggraver les choses, PL/SQL a un booléen, mais vous ne pouvez pas l'utiliser dans les instructions SQL.

11
Jens Schauder

Utilisez un CHAR (1) et une contrainte pour autoriser uniquement '1' et '0'.

...

col CHAR(1),
CONSTRAINT cons_atable_col1 CHECK (col1 IN ('1','0'))
26
Samuel

Je ne suis pas un anglais, alors j'ai tendance à utiliser soit 1 et 0, soit «1» et «0». Utiliser 'Y' et 'N' n'a pas de sens si vous ne codez pas en anglais (oui, le codage en langue maternelle existe). Utiliser 'SI' et 'NO' ou 'S' et 'N' n'a pas l'air professionnel (tout comme nommer des variables avec des lettres accentuées). Les zéros et les zéros, au contraire, sont assez classiques si vous avez codé en C, PHP ou JavaScript. Dans tous les cas, j'ajoute toujours la contrainte appropriée pour interdire tout autre caractère. Hormis les questions subjectives, je ne pense pas que le choix de CHAR ou NUMBER présente un gain de performance notable. J'aime les chiffres un peu plus parce que je n'ai pas besoin de les citer :)

Je conviens que c'est une omission flagrante, mais j'ai lu des discussions très animées sur le sujet dans certains forums Oracle; c'est une sorte de problème religieux. Certains affirment que les booléens appartiennent à des types de données d'application et n'ont pas de place dans le noyau de la base de données. Honnêtement, je crois que c’est un de ceux que nous avons si longtemps passés sans lui que nous aurions mieux dit de dire que c’était à dessein.

Au fait, MySQL a le type BOOLEN mais c'est un synonyme de TINYINT (1) donc il est égal à 1 et 0; ce qui est bien, car il a également les constantes TRUE et FALSE qui évaluent à 1 et 0.

16
Álvaro González

Voici un Ask Tom discussion sur le sujet. Donne une vue centrée sur Oracle du problème.

En ce qui concerne le stockage, char (1) est un peu plus efficace (sans jeu de mots):

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
8
DCookie

Selon ce guide Oracle, vous devez utiliser NUMBER (3). Fou, mais vrai.

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

3
GilesDMiddleton

Le nombre (1) n'est pas meilleur que le caractère (1). Surtout si ce sera en plus du caractère existant (1). Cela ne fera qu'ajouter à la confusion.

FWIW, Oracle dans les vues internes (comme USER_TAB_COLUMNS) utilise varchar2 (3) (YES et NO). Je ne sais pas si elles sont cohérentes à 100% ici, cependant.

2
Thilo

Oracle utilise en interne des "bits" (pas un type de données en soi) dans différentes vues du dictionnaire de données. 

Par exemple, la vue dba_users a:

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

ce qui montre un moyen de contourner cela d'une certaine manière. Si vous n'avez pas à modifier souvent les bits "booléens", vous pouvez utiliser la même approche qu'Oracle depuis Oracle 6 (au moins). Créez une table avec une colonne NUMBER et une vue qui cache la complexité des opérations BITAND.

ps. Par ailleurs, Oracle JDBC a un type de données "Bit" https://docs.Oracle.com/cd/E16338_01/appdev.112/e13995/Oracle/jdbc/OracleTypes.html#BIT ainsi que vous sais déjà que PL/SQL a Boolean. Bien que cela ne vous aide probablement pas beaucoup. Voir l'approche BITAND ci-dessus si elle convient à votre cas.

0
Tagar