Vous n'êtes pas identifié(e).

#1 21/03/2009 12:52:48

CinePhil
Membre

Clé primaire auto-incrémentée

Bonjour,
J'ai créé il y a quelques jours ma première BDD PostgreSQL à partir de requêtes DDL générées par le logiciel de modélisation Open ModelSphere et que j'ai dû adapter.

J'ai vu quelque part que pour CREER une table avec une clé primaire auto-incrémentée, il fallait utiliser, à la place du très pratique AUTO_INCREMENT de MySQL, le type 'serial', lequel entraîne la création automatique d'une séquence et le paramétrage de la colonne en DEFAULT nextval('nom_sequence'::regclass). Pourquoi faire simple quand on peut faire compliqué chez PostgreSQL !

Le problème est que j'ai pensé à ce détail pour la première table mais, corrigeant les bugs de mes requêtes DDL au fur et à mesure (character varying au lieu de variable character par exemple), je l'ai oublié pour les autres tables issues des entités de mon MCD.

Ces tables ont donc une clé primaire de type INTEGER ou SMALLINT mais ne sont pas auto-incrémentées.

Malheureusement, il semble qu'il soit impossible de MODIFIER le type de la colonne en 'serial' une fois la table créée ; je me suis tapé un joli message d'erreur quand j'ai essayé de le faire en SQL et le type n'est pas dans la liste proposée dans pgAdmin !

Alors j'ai fait l'effort :
- de créer une séquence sur le modèle de celle qui avait été créée automatiquement ;
- de changer la valeur par défaut de la colonne clé primaire de la table.

Pas de message d'erreur cette fois mais j'ai des doutes quand je regarde pgAdmin...

Pour la table où la clé primaire auto-incrémentée a été faite automatiquement grâce au type serial, je vois que le paramètre Séquence affiche bien le nom de la séquence et l'onglet "Objets dépendants" affiche bien le nom de la séquence.

Pour la table où j'ai voulu faire de même manuellement, ces informations n'apparaissent pas !

Du coup je me demande si c'est correctement implanté et si l'auto-incrémentation va bien s'effectuer.

Dernière modification par CinePhil (21/03/2009 12:54:42)


Philippe Leménager
Futur ingénieur CNAM.
En CDD à l'INRA Toulouse, reste ouvert aux propositions d'emploi.
Modérateur bases de données sur Développez.com.

Hors ligne

#2 21/03/2009 16:38:43

gleu
Administrateur

Re : Clé primaire auto-incrémentée

Pourquoi faire simple quand on peut faire compliqué chez PostgreSQL !

Sans vouloir polémiquer, pourquoi faire standard quand on peut l'éviter chez MySQL ?

Malheureusement, il semble qu'il soit impossible de MODIFIER le type de la colonne en 'serial' une fois la table créée ; je me suis tapé un joli message d'erreur quand j'ai essayé de le faire en SQL et le type n'est pas dans la liste proposée dans pgAdmin !

serial est un pseudo type. Ce n'est pas un vrai type car il est remplacé par int (si serial) et bigint (si bigserial) et il va causer l'ajout d'une séquence et d'une valeur par défaut. Il n'est donc disponible que pour un ajout de colonne, mais pas pour une modification.

Du coup je me demande si c'est correctement implanté et si l'auto-incrémentation va bien s'effectuer.

Le meilleur moyen de le savoir est d'insérer une donnée dans la table et de vérifier si la colonne s'est bien incrémentée automatiquement.


Guillaume.

Hors ligne

#3 22/03/2009 08:52:24

CinePhil
Membre

Re : Clé primaire auto-incrémentée

gleu a écrit :

Pourquoi faire simple quand on peut faire compliqué chez PostgreSQL !

Sans vouloir polémiquer, pourquoi faire standard quand on peut l'éviter chez MySQL ?

Sans vouloir polémiquer, je ne pense pas que

nextval('"CineDoc"."Festivals_Fe_Id_seq"'::regclass),

soit du standard SQL non plus ! Quitte à faire une fonction pour implémenter un truc qui n'est pas prévu par la norme SQL, autant faire simple comme MySQL avec son AUTO_INCREMENT !

serial est un pseudo type. Ce n'est pas un vrai type car il est remplacé par int (si serial) et bigint (si bigserial) et il va causer l'ajout d'une séquence et d'une valeur par défaut. Il n'est donc disponible que pour un ajout de colonne, mais pas pour une modification.

Et il manque la possibilité SMALLINT.

Du coup je me demande si c'est correctement implanté et si l'auto-incrémentation va bien s'effectuer.

Le meilleur moyen de le savoir est d'insérer une donnée dans la table et de vérifier si la colonne s'est bien incrémentée automatiquement.

Bon ben on verra ça quand j'aurai fait l'interface alors.


Philippe Leménager
Futur ingénieur CNAM.
En CDD à l'INRA Toulouse, reste ouvert aux propositions d'emploi.
Modérateur bases de données sur Développez.com.

Hors ligne

#4 05/06/2009 12:58:53

papafigus
Membre

Re : Clé primaire auto-incrémentée

Bonjour,
nouveau venu dans le monde des géomaticiens, je suis actuellement en projet avec une asso pour organiser une base de donnée postgres/postgis en ligne, et c'est pas tout simple pour une première expérience!!!
voila pour me situer, à présent je passe à l'appel au secours!!! :-)
Dans mes tables j'ai une clé auto incrémentée pour chaque enregistrement qui doit être de trois chiffres et malheuresement je ne trouve pas la solution pour activer le paramétrage de la longueur d'un type de champs tel que SERIAL ou BIGSERIAL.je suis obligé de le fixer à trois chiffre car cet ID est ensuite concaténé avec trois autres caractères pour former un code unique final.
Voila, j'espère avoir été assez explicite,bravo à tous ceux qui font vivre ce forum!
Et surtout MERCI à ceux qui m'aideront à résoudre mon problème...

Hors ligne

#5 05/06/2009 13:19:40

gleu
Administrateur

Re : Clé primaire auto-incrémentée

Vous ne pouvez pas le fixer à trois chiffres. Par contre, après coup, vous pouvez utiliser la fonction to_char pour transformer le nombre en nombre de trois caractères.


Guillaume.

Hors ligne

#6 05/06/2009 13:19:43

Marc Cousin
Membre

Re : Clé primaire auto-incrémentée

On ne peut effectivement pas le faire directement avec du SERIAL ou BIGSERIAL.

J'aurais besoin de davantage de précisions :
- Est ce juste le besoin de limiter le nombre dans cette colonne à trois chiffre ?
- Faut il qu'il fasse exactement trois chiffres ?
- Si oui, de 100 à 999 ou de 001 à 999 (doit on compléter avec des 0 devant) ?
- Faut il pouvoir réutiliser les chiffres manquants ? (on arrive très vite à 1000 enregistrements dans une table. Et avec une sequence, par défaut, c'est auto incrémenté jusqu'à la limite d'un chiffre bigint, soit beaucoup trop dans l'exemple qui nous concerne:) ).

Il y a probablement une solution, mais merci de préciser donc exactement la forme attendue pour le nombre, et comment on se comporte quand on arrive à 999.


Marc.

Hors ligne

#7 05/06/2009 16:42:53

papafigus
Membre

Re : Clé primaire auto-incrémentée

Re
merci pour la réponse rapide!
cette colonne doit comporter trois chiffre exactement, ceux-ci peuvent aller de 001 à 999 ou de 100 à 999, ça n'a pas trop d'importance à part que ça va limiter un peut le nombre de combinaisons possibles. Ce qui est important pour moi c'est de garder ce nombre de chiffre fixe car dans ma table mère ce numéro auto vient se concaténer avec deux autres codes, un comportant un caractère, et un autre avec deux. Ceci me permet d'avoir au final un identifiant unique avec bcp de combinaisons possibles (assez du moins).
j'espère avoir donné assez de renseignements!
Merci encore!!!

Hors ligne

#8 05/06/2009 17:16:35

Marc Cousin
Membre

Re : Clé primaire auto-incrémentée

Si tu veux forcer le format 3 chiffres, autant le stocker directement dans un char/varchar(3), puisqu'il ne s'agit plus vraiment d'un nombre smile
Voici un exemple qui je pense devrait t'aider à obtenir ce que tu veux

test=# CREATE SEQUENCE seqtest minvalue 0 maxvalue 999 start 0;
CREATE SEQUENCE
test=# CREATE TABLE test (machinauto varchar(3) default to_char(nextval('seqtest'::regclass),'FM000'),valeur varchar);
CREATE TABLE
test=# ALTER SEQUENCE seqtest OWNED BY test.machinauto;
ALTER SEQUENCE
test=# INSERT INTO test (valeur) values ('toto');
INSERT 0 1
test=# INSERT INTO test (valeur) values ('titi');
INSERT 0 1
test=# SELECT * from test;
 machinauto | valeur
------------+--------
 000        | toto
 001        | titi
(2 lignes)

Le principe est le suivant : on crée un objet séquence, qu'on limite à 999 (ça veut dire que ça plantera après).
Ensuite on crée la table avec comme valeur par défaut de la colonne le to_char(nextval()), qui fait le formatage au passage.
Tant qu'on y est pour plus de rigueur, on lie la séquence à la colonne (pour que la séquence soit droppée avec la colonne ou la table).
En espérant que cela résolve ton problème.


Marc.

Hors ligne

#9 05/06/2009 17:18:15

Marc Cousin
Membre

Re : Clé primaire auto-incrémentée

Par contre, l'histoire de concaténation, je ne suis pas sur que ca soit une bonne idée. Un identifiant unique (primary key) peut très bien être fait sur plusieurs colonnes.
A moins qu'il y ait vraiment une raison fonctionnelle forte, au niveau base de données, ce n'est pas une bonne idée (si il faut redécouper le champ composé par concaténation).


Marc.

Hors ligne

Pied de page des forums