¿Cómo evitar que dos usuarios se registren en el mismo instante con el mismo nombre de usuario?

11

No podemos serializar registros ya que hay millones de usuarios que se registran al mismo tiempo. Se deben realizar registros paralelos.

Digamos que la base de datos no contiene el nombre de usuario 'usuario1'. Cuando dos usuarios intentan registrarse en el mismo momento con 'user1', lo aceptará. Pero luego causará problemas. Esto no debería suceder.

Estoy buscando una solución lógica. No hay nada específico. Solo una idea para resolver esto.

Addzy K
fuente
dada la explicación en su intento anterior de publicar esto en The Workplace, considere leer por qué las preguntas de la entrevista hacen que los programadores sean pobres.
mosquito
44
Es un problema de arquitectura de software legítimo. No es el tipo de problema que solo hace una buena pregunta de entrevista y nada más.
Karl Bielefeldt
77
¿Millones de usuarios se registran al mismo tiempo? De Verdad? Si tiene millones de usuarios que se registran al mismo tiempo, tiene mayores problemas, como manejar miles de millones de usuarios registrados. Y probablemente el dinero para pagar los servidores que lo manejan.
gnasher729
2
@AddzyK ¿Este es un problema hipotético que se enfrentará en el futuro para el que desea una solución lógica? Estoy bastante seguro de que está fuera de alcance aquí.
paparazzo
3
Aquí hay una respuesta hipotética: pagarle a alguien para que lo haga y que ya sepa qué hacer. Con millones de nuevos usuarios / segundo, tendrá el efectivo.
cuál es el

Respuestas:

15

Digamos que la base de datos no contiene el nombre de usuario 'usuario1'. Cuando dos usuarios intentan registrarse en el mismo momento con 'user1', lo aceptará.

¿Por qué lo aceptaría? Es simple aplicar una restricción única, usar el nombre de usuario como clave principal o simplemente ejecutar el cheque en el código de la aplicación dentro de una transacción.

Absolutamente debería poder usar una transacción de base de datos para usar la base de datos para evitar que esto ocurra. De lo contrario, ninguna aplicación podría mantener invariantes en los datos de la base de datos.

En términos de escala, las bases de datos ya inventaron las tecnologías que necesita, como varios modos de bloqueo dependiendo de exactamente qué tipo de consistencia necesita, bases de datos distribuidas para múltiples servidores de bases de datos, etc.

DeadMG
fuente
¿Bloquear los registros no impide que otros usuarios se registren al mismo tiempo?
Addzy K
2
+1, solo ejecuté algunas matemáticas difíciles, e incluso Facebook solo promedia algunos registros por segundo. Por lo tanto, basarse en las propias restricciones de la base de datos debería ser suficiente.
GrandmasterB
2
@AddzyK: el bloqueo solo se produce por el breve momento en que la base de datos debe imponer las restricciones. Sí, otros usuarios que se registran simultáneamente deben esperar en línea, pero esa espera es muy corta y rara vez ocurre de todos modos, incluso en los sistemas más grandes.
Robert Harvey
1
@GrandmasterB Los promedios pueden no contar la historia completa aquí. Supuse en base a la pregunta de que esto era para manejar cargas pesadas pico, por ejemplo, el material del censo australiano.
DeadMG
@AddzyK Podría hacerlo. Esencialmente, puede salirse con solo bloquear parte de la mesa. Existen numerosos esquemas para lidiar con esto, como la respuesta de gnasher729, pero creo que usted debería poder obtener un producto de base de datos distribuido que pueda manejar esto por usted. Incluso si tiene que implementar su propio esquema de bloqueo parcial, hay muchas formas conocidas de manejarlo, como DHT.
DeadMG
7

Hay una solución estándar para esto. Crear múltiples trabajadores para hacer los registros. Cada solicitud tiene un hash aplicado al nombre de usuario, y el hash determina qué trabajador procesa la solicitud. De esta manera, no hay forma posible de que dos solicitudes para el mismo nombre de usuario puedan procesarse simultáneamente.

Para este tipo de volumen de solicitudes, considere un almacén de valores clave distribuido, como el riesgo, en lugar de una base de datos completa como el almacén de datos.

Michael Shaw
fuente
2

Es un problema ?

Permitir que dos usuarios finalicen su registro con un nombre de usuario no único no es aceptable si se utiliza el nombre de usuario (y no el correo electrónico del usuario) para el inicio de sesión.

Si el nombre de usuario no se usa para la autenticación, puede usar un proceso en segundo plano para identificar y marcar los dobles (por ejemplo, según la marca de tiempo) y obligar al usuario a cambiar su nombre de usuario en el próximo inicio de sesión

Si, es un problema

Como está preguntando, supongo que se supone que el nombre de usuario es una identificación única. Se pueden utilizar los siguientes enfoques:

  1. Antes: en el proceso de registro, prevea un paso en el que el nuevo usuario tenga que verificar la disponibilidad de su nombre. Al hacerlo, reserve previamente el nombre de cuenta disponible con un estado temporal y una identificación de sesión que permitirá finalizar el registro.
  2. Mismo tiempo: una variante más general y flexible de la respuesta de gnasher729 sería utilizar una función hash simple (como las que se usan para administrar las tablas de símbolos), para asignar la identificación a un único servidor de registro módulo i (i = h (nombre de usuario) number_of_servers) que manejará la unicidad en su alcance limitado / segmentado
  3. Después: al final del registro, cuando el usuario hace clic en registerenviar la solicitud a su base de datos transaccional, si puede definir el campo como único. En caso de error, envíe al usuario desafortunado el mensaje "¡Vaya! Hubo un problema" y pídale que elija otra identificación.
  4. Asíncrono: registrar al usuario. Vuelva a leer el registro de usuario justo después para asegurarse de que no haya cambiado y que sea único. Si es un problema, solicite al usuario que cambie (no es tan asíncrono), o envíele un correo electrónico que indique que hubo un problema (asíncrono, pero molesto desde la perspectiva del usuario), o deje que se registre, pero solicite su correo electrónico (para desambiguar) y obligarlo a cambiar el nombre de usuario como parte del procedimiento de inicio de sesión.
Christophe
fuente
1

Reconsidere lo que considera el identificador único para un usuario. Cada usuario ya tiene una dirección de correo electrónico única, por lo que ese problema ya está resuelto. Por supuesto, esto significa que múltiples usuarios podrán registrar el mismo nombre, como "Mike Nakis". ¿Hay algún problema con eso? ¿Estás seguro? No es un problema para Facebook, por ejemplo. Existen múltiples usuarios de Facebook llamados "Mike Nakis". Mire la página de inicio de sesión de Facebook: pide "correo electrónico o teléfono" y "contraseña".

Mike Nakis
fuente
0

Con millones de usuarios que se registran al mismo tiempo, solo usa servidores de registro de 26 x 26, uno para usuarios que comienzan con aa, otro para usuarios que comienzan con ab y así sucesivamente. Como resultado, solo hay miles de usuarios que se registran en cada servidor al mismo tiempo. Si aún no puede manejar eso, use servidores de 26 x 26 x 26.

gnasher729
fuente
55
... y luego el dueño del producto quiere salir al exterior ...
Telastyn
2
Los mismos principios se aplican a las cadenas Unicode siempre que estén en una forma normalizada, como NFKD. También puede hacer un hash del nombre de usuario y aplicarlo en función del hash. Sin embargo, esta respuesta es básicamente solo implementar su propia base de datos distribuida.
DeadMG
1
¿Quiere decir que tienen millones de usuarios que se registran al mismo tiempo en un país ? En ese caso, deberían tener suficiente dinero para pagar más por una solución real.
gnasher729
Más específicamente, esto es solo el comienzo de cómo se hacen los DHT.
DeadMG
¿Cómo soluciona esto el problema de que dos usuarios registren el mismo nombre al mismo tiempo: ambos nombres comenzarían con los mismos dos caracteres y, por lo tanto, serían manejados por el mismo servidor de registro?
HorusKol