IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

CHAR ou VARCHAR2


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2005
    Messages : 26
    Par défaut CHAR ou VARCHAR2
    Bonjour à tous,

    Dans le cadre de l'optimisation d'une base Oracle, j'aurai une question concernant le type CHAR.
    Suite à une analyse de notre base, on nous conseille de remplacer tous nos CHAR par des VARCHAR2. Cependant, nous avons utilisés le type CHAR à bon escient, c'est à dire que nous ne l'avons utilisés que lorsque la valeur était toujours entièrement valorisée et non null. Dans ces cas là, est ce que l'utilisation du VARCHAR2 est utile ? Ou au contraire, comme je le pense, utiliser des VARCHAR2 prendra plus de place en base ?

    En fait je vois les choses comme ça :
    - CHAR(2) valorisé et non null prend 2 octets en base
    - VARCHAR2(2) valorisé et non null prend 2 octets en base + 2 octets pour stocker la longueur, donc 4 octets.
    Donc si cela est correct, CHAR(2) est mieux que VARCHAR(2) si la valeur est toujours valorisée.

    PS : je suis tombé sur ce lien ici mais je trouve que la réponse n'est pas assez précise, donc j'ai préféré reposer la question

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Non, vous avez tort.

    La longueur du char et du varchar existe et est stockée dans les deux types, sur deux octets.
    Mais votre char prendra toujours sa longueur maximale, dans votre exemple un char(2) fera toujours 4 octets là où un varchar(2) oscillera entre 3 et 4 octets.

    Si vous êtes sûr de votre donnée et que cette dernière fait toujours deux octets, les deux types fonctionneront de manière strictement identique.

    Et la petite citation de Tom Kytes (comparaison entre char(10) et varchar2(10), voir ici):
    If the field is in fact ALWAYS 10 bytes long, using a CHAR will not hurt -- HOWEVER, it will not help either.

    The only time I personally use a CHAR type is for CHAR(1). And that is only because its faster to type char(1) then varchar2(1) -- it offers no advantages.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2005
    Messages : 26
    Par défaut
    Merci beaucoup pour ta réponse rapide
    Je vais donc de ce pas changer tous mes CHAR en VARCHAR2

  4. #4
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut !

    Petite question au passage : quelqu'un sait pourquoi ?

    Il paraît que ce n'est pas le cas dans pleins d'autres SGBD... (la longueur n'est pas stockée pour les CHAR)

  5. #5
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par pacmann Voir le message
    Salut !

    Petite question au passage : quelqu'un sait pourquoi ?

    Il paraît que ce n'est pas le cas dans pleins d'autres SGBD... (la longueur n'est pas stockée pour les CHAR)
    Moi je ne crois pas que c'est vrai!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    SQL> create table t_char (a varchar2(2),b char(2));
     
    Table crÚÚe.
    SQL> insert into t_char values('aa','aa')
      2  ;
     
    1 ligne crÚÚe.
     
    SQL> commit;
     
    Validation effectuÚe.
     
    SQL> select dump(a),dump(b) from t_char;
     
    DUMP(A)
    -------------------------------------------------------------
    DUMP(B)
    -------------------------------------------------------------
    Typ=1 Len=2: 97,97
    Typ=96 Len=2: 97,97
     
    SQL> insert into t_char values('b','b');
     
    1 ligne crÚÚe.
     
    SQL> commit;
     
    Validation effectuÚe.
     
    SQL> select dump(a),dump(b) from t_char where a= 'b';
     
    DUMP(A)
    ---------------------------------------------------------
    DUMP(B)
    ---------------------------------------------------------
    Typ=1 Len=1: 98
    Typ=96 Len=2: 98,32
    Oracle concepts
    VARCHAR2 and VARCHAR Datatypes
    The VARCHAR2 datatype stores variable-length character strings. When you create a table with a VARCHAR2 column, you specify a maximum string length (in bytes or characters) between 1 and 4000 bytes for the VARCHAR2 column. For each row, Oracle stores each value in the column as a variable-length field unless a value exceeds the column's maximum length, in which case Oracle returns an error. Using VARCHAR2 and VARCHAR saves on space used by the table.

    For example, assume you declare a column VARCHAR2 with a maximum size of 50 characters. In a single-byte character set, if only 10 characters are given for the VARCHAR2 column value in a particular row, the column in the row's row piece stores only the 10 characters (10 bytes), not 50.
    Oracle compares VARCHAR2 values using nonpadded comparison semantics.


  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Pacmann faisait référence aux messages de SQLPro sur ce fil : http://www.developpez.net/forums/d68...d-int-varchar/

    Je pense que votre réponse est un peu hors-sujet

  7. #7
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Pacmann faisait référence aux messages de SQLPro sur ce fil : http://www.developpez.net/forums/d68...d-int-varchar/

    Je pense que votre réponse est un peu hors-sujet
    Mon réponse concerne en fait votre remarque
    ...
    Mais votre char prendra toujours sa longueur maximale, dans votre exemple un char(2) fera toujours 4 octets là où un varchar(2) oscillera entre 3 et 4 octets.

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Oui, en terme d'octets stockés sur disque.

    Ou alors j'ai mal compris ce que j'ai lu !

  9. #9
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Sur le disque le type char et varchar sont stockées de la même manière: une zone qui indique la longueur de 1 jusqu'au 3 octets suivie de la valeur. Si la longueur est inférieure ou égale à 250 Oracle va utiliser un octet sinon il y aura un octet fanion (flag byte) suivi de deux octets qui indiquent la longueur. C'est ce fait qui détermine Tom Kyte de dire que pour lui seules les types varchar2 et nvarchar2 sont à utiliser.
    Le lien (sur AskTom) que t'indique montre un exemple de dump d'un bloc des données où les deux types, char et varchar2 sont stockées de la même manière: 1 octet pour la longueur suivi des autres octets pour la valeur.

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    D'où la remarque de pacmann, qui demande pourquoi pour les char et les varchar2 la longueur est toujours stockée, car d'après sqlpro ce n'est pas le cas pour la plupart des autres sgbd, la longueur du char n'étant pas stockée.

  11. #11
    Expert confirmé
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 822
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    Si la longueur n'est pas stockée, il faut quand même stocker un indicateur pour dire si la valeur est nulle, alors pourquoi pas la longueur (=0 pour null) ?
    C'est aussi très pratique et performant pour parcourir des enregistrements de longueur variable dans un bloc. Au lieu d'un séparateur de champ, on met la longueur de chacun et on peut donc passer au suivant directement.
    Cordialement,
    Franck.

  12. #12
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par Waldar Voir le message
    D'où la remarque de pacmann, qui demande pourquoi pour les char et les varchar2 la longueur est toujours stockée, car d'après sqlpro ce n'est pas le cas pour la plupart des autres sgbd, la longueur du char n'étant pas stockée.
    Je ne sait pas pourquoi. Mais je viens de lire l'autre discutions et j'ai quelques remarques:
    • ce qui est valable pour un SGBD ne l'est pas forcement valable pour un autre donc il sera toujours mieux de préciser dans quel cas «*la chose est vraie*»
    • appeler Oracle «*un mauvais SGBD*» est un remarque plutôt «*politique*»
    • le mécanisme de gestion d'espace d'Oracle est de loin plus complexe et réduire l'analyse au comptage des octets est un approche un peu simpliste pour Oracle mais qui convient peut être aux «*bons bases des données*»


    PS. La zone qui précise la longueur prends entre 1 et 3 octets et non pas entre 1 et 2.

  13. #13
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut !

    appeler Oracle «*un mauvais SGBD*» est un remarque plutôt «*politique*»

    le mécanisme de gestion d'espace d'Oracle est de loin plus complexe et réduire l'analyse au comptage des octets est un approche un peu simpliste pour Oracle mais qui convient peut être aux «*bons bases des données*»
    Mnitu, je suis tout à fait d'accord !

    Visiblement, SQLPro est très Microsoft, et on a quand même l'impression que c'est l'une des grandes sources d'animosité envers Oracle, même s'il dit que c'est parce qu'Oracle ne respecte pas assez la norme SQL...
    Enfin à priori, il ne peut malgré tout pas se déchaîner sur Oracle comme il le fait sur MySQL, parce que si Oracle est populaire, c'est pas seulement à cause du string rose de Tom Kyte !
    Du coup, quand il y a une "faille" comme le coup du CHAR, il jubile un tout petit peut... (cf. toujours le même thread).
    (SQLPro, si tu nous entends, désolé !)

    Et c'est pour ça que je pose la question !
    Je suis moi aussi convaincu qu'Oracle n'a pas pris des choix délibérément naze dans l'implémentation, mais qu'il doit y avoir une explication rationnelle à tout ça...

    [EDIT]
    Par exemple, éventuellement, le genre de considérations proposée par pachot / franck

  14. #14
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Salut Pacmann,

    Bref, laissons à cote la guerre religieuse entre Oracle et Microsoft ; je regrette de m’avoir emballé.
    Il me semble que le vrai problème consiste à faire une analyse pour un SGBD et de penser qu'elle est valable pour tous les autres. SQLPro dans son exemple il discute le type INTEGER face aux types CHAR et VARCHAR. Le problème est qu’avec Oracle à la place du INTEGER les gens utilise NUMBER et ce type n’est pas stocké en format fixe comme un INTEGER. Il peut prendre entre 0 et 22 octets sur le disque et le nombre d’octets dépend de la valeur effectivement stockée.
    Je viens de poser la question à Tom on verra s’il y aura un réponse.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Différence entre char et varchar2
    Par wallace27 dans le forum SQL
    Réponses: 6
    Dernier message: 24/04/2015, 08h51
  2. Convertir VARCHAR2 en CHAR
    Par iiban dans le forum PL/SQL
    Réponses: 2
    Dernier message: 19/08/2009, 11h29
  3. 10g - Modification d'une colonne char en varchar2
    Par isa06 dans le forum Administration
    Réponses: 3
    Dernier message: 04/06/2007, 17h13
  4. varchar varchar2 char
    Par fantomas261 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 15/05/2007, 12h25
  5. Diff. de taille physique entre CHAR(1) et VARCHAR2(1)
    Par foster06 dans le forum Oracle
    Réponses: 6
    Dernier message: 20/10/2004, 11h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo