Partage
  • Partager sur Facebook
  • Partager sur Twitter

[PostgreSQL]Types les plus courants

    11 novembre 2010 à 23:24:49

    Bonsoir,
    Je me met au PostgreSQL, et j'aurais aimé savoir quels types étaient les plus utilisés et adaptés.
    J'ai trouvé une liste, mais beaucoup se ressemblent et j'aimerais faire un choix pour n'avoir à en utiliser que certains, par exemple:
    *Boolean (Comment ca marche, il prend les valeurs True/False, 'True'/'False', 0/1 ... ?)
    *Integer
    *Serial (Il s'auto-incrémente, mais si par exemple on lui assigne tout de même une valeur il la prend quand même ?)
    *Double precision (pour les réels, je sais pas si c'est le mieux)
    *Text / Character / Character varying (Lequel choisir pour les textes ?)
    *Timestamp (il renvoie quoi, et comment peut on l'analiser?)
    Aussi dans phpPgAdmin, quand on crée une table à droite d type de la colonne on peut choisir [] pour cette colonne, je ne vois pas ce que c'est (peut être pour rendre optionnel cette colonne, mais il y a déjà une case à cocher "NOT NULL" ...)

    Merci de m'éclairer
    • Partager sur Facebook
    • Partager sur Twitter
      11 novembre 2010 à 23:50:37

      La question n'a pas vraiment de sens. On utilise pas un type parce qu'il est "courant", on l'utilise parce qu'il est approprié. On utilise le bon type, point.

      Pour tes questions sur les types, dans la plupart des cas, tu peux tester toi-même (je pense notamment à boolean ou bien serial). Ça prend 30 secondes et tu comprends facilement.

      Concernant les nombres flottants, si la précision est importante, il vaut mieux utiliser le type decimal / numeric (money pour l'argent, etc.).

      Pour les types de chaînes de caractères, ça dépend. Character est le seul qui est fixe : char(5), par exemple, prend toujours une chaîne de 5 caractères (attention, caractères comme a, è, etc., pas octets). Si on lui passe une chaîne plus longue, PostgreSQL la tronque, si la chaîne est plus courte, elle est remplie par des espaces.
      Varchar et text sont semblables. La seule différence, c'est qu'on peut imposer une limite à varchar. Les chaînes de caractères plus longues que cette limite sont tronquées (mais celles plus courtes ne sont pas remplies d'espaces, donc gain d'octets sur le disque).
      Text n'a, en théorie, pas de limite (il doit bien y en avoir une en pratique).

      Concernant le timestamp, c'est le moyen utilisé pour géré les heures, au format YYYY-MM-DD HH:II:SS.LLLLLL (Les L sont les millisecondes).

      Pour finir, les [] signifient un array, tout bêtement. Avec PostgreSQL, une colonne peut un array d'un type spécifique.

      Tu peux regarder la doc pour plus d'informations sur les types (et sur tout le reste).
      • Partager sur Facebook
      • Partager sur Twitter
        11 novembre 2010 à 23:59:11

        Merci de ta réponse, j'entendais bien sûr les types les plus adaptés et non les plus utilisés. Pour le timestamp, il ne peut donc être utilisé que sous ce format et il n'est pas modulable (comme la fonction time en PHP) sinon en faisant une fonction spéciale?
        Pour finir, je n'ai pas compris l'histoire des arrays sur une colonne ... Sans doute je n'en aurait pas besoin mais bon. Et si on peut le faire avec phpPgAdmin, on peut le faire dans le CREATE TABLE, il faut juste rajouter les [] après le type de colonne ?

        Edit: une derniere chose:
        dans phpPgAdmin j'ai une case précochée "WITHOUT OIDS" quand je crée une table, que signifie elle ?
        • Partager sur Facebook
        • Partager sur Twitter
          12 novembre 2010 à 0:04:14

          La fonction time() est une erreur de PHP (et une grosse, malheureusement). Un timestamp unix ne devrait jamais être utilisé pour représenter une date, il y a déjà un type approprié qui existe : timestamp.

          On peut déjà tout faire avec un vrai timestamp (et mieux qu'avec un timestamp unix), inutile de se compliquer la vie avec des aberrations de PHP.

          Sinon, pour les arrays, c'est comme en PHP :
          <?php
          $array = array();
          $array[0] = 'hello';
          $array[1] = 'world';
          


          Ceci crée un array en PHP. C'est le même principe en SQL :
          vsavard_db=> CREATE TABLE test_array (str varchar(20)[]);
          CREATE TABLE
          vsavard_db=> INSERT INTO test_array (str) VALUES ('{"hello", "world"}');
          INSERT 0 1
          vsavard_db=> SELECT str FROM test_array;
                str      
          ---------------
           {hello,world}
          (1 ligne)


          Ça peut avoir son utilité, mais c'est plus rare.

          Edit: Les OIDS, ce sont des object identifiers. Lord Casque Noir ou Cintre Sournois pourrait certainement te répondre mieux que moi à ce sujet, mais ça semble être utilisé pour l'héritage des tables. Citation de la doc :

          Citation

          WITH OIDS
          WITHOUT OIDS
          This optional clause specifies whether rows of the new table should have OIDs (object identifiers) assigned to them. The default is to have OIDs. (If the new table inherits from any tables that have OIDs, then WITH OIDS is forced even if the command says WITHOUT OIDS.)

          Specifying WITHOUT OIDS allows the user to suppress generation of OIDs for rows of a table. This may be worthwhile for large tables, since it will reduce OID consumption and thereby postpone wraparound of the 32-bit OID counter. Once the counter wraps around, uniqueness of OIDs can no longer be assumed, which considerably reduces their usefulness. Specifying WITHOUT OIDS also reduces the space required to store the table on disk by 4 bytes per row of the table, thereby improving performance.

          • Partager sur Facebook
          • Partager sur Twitter
            12 novembre 2010 à 0:12:52

            Ok merci bien, je vais utiliser timestamp ;)
            Sinon j'ai testé et pour un booléen "True" et True marchent, mais pas 1.
            Et pour le serial, si on met une valeur elle est gardée mais c'est assez étrange parce qu'on peut aussi bien mettre une valeur de type entier que de type texte (voir même d'autre), pourtant je crois que le select renvoie des entiers ...
            • Partager sur Facebook
            • Partager sur Twitter
              12 novembre 2010 à 0:16:27

              C'est normal pour le booléen, c'est écrit dans la doc d'ailleurs.

              Pour serial, ça marche pas chez moi. C'est une valeur entière (qui peut être négative), sinon ça lève une erreur. Les flottants sont tronqués.

              Mais bon, en général, si on utilise le type serial, c'est pas pour ajouter nous-mêmes une valeur. On laisse le SGBDR s'en occuper.
              • Partager sur Facebook
              • Partager sur Twitter
                12 novembre 2010 à 0:18:34

                Oui oui bien sûr, c'était juste par curiosité :p
                En fait je vois mal comment remplacer ma fonction time() que j'utilise comme ça:
                date('j/n/Y à G:i',time())
                Si j'utilise le timestamp de PostgreSQL, je ne pourrais l'utiliser que sous un format tandis que là c'est très maniable ...

                edit: en fait ca ne marche pas pour les textes mais ça marche pour un entier entre "".
                • Partager sur Facebook
                • Partager sur Twitter
                  12 novembre 2010 à 0:22:12

                  YYYY-MM-DD HH:II:SS.LLLLLL, c'est le format sous lequel est stocké ta date. Tu peux évidemment la changer pour quelque chose d'autre ("11 novembre 2010 à 18:19", si tu veux). Pour MySQL, c'est la fonction DATE_FORMAT, pour PostgreSQL, c'est to_char(). Encore une fois, voir la doc pour plus d'informations.

                  Crois-moi, c'est beaucoup plus malléable qu'un timestamp unix, tu vas t'en rendre compte au fil du temps.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    12 novembre 2010 à 0:23:51

                    Ok, je vais regarder ça. Juste pour une précision, les flottants sont arrondis et non tronqués.
                    Merci beaucoup de ton aide, bonne soirée.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 novembre 2010 à 9:14:06

                      SERIAL et BIGSERIAL : c'est juste une syntaxe qui ordonne à la BDD de créer automatiquement une séquence et de la mettre en valeur par défaut dans la colonne. Sinon c'est identique à INT/BIGINT.

                      Citation : Fayden

                      Edit: Les OIDS, ce sont des object identifiers. Lord Casque Noir ou Cintre Sournois pourrait certainement te répondre mieux que moi à ce sujet, mais ça semble être utilisé pour l'héritage des tables. Citation de la doc :



                      En fait, tout sous postgres a un oid (les tables, les types, les fonctions etc) et tu peux en donner aux lignes de tables aussi, mais comme la valeur ne fait que 32 bits, quand elle boucle, c'est chiant. Donc, comme il faut dire que ça ne sert pas à grand chose de mettre des OID dans les tables, il vaut mieux garder le défaut WITHOUT OIDS.

                      > YYYY-MM-DD HH:II:SS.LLLLLL, c'est le format sous lequel est stocké ta date

                      en fait non, c'est un int64 en interne, ce que tu vois c'est juste le datestyle par défaut. Tu peux le changer, (SET datestyle) mais personnellement je préfère garder le standard en base.

                      Sous python si tu SELECT une colonne TIMESTAMP, tu obtiens un objet datetime (la conversion de types est automatique pour pratiquement tout) ; en PHP la conversion de types n'est pas réalisée mais tu peux faire simplement :

                      $dt = new DateTime( $valeur genre '2010-01-01 10:00:00' );
                      echo $dt->format( "format de ton choix" );
                      


                      Ne pas oublier le type INTERVAL sous postgres qui est extrêmement pratique.

                      test=> SELECT now(), now() + '1 MONTH'::INTERVAL;
                                   now              |           ?column?           
                      ------------------------------+------------------------------
                       2010-11-12 09:16:17.93329+01 | 2010-12-12 09:16:17.93329+01
                      
                      • Partager sur Facebook
                      • Partager sur Twitter
                        12 novembre 2010 à 11:34:29

                        Ok merci des précisions.
                        J'ai un petit problème avec les dates, voici un exemple:
                        Je stock un current_timestamp dans la colonne date, et je veux le récupérer et modifier son format:
                        $resultat = pg_query($connexion,"SELECT auteur,to_char(date,'FMDD/FMMM/YYYY FMHH24:MI';) AS date2,titre,texte FROM article") or die('Échec de la requête : ' . pg_last_error());
                        	echo "<table>\n";
                        	while ($ligne = pg_fetch_array($resultat)) {
                        		echo "\t<tr>\n";
                        		echo "\t\t<td>Auteur: $ligne[auteur]</td><br />\n";
                        		echo "\t\t<td>Date: $ligne[date2]</td><br />\n";
                        		echo "\t\t<td>Titre: $ligne[titre]</td><br />\n";
                        		echo "\t\t<td>Texte: $ligne[texte]</td>\n";
                        		echo "\t</tr><br />\n";
                        	}
                        	echo "</table>\n";
                        

                        Cette requête marche très bien, mais quand je veux modifier le format de la date pour ajouter du texte, je dois mettre des " seulement je ne peux pas sinon ça arrête la requête...
                        (exemple: to_char(date,'"Le "FMDD/FMMM/YYYY" à "FMHH24:MI';) AS date2 )
                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 novembre 2010 à 11:44:51

                          Là, je tape dans la console psql :

                          test=> SELECT to_char(now(),'Le FMDD/FMMM/YYYY à FMHH24:MI');
                                  to_char        
                          -----------------------
                           Le 12/11/2010 à 11:42


                          A mon avis tu t'es emmélé avec les ' et les "
                          - pour les strings dans les requêtes on utilise toujours ' et jamais "
                          - " sert à quoter des identifiants de colonnes, par exemple si tu appelles ta colonne "select" vu que select est un mot réservé il faut mettre des ", rarement utile...

                          tu as un ; qui traîne dans ta requête avant la )

                          si tu as un doute, utilise la console psql ; après tu peux coller la requête dans PHP en mettant simplement des " autour.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            12 novembre 2010 à 11:50:23

                            Oui je venais aussi de me rendre compte pour le ; ^^
                            En fait là en effet ça marche parce que L, e et à ne sont pas des "template string" donc mauvais exemple. Mais en imaginant que je veuille par exemple écrire des "template string" tels quels:
                            In an output template string (for to_char), there are certain patterns that are recognized and replaced with appropriately-formatted data from the value to be formatted. Any text that is not a template pattern is simply copied verbatim. Similarly, in an input template string (for anything but to_char), template patterns identify the parts of the input data string to be looked at and the values to be found there.
                            J'en déduis que je peux échapper des caractères avec des " nan ?
                            Sinon je pense pas que ca marche psql, je fais mes tests directement sur un serveur et non en local.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              12 novembre 2010 à 11:53:40

                              OK, alors la bonne réponse semble être :

                              test=> SELECT to_char(now(),'"Le" FMDD/FMMM/YYYY "à" FMHH24:MI');
                                      to_char        
                              -----------------------
                               Le 12/11/2010 à 11:52


                              Pour rentrer ça dans une string php, il faut mettre des \ devant les "

                              <?
                              pg_query("SELECT to_char(now(),'\"Le\" FMDD/FMMM/YYYY \"à\" FMHH24:MI');" );
                              


                              Sinon, pour les paramètres, je te conseille de regarder pg_query_params...
                              • Partager sur Facebook
                              • Partager sur Twitter
                                12 novembre 2010 à 11:58:22

                                Oui mais justement ça ne marche pas (avec php en tous cas ...)
                                Warning: pg_query() [function.pg-query]: Query failed: ERROR: invalid byte sequence for encoding "UTF8": 0xe02220 HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding". in /home/totof/www/connexion.php on line 5
                                Échec de la requête : ERROR: invalid byte sequence for encoding "UTF8": 0xe02220 HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".

                                J'ai juste changé 'FMDD/FMMM/YYYY FMHH24:MI' par '\"Le\" FMDD/FMMM/YYYY \"à\" FMHH24:MI'
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  12 novembre 2010 à 12:32:34

                                  Je suppose que tu as encodé ton fichier php en utf8, et que tu as pensé à configurer ta connexion postgres avec :

                                  http://fr.php.net/manual/fr/function.p [...] -encoding.php

                                  ?...

                                  (contrairement à mysql, postgres vérifie l'encodage du texte...)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    12 novembre 2010 à 13:12:04

                                    Erf autant pour moi, ma base de donnée est bien en UTF-8 mais pas mon fichier, merci beaucoup ^^ (c'est juste les accents qui posaient problème)
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    [PostgreSQL]Types les plus courants

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown