156 votes

Génération d'une chaîne de 8 caractères unique et aléatoire à l'aide de MySQL

Je travaille sur un jeu qui implique des véhicules à un moment donné. J'ai une table MySQL nommée "véhicules" contenant les données sur les véhicules, y compris la colonne "plaque" qui stocke les plaques d'immatriculation des véhicules.

Maintenant, voici la partie avec laquelle j'ai des problèmes. Je dois trouver une plaque d'immatriculation inutilisée avant de créer un nouveau véhicule - il doit s'agir d'une chaîne alphanumérique aléatoire de 8 caractères. Pour y parvenir, j'ai utilisé une boucle while en Lua, qui est le langage dans lequel je programme, pour générer des chaînes et interroger la base de données pour voir si elle est utilisée. Cependant, à mesure que le nombre de véhicules augmente, je m'attends à ce que cela devienne encore plus inefficace que maintenant. J'ai donc décidé d'essayer de résoudre ce problème en utilisant une requête MySQL.

La requête dont j'ai besoin doit simplement générer une chaîne alphanumérique de 8 caractères qui n'est pas déjà dans la table. J'ai de nouveau pensé à l'approche de la boucle generate&check, mais je ne limite pas cette question à celle-ci, au cas où il en existerait une plus efficace. J'ai réussi à générer des chaînes de caractères en définissant une chaîne contenant tous les caractères autorisés et en la soustrayant de manière aléatoire, mais rien de plus.

Toute aide est appréciée.

26voto

beingalex Points 755

Voici une autre méthode pour générer une chaîne aléatoire :

SELECT SUBSTRING(MD5(RAND()) FROM 1 FOR 8) AS myrandomstring

18voto

Paul Spiegel Points 15506

Vous pouvez générer une chaîne alphanumérique aléatoire avec :

lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0);

Vous pouvez l'utiliser dans un BEFORE INSERT déclencher et vérifier un doublon dans une boucle while :

CREATE TABLE `vehicles` (
    `plate` CHAR(8) NULL DEFAULT NULL,
    `data` VARCHAR(50) NOT NULL,
    UNIQUE INDEX `plate` (`plate`)
);

DELIMITER //
CREATE TRIGGER `vehicles_before_insert` BEFORE INSERT ON `vehicles`
FOR EACH ROW BEGIN

    declare str_len int default 8;
    declare ready int default 0;
    declare rnd_str text;
    while not ready do
        set rnd_str := lpad(conv(floor(rand()*pow(36,str_len)), 10, 36), str_len, 0);
        if not exists (select * from vehicles where plate = rnd_str) then
            set new.plate = rnd_str;
            set ready := 1;
        end if;
    end while;

END//
DELIMITER ;

Maintenant, il suffit d'insérer vos données comme

insert into vehicles(col1, col2) values ('value1', 'value2');

Et le déclencheur va générer une valeur pour le plate colonne.

( Démonstration de sqlfiddle )

Cela fonctionne ainsi si la colonne autorise les NULLs. Si vous voulez qu'elle soit NOT NULL, vous devez définir une valeur par défaut.

`plate` CHAR(8) NOT NULL DEFAULT 'default',

Vous pouvez également utiliser tout autre algorithme de génération de chaîne aléatoire dans le déclencheur si les caractères alphanumériques majuscules ne sont pas ce que vous voulez. Mais le déclencheur se chargera de l'unicité.

17voto

Andrey Volk Points 1925

Vous pouvez utiliser la fonction rand() y char() fonction :

select concat( 
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97)
) as name;

10voto

Aman Kumar Points 1

Ce travail me permet de générer un numéro à 6 chiffres et de le mettre à jour dans MySQL :

Générer :

SELECT SUBSTRING(MD5(RAND()) FROM 1 FOR 6)

Mise à jour :

UPDATE table_name 
SET column_name = SUBSTRING(MD5(RAND()) FROM 1 FOR 6) 
WHERE id = x12

9voto

Jan Uhlig Points 81

Pour une chaîne composée de 8 chiffres aléatoires et de lettres majuscules et minuscules, voici ma solution :

LPAD(LEFT(REPLACE(REPLACE(REPLACE(TO_BASE64(UNHEX(MD5(RAND()))), "/", ""), "+", ""), "=", ""), 8), 8, 0)

Expliqué de l'intérieur vers l'extérieur :

  1. RAND génère un nombre aléatoire entre 0 et 1
  2. MD5 calcule la somme MD5 de (1), 32 caractères de a-f et 0-9
  3. UNHEX traduit (2) en 16 octets avec des valeurs de 00 à FF
  4. TO_BASE64 encode (3) en base64, 22 caractères de a-z, A-Z et 0-9 plus "/" et "+", suivis de deux "=".
  5. les trois REPLACE s supprimer les caractères "/", "+" et "=" de (4)
  6. LEFT prend les 8 premiers caractères de (5), changez 8 en quelque chose d'autre si vous avez besoin de plus ou moins de caractères dans votre chaîne aléatoire
  7. LPAD insère des zéros au début de (6) s'il comporte moins de 8 caractères ; là encore, changez 8 par quelque chose d'autre si nécessaire

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X