Visualizzazione post con etichetta primary key. Mostra tutti i post
Visualizzazione post con etichetta primary key. Mostra tutti i post

martedì 9 febbraio 2010

MySQL: Generare una chiave primaria per una tabella (versione migliorata)


Ciao a tutti,

l'altro giorno avendo un po' di tempo per sperimentare nuove e più comode soluzioni, sono voluto ritornare su un argomento che avevo trattato qualche mese fa in questo post, la generazione di una chiave primaria per le tabelle MySQL.

Siccome l'altra volta avevamo trattato una soluzione veloce, quindi non troppo elegante, per la gestione del problema ho ripensato alla cosa ed ho trovato che la cosa migliore fosse integrare il codice in una funzione, comodamente richiamabile, in qualsiasi punto del codice, e standardizzata.

Allego quindi il codice di creazione della procedura:
CREATE DEFINER=`root`@`localhost` FUNCTION `RowIdGen`() RETURNS CHAR(30) CHARSET latin1
DETERMINISTIC
BEGIN
RETURN CONCAT('PREF',DATE_FORMAT(SYSDATE(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := IFNULL(@numero,0) + 1,5,0));
END$$

DELIMITER ;
Non sto a ridiscutere il codice in quanto è già spiegato nel dettaglio nel vecchio post.
Spero di esservi stato utile, e se avete voglia cliccate sui banner pubblicitari.

Ciao

Wsc

giovedì 2 aprile 2009

MySQL: Generare una chiave primaria per una tabella

Oggi ho avuto la necessità di generare una chiave primaria per una tabella. Siccome non ho molto in simpatia l'uso degli autoincrement ho deciso di costruirla sulla base di un campo varchar(30).

Una delle problematiche è che in una fase di insert massivo (il sistema riesce ad inserire alcune migliaia di record in un secondo) la generazione di questa stringa non è stata semplicissima.
Vediamo comunque le strategie usate partendo dal risultato finale.
SET @numero = 1;

SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Leggendo così a primo colpo può quasi spaventare, ma vediamola passo passo.
La Set iniziale servirà più avanti e per ora evito di trattarla.
Innanzi tutto per ottenere una stringa avremo bisogno ci concatenare gli elementi che useremo per andare a formare la stringa.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Come primo elemento aggiungiamo un prefisso (in questo caso di 4 lettere) che ci identifica la tabella o qualsiasi altra cosa vi possa venire in mente.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Per la seconda parte utilizziamo la data attuale con precisione al secondo in tale maniera ogni volta che creeremo la chiave primaria si già diversa in dipendenza del tempo.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
A questo punto siccome in un secondo possono esserci anche migliaia di inserimenti che manderebbero in violazione di chiave la nostra operazione aggiungiamo il terzo e quarto elemento. Il terzo sarò un numero randomico generato come già spiegato in un latro post secondo una formula matematica.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Ultima parte un numero sequenziale, che io nel caso gli ho passato da una variabile @numero, ma che si può tranquillamente immagazzinare in una tabella e richiamare a piacere, aumentando il suo valore ad ogni passaggio.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Il risultato che si ottiene è qualcosa come questo:
DVBH20090402133508062740800002
Ecco fatto!

Wsc