¿Mantener usuario y perfil de usuario en diferentes tablas?

26

He visto en un par de proyectos que los desarrolladores prefieren mantener la información esencial del usuario en una tabla (correo electrónico / inicio de sesión, hash de contraseña, nombre de usuario) y el resto del perfil de usuario no esencial en otra (fecha de creación, país, etc.). Por no esencial quiero decir que estos datos se necesitan solo ocasionalmente. El beneficio obvio es que si está utilizando ORM, consultar menos campos es obviamente bueno. Pero luego puede tener dos entidades asignadas a la misma tabla y esto le ahorrará consultar cosas que no necesita (aunque es más conveniente). ¿Alguien sabe alguna otra ventaja de mantener estas cosas en dos tablas?

Andrey
fuente
1
@MichaelT gracias! Es interesante que no haya consenso en todas las preguntas vinculadas.
Andrey
Es por eso que fui con la lista de preguntas vinculadas en lugar de tratar de responderla yo mismo. Es realmente se reduce a una base de caso por caso y cómo se está Architected una aplicación particular. Recuerde, siempre puede usar una vista para juntar los dos bits si es necesario. Considere también la posibilidad de desvincular una (eliminar la cuenta), pero mantener la otra alrededor (las preguntas deben estar vinculadas a una cuenta, pero la cuenta no siempre tiene un perfil ...). Puede ser una pregunta interesante incluir en el chat de ingeniería de software o dirigirse a DBA.SE y preguntar en su chat.
1
@MichaelT Estoy pensando en crear una especie de marco generalizado que proporcione el modelo de usuario.
Andrey
En algunos proyectos anteriores, he movido a propósito columnas que se esperaba que se escribieran con mucha frecuencia en sus propias tablas separadas con el fin de proteger la tabla primaria en caso de que el archivo de la base de datos se corrompiera o dañara.
GrandmasterB

Respuestas:

11

Depende del tamaño y los requisitos de su proyecto.

Puedo ver una forma en que los datos sobre los usuarios se pueden dividir en dos conjuntos, con diferentes propósitos y, por lo tanto, requisitos:

  • Datos de identidad: nombre de usuario, hash de contraseña, dirección de correo electrónico, último tiempo de inicio de sesión, etc.
  • Datos de perfil de usuario, que incluyen las preferencias de los usuarios, la actividad más reciente, las actualizaciones de estado, etc.

Tenga en cuenta que hay algunos atributos sobre el usuario que pueden caer en cualquier categoría (por ejemplo, la fecha de nacimiento del usuario). Sin embargo, la diferencia entre estos dos conjuntos es que el primero está estrictamente controlado y solo a través de ciertos flujos de trabajo puede modificarse. Por ejemplo, cambiar una contraseña puede requerir proporcionar una contraseña existente, cambiar el correo electrónico puede requerir la verificación del correo electrónico, y se usaría en caso de que el usuario olvide la contraseña.

Las preferencias no requieren tales ACL y, en teoría, podrían ser modificadas por el usuario u otra aplicación siempre que el usuario lo consienta. Hay mucho en juego si una aplicación malintencionada o debido a un error corrompe los datos o intenta modificarlos (suponiendo que se tomen otras medidas de seguridad). Sin embargo, generalmente sería desastroso si se pudiera modificar alguno de los nombres de usuario, contraseñas o correos electrónicos. ya que pueden usarse para asumir la identidad del usuario o denegar el servicio o causar costos de soporte, etc. para el administrador.

Por lo tanto, generalmente los datos se almacenan en dos tipos de sistemas:

  • Los datos de identidad generalmente irán en un directorio o una solución IAM.
  • Los datos de preferencia terminarán en una base de datos.

Dicho esto, en la práctica, las personas violarán estas reglas y usarán una u otra (por ejemplo, un servidor SQL detrás del proveedor de membresía ASP.NET).

A medida que los datos de identidad se hacen más grandes o la organización que los usa se hace más grande, aparecen diferentes tipos de problemas. Por ejemplo, en el caso del directorio, intentará replicar los cambios de contraseña de inmediato a todos los servidores en un entorno multiservidor. Sin embargo, la preferencia del usuario solo requiere una coherencia eventual. (FYI: Ambas son optimizaciones diferentes del teorema de CAPS).

Finalmente, los directorios (especialmente los directorios en línea / en la nube) también emitirán tokens de acceso para otros recursos utilizando protocolos como OAUTH (por ejemplo, considere Facebook, Google, Cuenta de Microsoft, ADFS), mientras que una base de datos no tiene esa necesidad. Una base de datos admitirá combinaciones bastante complejas y estructura de consulta, que directorio no necesita.

Para más detalles, ayudarían algunas búsquedas en el directorio de identidad frente a la base de datos.

Eventualmente se reduce a cuáles son sus escenarios y se espera que sean en el futuro, incluida la integración con terceros (y lo que están utilizando). Si se trata de un proyecto bien contenido y está seguro de que puede proteger los datos de identidad del usuario y autenticarse correctamente, puede optar por la base de datos. De lo contrario, podría valer la pena investigar un directorio de identidad.

Si opta por DB, IMO, usar una DB vs dos eventualmente se reduciría al control de acceso, tanto para usuarios como para aplicaciones.

Omer Iqbal
fuente
3

Hay, al menos, tres casos en los que es deseable tener una tabla de persona para los atributos básicos y una segunda tabla para otros atributos con una relación uno a uno:

  • BLOB de datos como una imagen. Una tabla separada permite que los datos se almacenen por separado por razones de rendimiento, por ejemplo, en un espacio de tabla separado.
  • Datos que no se aplican a todos o que solo se aplican a una persona que desempeña un determinado rol. Piense en ello como columnas que serían nulas en muchas filas si fueran parte de la tabla principal. En la base de datos de una clínica, puede tener una tabla de personas, una tabla de pacientes y una tabla de médicos, en la primera tendría atributos básicos, en la segunda solo atributos pertinentes cuando la persona es un paciente como cobertura de seguro, en la tercera tabla (cuando la persona es un médico) podría tener la especialidad médica y otros datos que solo se aplican al personal médico. Obviamente, un médico puede ser un paciente.
  • Una tabla que materializa una relación con una entidad en un sistema remoto. En este caso, la tabla establece una equivalencia entre identificadores únicos en una base de datos separada por razones de interoperabilidad.

Creo que el caso que expones encaja en el segundo caso.

Tulains Córdova
fuente
1

Mi razón principal para mantenerlos separados es intentar evitar lo que se conoce en la programación orientada a objetos como una 'clase de dios'. Los ORM relacionan tablas y campos con clases y atributos, por lo que también se vuelve relevante como nivel SQL (incluso sin un ORM, generalmente hay un principio similar en juego).

La clase de usuario (y, por asociación, la tabla de usuario) es con frecuencia la tabla que se convierte en la clase divina con cientos de atributos / campos, docenas o cientos de métodos y una definición de clase (para los métodos) de más de 1000 líneas. Lo he visto todo. Mas de una vez.

Entonces, la separación del usuario intenta abordar eso. Puede haber persona, usuario, cuenta y la separación de las preocupaciones puede parecer un poco artificial, pero es para tratar de evitar la complejidad y garantizar que cada objeto solo se preocupe por 1 aspecto de los datos.

Michael Durrant
fuente
2
Incluso la clase de usuario hinchada todavía no es necesariamente una clase de Dios. Puede hincharse con la lógica relacionada con el usuario (que puede complicarse en grandes proyectos), pero si no incorpora lógica no relacionada, no veo un gran problema. No estoy seguro de cómo dividir 1 clase en 2 resolverá dicho problema de la clase de Dios.
Andrey