Como impedir que dois usuários se registrem no mesmo instante com o mesmo nome de usuário?

11

Não podemos serializar registros, pois existem milhões de usuários registrando ao mesmo tempo. Registros paralelos precisam acontecer.

Digamos que o banco de dados não contenha o nome de usuário 'user1'. Quando dois usuários tentam se registrar no mesmo momento com 'user1', ele aceita. Mas depois causará problemas. Isso não deveria acontecer.

Estou procurando uma solução lógica. Não é nada específico. Apenas uma idéia para resolver isso.

Addzy K
fonte
dada a explicação em sua tentativa anterior de publicá-la no The Workplace, considere fazer uma leitura de Por que as perguntas da entrevista fazem com que os programadores sejam pobres.
Gnat
4
É um problema legítimo de arquitetura de software. Não é o tipo de problema que apenas faz uma boa pergunta para entrevista e nada mais.
Karl Bielefeldt
7
Milhões de usuários se registrando ao mesmo tempo? Verdade? Se você tiver milhões de usuários registrando ao mesmo tempo, terá maiores problemas - como lidar com bilhões de usuários registrados. E provavelmente o dinheiro para comprar servidores que lidam com isso.
precisa saber é o seguinte
2
@AddzyK Esse é um problema hipotético enfrentado no futuro para o qual você deseja uma solução lógica? Tenho certeza de que está fora de escopo aqui.
Paparazzo
3
Aqui está uma resposta hipotética: pague a alguém que já sabe o que fazer. Com milhões de novos usuários / segundo, você terá o dinheiro.
Whatsisname

Respostas:

15

Digamos que o banco de dados não contenha o nome de usuário 'user1'. Quando dois usuários tentam se registrar no mesmo momento com 'user1', ele aceita.

Por que aceitaria isso? É simples aplicar uma restrição exclusiva, usar o nome de usuário como chave primária ou simplesmente executar o código do aplicativo de check-in dentro de uma transação.

Você absolutamente deve poder usar uma transação de banco de dados para usá-lo para impedir que isso ocorra. Caso contrário, nenhum aplicativo seria capaz de manter invariantes nos dados do banco de dados.

Em termos de escala, os bancos de dados já inventaram as tecnologias necessárias, como vários modos de bloqueio, dependendo exatamente de que tipo de consistência você precisa, bancos de dados distribuídos para vários servidores de banco de dados, etc.

DeadMG
fonte
O bloqueio dos registros não impede que outros usuários se registrem ao mesmo tempo?
precisa saber é o seguinte
2
+1, Acabei de executar algumas contas matemáticas e até o Facebook calcula a média de algumas inscrições por segundo. Portanto, confiar nas próprias restrições do banco de dados deve ser suficiente.
GrandmasterB
2
@AddzyK: O bloqueio ocorre apenas por um breve momento em que o banco de dados deve impor as restrições. Sim, outros usuários que se registram simultaneamente devem esperar na fila, mas essa espera é muito curta e raramente ocorre de qualquer maneira, mesmo nos maiores sistemas.
Robert Harvey
1
@GrandmasterB As médias podem não contar a história completa aqui. Eu assumi com base na pergunta que isso era para lidar com o pico de carga pesada - por exemplo, o material do censo australiano.
DeadMG
@AddzyK Pode funcionar. Essencialmente, você pode se safar com apenas travar parte da mesa. Existem inúmeros esquemas para lidar com isso, como a resposta do gnasher729, mas acredito que você deve conseguir um produto de banco de dados distribuído pronto para uso que possa lidar com isso para você. Mesmo se você precisar executar seu próprio esquema de bloqueio parcial, existem várias maneiras conhecidas de lidar com isso, como o DHT.
DeadMG
7

Existe uma solução padrão para isso. Crie vários trabalhadores para fazer os registros. Cada solicitação possui um hash aplicado ao nome de usuário e o hash determina qual trabalhador processa a solicitação. Dessa forma, não é possível processar duas solicitações para o mesmo nome de usuário simultaneamente.

Para esse tipo de volume de solicitações, considere um armazenamento de valor de chave distribuído, como risco, em vez de um banco de dados all como o armazenamento de dados.

Michael Shaw
fonte
2

Isso é um problema ?

Permitir que dois usuários concluam seu registro com um nome de usuário não exclusivo não é aceitável se o nome de usuário (e não o email do usuário) for usado para o logon.

Se o nome de usuário não for usado para autenticação, você poderá usar algum processo em segundo plano para identificar e sinalizar as duplas (por exemplo, com base no carimbo de data / hora) e forçar o usuário a alterar seu nome de usuário no próximo logon

Sim é um problema

Como você está perguntando, suponho que o nome de usuário seja um ID exclusivo. As seguintes abordagens podem ser usadas:

  1. Antes: No processo de registro, preveja uma etapa em que o novo usuário deve verificar a disponibilidade de seu nome. Ao fazer isso, reserve o nome da conta disponível com um status temporário e um ID de sessão que permitirá concluir o registro.
  2. Mesmo tempo: uma variante mais geral e flexível da resposta gnasher729 seria usar uma função hash simples (como as usadas para gerenciar tabelas de símbolos), para atribuir o ID a um servidor de registro exclusivo i (i = h (nome de usuário) módulo number_of_servers) que manipularão a exclusividade em seu escopo limitado / segmentado
  3. Depois: No final do registro, quando o usuário clicar em registerenviar a solicitação ao seu banco de dados transacional, se você puder definir o campo como exclusivo. Em caso de erro, envie ao usuário azarado "opa, ocorreu um problema" e peça para ele escolher outro ID.
  4. Assíncrono: registre o usuário. Releia o registro do usuário logo após para garantir que ele seja inalterado e o único. Se for um problema, peça ao usuário que mude (não tão assíncrono) ou envie a ele um e-mail informando que houve um problema (assíncrono, mas irritante da perspectiva do usuário) ou deixe-o registrar, mas peça seu e-mail (para desambiguar) e forçá-lo a alterar o nome de usuário como parte do procedimento de login.
Christophe
fonte
1

Reconsidere o que você considera o identificador exclusivo de um usuário. Cada usuário já possui um endereço de email exclusivo, para que o problema já tenha sido resolvido para você. Obviamente, isso significa que vários usuários poderão registrar o mesmo nome, como "Mike Nakis". Existe algum problema com isso? Você tem certeza? Não é um problema para o facebook, por exemplo. Existem vários usuários do Facebook chamados "Mike Nakis". Veja a página de login do facebook: ele pede "email ou telefone" e "senha".

Mike Nakis
fonte
0

Com milhões de usuários registrados ao mesmo tempo, você apenas usa servidores de registro 26 x 26, um para usuários começando com aa, outro para usuários começando com ab e assim por diante. Como resultado, existem apenas milhares de usuários registrados em cada servidor ao mesmo tempo. Se você ainda não conseguir lidar com isso, use servidores 26 x 26 x 26.

gnasher729
fonte
5
... e então o seu proprietário do produto quer ir internacional ...
Telastyn
2
Os mesmos princípios se aplicam às seqüências de caracteres Unicode desde que estejam em uma forma normalizada, como NFKD. Você também pode fazer o hash do nome de usuário e aplicá-lo com base no hash. No entanto, essa resposta está basicamente implementando seu próprio banco de dados distribuído.
DeadMG
1
Você quer dizer que eles têm milhões de usuários registrando ao mesmo tempo em um país ? Nesse caso, eles devem ter dinheiro suficiente para pagar mais por uma solução real.
gnasher729
Mais especificamente, este é apenas o começo de como as DHTs são feitas.
DeadMG
como isso resolve o problema de dois usuários registrando o mesmo nome ao mesmo tempo - ambos os nomes começariam com os mesmos dois caracteres e, portanto, eram tratados pelo mesmo servidor de registro?
HorusKol 30/08/16