2008-09-19 10 views
5

Hola, necesito generar números de cuenta únicos de 9 dígitos. Aquí está mi pseudocódigo:Generando números de cuenta únicos - llamada recursiva

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 función parece estar funcionando bien, sin embargo, estoy un poco preocupado por la llamada recursiva.

¿Esto provocará pérdidas de memoria (PHP 5 en apache)?

¿Es esta una forma aceptable de abordar este problema?

Gracias por su aportación.

Respuesta

8

Te das cuenta de que esto podría causar un desbordamiento de la pila, ¿verdad? A medida que aumenta el número de customesr, aumenta la probabilidad de no encontrar un número de cuenta aceptable.

Además, ¿por qué no puede simplemente hacer números de cuenta secuenciales y simplemente aumentar en uno cada vez? Con este enfoque, solo tendrías que leer la identificación máxima actualmente en la base de datos y simplemente incrementarla.

Lamento ser tan directo, pero su solución es una forma terrible de abordar el problema. Utilizará toneladas de memoria (ya que la pila posiblemente crezca infinitamente) y generará toneladas de llamadas caras a la base de datos.

que realmente debería considerar algún otro enfoque:
recomiendo fuertemente simplemente incrementando el número de cliente cada vez que cree un cliente. De hecho, si configura su db correctamente (con incremento automático en la columna de identificación), ni siquiera tendrá que establecer la identificación. La identificación se establecerá para usted cada vez que inserte un nuevo cliente.

+2

¡pero stackoverflow es increíble! – Aaron

+0

Eso sería poco probable. Depende de la aleatoriedad del número de cuenta generado y del número de cuentas activas. Con el código administrado, debe recurse 10 veces o miles de veces para romper la pila. Cuando la probabilidad de no exclusividad se acerca a 10,000: 1, entonces es hora de preocuparse. – Wedge

+0

Gracias Esetban has hablado un poco de sentido común en mí jeje :) Dejaré que el DB cree el valor para mí y me atengo a los números secuenciales. Gracias –

0

No necesita utilizar recursividad aquí. Un bucle simple sería igual de rápido y consumiría menos espacio en la pila.

0

Se puede poner en un bucle 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 
1

Parece bien, pero creo que se necesita algún tipo de afección muere, ¿cuántas veces vas a dejar esta carrera antes de renunciar?

Sé que esto parece poco probable con el gran rango de números, pero algo podría ir mal que simplemente te devuelve a la llamada anterior, que se llamará de nuevo, ad-nauseum.

2

No hay necesidad de utilizar una llamada recursiva aquí. Ejecute un ciclo while simple en la función de prueba contra la inexistencia como el condicional, p. Ej.

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 

aleatoriamente generando-y-prueba es un enfoque sub-óptimo para la generación de números de cuentas únicas, sin embargo, si este código es para otra cosa que un juguete.

+1

QUÉ!?! ¿Quieres hacer 899,999,999 db hits solo para crear un número de cuenta? Parece un mal enfoque para mí. –

+0

Hmm buen punto Esteban alguna otra sugerencia? –

+0

Cuando hacemos esto, generalmente usamos alguna característica de la base de datos para producir el valor, por lo que es una consulta en lugar de O (n). –

0

Por qué no:

lock_db 
do 
    account_num <= generate number 
while account_num in db 

put row with account_num in db 

unlock_db 
0

Por qué no tienen la base de datos manejar esto? En SQL Server, puede tener una columna de identidad que comienza en 100000000. O puede usar sql en cualquier db que tenga. Obtenga el ID máximo más 1.

+0

Me gustaría tener números de cuenta de aspecto aleatorio en lugar de secuencial. –

+0

¿Por qué querrías eso? – Thomas

1

Generar números de cuenta secuencialmente es un riesgo de seguridad; debe encontrar otro algoritmo para hacerlo.

+0

Solo si no los hash siempre que los uses. –

1

Alternativamente, puede mantener una tabla separada que contiene un búfer de números de cuenta generados conocidos como únicos. Esta tabla debe tener una identificación entera autoincrementada. Cuando desee un número de cuenta, simplemente extraiga el registro con el índice más bajo en el búfer y extráigalo de esa tabla. Tenga algún proceso que se ejecute con regularidad que reponga el buffer y se asegure de que tenga una capacidad >> de uso normal. La ventaja es que la cantidad de tiempo que el usuario final pasó creando un número de cuenta será esencialmente constante.

Además, debo señalar que la sobrecarga de procesamiento o los riesgos de recursión o iteración, el verdadero problema es el determinismo y la sobrecarga de repetir las consultas de la base de datos. Me gusta la solución de TheZenker de aleatorio + secuencial. Garantizado para generar una identificación única sin agregar gastos indirectos innecesarios.

+0

Sorprendido de que esto no tiene más votos positivos.Generar números de cuenta bajo demanda, en tiempo de ejecución, no es un buen plan, recursión o no. Escriba un ciclo para generar un millón de números de forma secuencial en función de su patrón de número de cuenta, mezcle, almacénelos y llámelo por día. –

3

Realmente no creo que se reduzca a recurrencia frente a bucle, ambos son propensos a problemas a medida que el conjunto de datos crece y si la generación de números aleatorios no se implementa correctamente. Dos ideas vienen a la mente:

. GUID

Si se requiere una identificación realmente única con el mínimo esfuerzo posible, considere un GUID, su DB probablemente podrá asignarle una inserción, si no crear una en el código. Se garantiza que es único, aunque no es muy fácil de usar. Sin embargo, en combinación con un AccountRecordId secuencial generado por la base de datos en la inserción, tendría una combinación sólida

. Clave compuesta: aleatoria + secuencial

Una forma de abordar todas las necesidades, aunque en la superficie se siente un poco kludgy, es crear un número de cuenta compuesto de una clave secuencial db de 5 dígitos (o más) y luego otra 5 dígitos de aleatoriedad. Si se duplicara el número aleatorio, no importaría ya que la identificación secuencial garantizaría la singularidad de todo el número de cuenta

Cuestiones relacionadas