PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

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

#1 20/11/2012 20:09:15

laurentalpha
Membre

Compteur cyclique optimisé

Bonjour,

Je dois gérer un numéro unique par ligne, celui-ci ne devant pas dépasser 10 000 et rebouclant sur le premier numéro libre dans la suite (au fil du temps des lignes sont insérées et supprimées avec une marge suffisante, de sorte qu'il n'y ait jamais plus de 10 000 enregistrements). Un trigger sur delete permettrait de stocker les valeurs libérées pour pouvoir les utiliser, mais je me demandais s'il n'existait pas un mécanisme simple inhérent à Postgre. J'ai regardé du côté des séquences et de l'option CYCLE, mais la documentation indique que le rebouclage se fait sur min_value, et non sur la première valeur non utilisée.

Des idées ?

Dernière modification par laurentalpha (20/11/2012 20:09:48)

Hors ligne

#2 21/11/2012 00:14:49

gleu
Administrateur

Re : Compteur cyclique optimisé

Il n'y a pas de mécanisme interne pour ça. Et tout mécanisme autre aura un coût fort en performance.


Guillaume.

Hors ligne

#3 23/11/2012 18:56:28

arthurr
Membre

Re : Compteur cyclique optimisé

Pas de magie en termes de performances mais avec 10000 lignes ça doit passer sans trop de problème :

postgres=# create table titi(toto integer);
CREATE TABLE
postgres=# insert into titi values(1);
INSERT 0 1
postgres=# insert into titi values(2);
INSERT 0 1
postgres=# insert into titi values(5);
INSERT 0 1
postgres=# select foo.val from (select generate_series(1,10000) as val) as foo where not exists (select 1 from titi where foo.val = titi.toto) limit 1;
 val 
-----
   3
(1 row)

Dernière modification par arthurr (23/11/2012 18:58:45)

Hors ligne

#4 24/11/2012 00:04:58

MitsuTomoe
Membre

Re : Compteur cyclique optimisé

J'ai ce script pour vérifier qu'une table n'a pas de trous dans les identifiants (obligation légale) :

with rech_trous as (
select id_registre as id,row_number() over (order by id_registre) as rn
from registre_mandat)
select id from rech_trous where id <> rn;

J'imagine qu'un limit 1 à la fin suffirait à donner le 1er numéro inutilisé.
Ma table ne fait que quelques milliers de lignes, donc je n'ai aucune idée des performances avec une volumétrie conséquente.

Hors ligne

Pied de page des forums