Geração de números de contas únicas - chamada recursiva
Pergunta
Oi Eu preciso gerar números de contas únicas 9 dígitos. Aqui está o meu pseudocódigo:
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
A função parece estar funcionando bem, mas estou um pouco preocupado com a chamada recursiva.
Será que esta causa quaisquer vazamentos de memória (PHP 5 sob apache)?
Esta é uma maneira aceitável para resolver este problema?
Obrigado por sua entrada.
Solução
Você percebe isso poderia muito bem causar um estouro de pilha, certo? Como o número de aumentos customesr, a probabilidade de não encontrar um um número aumenta conta aceitáveis.
Além disso, por que não pode apenas fazer números de conta seqüenciais e apenas aumentar em um de cada vez? Com esta abordagem, você só tem que ler o ID máximo atualmente no banco de dados e apenas incrementá-lo.
Desculpa ser tão brusco, mas sua solução é uma péssima maneira de resolver o problema. Ele vai usar toneladas de memória (como a pilha possivelmente cresce infinitamente) e vai faz toneladas de chamadas caras para o banco de dados.
Você deve realmente considerar alguma outra abordagem:
Eu recomendo fortemente apenas incrementando o número de cliente cada vez que você criar um cliente. Na verdade, se você configurar seu db adequadamente (com auto incremento na coluna id), você não vai mesmo ter de definir o id. O ID será definido para você sempre que você inserir um novo cliente.
Outras dicas
Eu realmente não acho que se resume a recursão vs. looping, ambos são propensos a problemas como o conjunto de dados cresce e se a geração de números aleatórios não é implementada corretamente. Duas idéias vêm à mente:
. GUID
Se um ID de verdadeiramente único é necessária com o menor esforço possível, considere um GUID, o DB provavelmente será capaz de atribuir por você na inserção, se não criar um em código. É garantido para ser único, embora não seja muito amigável. No entanto, em combinação com um seqüencial AccountRecordId gerado pela DB na inserção você teria uma sólida combinação
. Composite Chave: Random + Sequential
Uma forma de lidar com todas as necessidades, embora na superfície que se sente um kludgy bit, é a criação de um número de conta de composto a partir de uma chave db sequencial de 5 dígitos (ou mais) e, em seguida, mais 5 dígitos de aleatoriedade. Se o número aleatório foi duplicada não importaria como o ID seqüencial iria garantir a unicidade do número da conta inteira
Não há necessidade de usar uma chamada recursiva aqui. Executar um simples loop while na função testando contra a não-existência como a condicional, por exemplo.
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 gerando-and-teste é uma abordagem sub-optimal para a geração de números de contas únicas, porém, se esse código é para outra coisa senão um brinquedo.
Parece bom, mas eu acho que você precisa de algum tipo de condição morrer, quantas vezes você vai deixar este prazo antes de desistir?
Eu sei que isso parece improvável com a enorme gama de números, mas algo poderia dar errado que só cai de volta para a chamada anterior, que irá chamar-se novamente, ad-nauseum.
números de conta Geradoras sequencialmente é um risco de segurança -. Você deve encontrar algum outro algoritmo para fazê-lo
Como alternativa, você pode manter uma tabela separada contendo tampão de gerada, conhecido por ser números de contas únicas. Esta tabela deve ter um ID de inteiro auto-incremento. Quando você quer um número de conta, basta puxar o registro com o menor índice no buffer e removê-lo dessa tabela. Ter algum processo que é executado regularmente, o que repõe o buffer e garante que tem capacidade >> uso normal. A vantagem é que a quantidade de tempo experimentado pelo utilizador final gasto criando um número de conta será essencialmente constante.
Além disso, devo notar que a sobrecarga de processamento ou riscos de recursão ou iteração, a verdadeira questão é o determinismo ea sobrecarga de repetir consultas de banco de dados. I como solução de + sequencial aleatória de TheZenker. Garantido para gerar uma identificação única sem adicionar sobrecarga desnecessária.
Você não precisa usar recursão aqui. Um loop simples seria tão rápido e consumir menos espaço pilha.
Você poderia colocá-lo em um tempo loop:
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
Por que não:
lock_db
do
account_num <= generate number
while account_num in db
put row with account_num in db
unlock_db
Por que não ter o identificador do banco de dados isso? No SQL Server, você pode apenas ter uma coluna de identidade que começa em 100000000. Ou você pode usar sql em qualquer db que você tem. Basta obter o ID máximo mais 1.