Domanda

Salve, devo generare numeri di conto univoci a 9 cifre.Ecco il mio pseudocodice:

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    if the account number already exists in the DB 
        call generateAccNo()    /* recursive call */
    else
        return new accout number
    end if

end function

La funzione sembra funzionare bene, tuttavia sono un po' preoccupato per la chiamata ricorsiva.

Ciò causerà perdite di memoria (PHP 5 sotto Apache)?

È questo un modo accettabile per affrontare questo problema?

Grazie per il tuo contributo

È stato utile?

Soluzione

Ti rendi conto che questo potrebbe benissimo causare un overflow dello stack, giusto?All'aumentare del numero di clienti, aumenta la probabilità di non trovare un numero di conto accettabile.

Inoltre, perché non puoi semplicemente creare numeri di conto sequenziali e aumentarli di uno ogni volta?Con questo approccio, dovresti semplicemente leggere l'ID massimo attualmente nel database e semplicemente incrementarlo.

Mi dispiace essere così schietto, ma la tua soluzione è un modo terribile per affrontare il problema.Utilizzerà tonnellate di memoria (poiché lo stack potrebbe crescere all'infinito) ed effettuerà tonnellate di chiamate costose al database.

Dovresti davvero considerare qualche altro approccio:
Consiglio vivamente di incrementare semplicemente il numero cliente ogni volta che crei un cliente.Infatti, se imposti correttamente il tuo db (con incremento automatico sulla colonna id), non dovrai nemmeno impostare l'id.L'ID ti verrà impostato ogni volta che inserisci un nuovo cliente.

Altri suggerimenti

Non penso davvero che dipenda dalla ricorsione vs.looping, entrambi sono soggetti a problemi man mano che il set di dati cresce e se la generazione di numeri casuali non è implementata correttamente.Mi vengono in mente due idee:

.GUIDA

Se è richiesto un ID veramente univoco con il minimo sforzo possibile, considera un GUID, molto probabilmente il tuo DB sarà in grado di assegnarti al momento dell'inserimento, se non di crearne uno nel codice.È garantito che sia unico anche se non è molto facile da usare.Tuttavia, in combinazione con un AccountRecordId sequenziale generato dal DB all'inserimento si otterrebbe una combinazione solida

.Chiave composita:Casuale + Sequenziale

Un modo per soddisfare tutte le esigenze, anche se in superficie sembra un po' complicato, è creare un numero di conto composito da una chiave db sequenziale di 5 cifre (o più) e poi altre 5 cifre casuali.Se il numero casuale fosse duplicato non avrebbe importanza poiché l'ID sequenziale garantirebbe l'unicità dell'intero numero di conto

Non è necessario utilizzare una chiamata ricorsiva qui.Esegui un semplice ciclo while nella funzione test contro la non esistenza come condizionale, ad es.

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    while ( the account number already exists in the DB ) {
         generate new account number;
    }
    return new account number

end function

Tuttavia, generare e testare in modo casuale è un approccio non ottimale per generare numeri di conto univoci, se questo codice è per qualcosa di diverso da un giocattolo.

Sembra che vada bene, ma penso che tu abbia bisogno di una sorta di condizione di morte, quante volte lascerai correre prima di arrenderti?

So che questo sembra improbabile con l'enorme gamma di numeri, ma qualcosa potrebbe andare storto e riportarti alla chiamata precedente, che si chiamerà di nuovo, fino alla nausea.

Generare numeri di conto in sequenza è un rischio per la sicurezza: dovresti trovare qualche altro algoritmo per farlo.

In alternativa, è possibile mantenere una tabella separata contenente un buffer di numeri di conto generati, noti come univoci.Questa tabella dovrebbe avere un ID intero con incremento automatico.Quando desideri un numero di conto, seleziona semplicemente il record con l'indice più basso nel buffer e rimuovilo da quella tabella.Avere un processo che venga eseguito regolarmente che riempia il buffer e si assicuri che abbia capacità >> utilizzo normale.Il vantaggio è che la quantità di tempo impiegato dall'utente finale per creare un numero di conto sarà sostanzialmente costante.

Inoltre, dovrei notare che il sovraccarico di elaborazione o i rischi di ricorsione o iterazione, il vero problema è il determinismo e il sovraccarico della ripetizione delle query del database.Mi piace la soluzione casuale + sequenziale di TheZenker.Garantito per generare un ID univoco senza aggiungere spese generali inutili.

Non è necessario utilizzare la ricorsione qui.Un ciclo semplice sarebbe altrettanto veloce e consumerebbe meno spazio nello stack.

Potresti inserirlo in un ciclo while:

function generateAccNo()

    while (true) {    

      generate an account number between 100,000,000 and 999,999,999

      if the account number already exists in the DB 
          /* do nothing */
      else
          return new accout number
      end if
    }

end function

Perché no:

lock_db
do
    account_num <= generate number
while account_num in db

put row with account_num in db

unlock_db

Perché non lasciare che sia il database a gestirlo?IN SQL Server, puoi semplicemente avere una colonna identità che inizia da 100000000.Oppure potresti usare SQL in qualunque DB tu abbia.Ottieni semplicemente l'ID massimo più 1.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top