¿Es una buena idea dividir una tabla de 'usuarios' para fines de autenticación?

8

Supongamos que tengo una tabla de usuario en mi sitio en la que hay alrededor de 2-3 millones de usuarios (registros) en la tabla.

Para acelerar mi proceso de inicio de sesión, ¿es un buen enfoque dividir mi tabla de usuarios, una para su información y otra para su inicio de sesión?

Si podemos ejecutar una consulta similar a la siguiente desde una tabla:

select username,password from users where username=`test` AND password=****

¿Es necesario dividirlo y esto acelera el proceso de inicio de sesión de mi sitio?

ALH
fuente
1
Agregando esto solo como un comentario, ya que no es una respuesta directa a su pregunta. Quizás esto es lo que está haciendo más allá de su consulta de muestra, pero es una muy mala práctica almacenar las contraseñas reales en su base de datos. Desea almacenarlos como has y luego consultar como donde password_hash = hash ($ userEnteredPassword)
atxdba
@atxdba Realmente los trillé, pero aquí solo di un ejemplo.
ALH

Respuestas:

10

En mi humilde opinión, no es necesario dividirlo físicamente. Sin embargo, sería bueno almacenarlo en caché.

Si la userstabla usa el motor de almacenamiento MyISAM, tiene una buena ventaja.

Dado que MyISAM solo almacena en caché los índices, puede hacer dos cosas

  • Puede crear un caché de claves personalizado solo para cargar el índice MyISAM userssolo para la tabla
  • Puede indexar el nombre de usuario y la contraseña para forzar que la consulta golpee solo esa caché de claves personalizada

Asegúrese de que existan los siguientes índices para users

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

Hay dos (2) razones principales para los dos índices

MOTIVO del índice n. ° 1

El índice username_ndxevita que un nombre de usuario tenga múltiples contraseñas, así como también evita que varios usuarios con el mismo nombre

MOTIVO del índice n. ° 2

El índice username_password_ndxproporciona un índice de cobertura . Por lo tanto, su consulta buscará el nombre de usuario y la contraseña solo en el caché MyISAM personalizado, en lugar de verificar la tabla.

Más enlaces sobre los principios de los índices de cobertura

Lo siguiente es crear esa caché de claves personalizada. Estos son los comandos para crear un caché de claves de 8 MB y cargar ese caché de claves dedicado (Ejemplo: si la tabla es mydb.users):

SET GLOBAL authentication_cache.key_buffer_size = 1024 * 1024 * 8;
CACHE INDEX mydb.users IN authentication_cache;
LOAD INDEX INTO CACHE mydb.users;

Debe colocar estas tres líneas en el archivo /var/lib/mysql/startup.sql

Agregue esto a /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/startup.sql

Esto cargará el caché cada vez que se inicia mysql

Darle una oportunidad !!!

ACTUALIZACIÓN 2011-12-30 17:25 EDT

Si desea obtener el tamaño exacto para configurar el caché, use la siguiente consulta:

SELECT CONCAT('1024 * 1024 * ',ROUND(index_length/power(1024,2))) RecommendedCacheSize
FROM information_schema.tables WHERE table_name='users';

ACTUALIZACIÓN 2011-12-30 23:21 EDT

Aquí hay un método basado en InnoDB

Aún necesitas los índices

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

Debe asegurarse de que el InnoDB Buffer Pool tenga los nombres de usuario y las contraseñas disponibles. Es posible que tenga que recurrir a hacer un análisis de índice completo al iniciar mysql:

Paso 1) Crear ReadUserPass.sql

echo "select username,password from users;" > /var/lib/mysql/ReadUserPass.sql

Paso 2) Agregue ese script a /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/ReadUserPass.sql

Paso 3) Realice uno de los siguientes

  • $ service mysql restart
  • mysql> source /var/lib/mysql/ReadUserPass.sql

Debido a que ambas columnas (nombre de usuario y contraseña) residen en username_password_ndx, todas las páginas de índice que componen este índice se vuelven a cargar en el InnoDB Buffer Pool. Esto es necesario porque existe la posibilidad de que las páginas de índice se eliminen. Para minimizar que eso suceda, aumente el tamaño de la agrupación de almacenamiento intermedio y reinicie mysql (una vez).

RolandoMySQLDBA
fuente
En realidad, uso el motor de almacenamiento InnoDB, pero creo que el proceso de caché estaría bien, ¿no es @RolandoMySQLDBA?
ALH
No. Los pasos en mi respuesta son solo MyISAM.
RolandoMySQLDBA
Si la userstabla está involucrada en transacciones, entonces necesito enviar otra respuesta basada únicamente en InnoDB.
RolandoMySQLDBA
Lo siento, no mencioné eso, ¡no sabía que tendrían enfoques diferentes!
ALH
Respondí basado en MyISAM porque quería que la tabla de usuarios se almacenara en caché en su propio búfer de claves.
RolandoMySQLDBA
5

No debería ser necesario dividir una tabla de un par de millones de filas. El ajuste del rendimiento debe hacerse a través de índices. MySpace tenía cientos de millones de cuentas en una sola tabla y el rendimiento en esa tabla estuvo bien. (Yo era un DBA para MySpace en el punto más alto de su uso). La tabla en ese caso probablemente tenía entre 80 y 90 bytes de ancho (quizás un poco más).

mrdenny
fuente
Eh, ¿cómo era el tamaño de la RAM?
Chibueze Opata
3

¿Realmente tienes 2 millones de usuarios? A menos que ya tenga este problema o esté seguro de que lo hará, está optimizando con mucha anticipación. Agregue un índice compuesto en los campos de inicio de sesión y contraseña y termine con él. No optimice a menos que sepa que realmente tiene un problema que resolver. Estoy seguro de que tienes problemas más grandes que resolver.

Aaron Brown
fuente
1
¿Qué quieres decir con "estás seguro de que tengo mayores problemas que resolver"?
ALH
1
No tiene sentido resolver problemas cuando sabemos que en un futuro cercano nos encontraremos con muchos problemas. ¡Esta solución de problemas es un dolor de cabeza cuando hay muchos datos en la tabla! -1 para ti.
ALH
2
Mi punto es doble ... no optimices antes de tener que hacerlo y 2 millones de registros no son muchos. Un índice será suficiente.
Aaron Brown
2

Si usa Mysql 5.1 y superior, puede intentar particionar su tabla.
En cuanto a su pregunta sobre si acelera el proceso de inicio de sesión, depende de cómo se vea el resto del procedimiento de inicio de sesión (por ejemplo, si su consulta ahora toma 0.05 segundos y el resto del código tarda 20 segundos, prefiero volver a pensar en toda la rutina ...)
Además, independientemente de usar particiones, no olvide agregar índices como lo señaló RolandoMySQLDBA .

a1ex07
fuente
Una buena decisión para determinar la causa real de un problema de rendimiento antes de optimizar. A menudo no está donde creemos que está. ¡El ajuste basado en evidencia es el camino a seguir!
Stuart Woodward