Faresti meglio a memorizzare una tabella con tutti i 10.000 valori possibili definiti e un flag "in uso" su ciascuno. In questo modo, rilasciare il numero per il riutilizzo è un semplice aggiornamento per impostare "inuse=false".
Inoltre, trovare il valore più basso disponibile diventa semplice
SELECT idstring
FROM idstringtable
ORDER BY idstring ASC
WHERE (available = 1)
LIMIT 1
Farlo con blocchi/transazioni appropriati impedirebbe a due o più richieste di ottenere lo stesso ID e, poiché si tratta di una piccola tabella, eseguire un blocco di tabella globale non inciderebbe in modo significativo sulle prestazioni.
Altrimenti, saresti bloccato a rovistare nella tabella degli utenti, cercando di trovare il primo "spazio vuoto" nella sequenza di numerazione.