Vous feriez mieux de stocker une table avec les 10 000 valeurs possibles définies et un indicateur "en cours d'utilisation" sur chacune. De cette façon, libérer le numéro pour réutilisation est une simple mise à jour pour définir "inuse=false".
Facilite également la recherche de la valeur disponible la plus basse
SELECT idstring
FROM idstringtable
ORDER BY idstring ASC
WHERE (available = 1)
LIMIT 1
Faire cela avec des verrous/transactions appropriés empêcherait deux requêtes ou plus d'obtenir le même ID, et comme il s'agit d'une petite table, faire un verrou de table global n'aurait pas d'impact significatif sur les performances.
Sinon, vous seriez coincé à fouiller dans votre tableau des utilisateurs, essayant de trouver le premier "écart" dans la séquence de numérotation.