database - recomendaciones - porque se dañan las tablas en mysql
Separación de la tabla de usuarios de la tabla de personas en una base de datos relacional (7)
He hecho muchas aplicaciones web en las que lo primero que hace es crear una tabla de usuarios con nombres de usuario, contraseñas, nombres, correos electrónicos y todos los demás objetos flotantes habituales. Mi proyecto actual presenta una situación en la que los registros de los no usuarios deben funcionar de manera similar a los usuarios, pero no necesitan la capacidad de ser un usuario de primer orden.
¿Es razonable crear una segunda tabla, people_tb
, que es la tabla relacional principal y el almacén de datos, y solo usar los users_tb
para la autenticación? ¿La separación de user_tb
de people_tb
presenta algún problema? Si esto se hace comúnmente, ¿cuáles son algunas estrategias y soluciones, así como los inconvenientes?
Esta es ciertamente una buena idea, ya que está normalizando la base de datos. He hecho un diseño similar en una aplicación que estoy escribiendo, donde tengo una tabla de empleados y una tabla de usuarios. Los usuarios pueden a partir de una empresa externa o un empleado, por lo que tengo tablas separadas porque un empleado siempre es un usuario, pero un usuario no puede ser un empleado.
Los problemas con los que se encontrará es que cada vez que utiliza la tabla de usuarios, casi siempre querrá que la tabla de personas obtenga el nombre u otros atributos comunes que le gustaría mostrar.
Desde el punto de vista de la codificación, si está utilizando SQL directo, le tomará un poco más de esfuerzo analizar mentalmente la declaración de selección. Puede ser un poco más complicado si está usando una biblioteca ORM. No tengo suficiente experiencia con esos.
En mi aplicación, lo estoy escribiendo en Ruby on Rails, así que estoy constantemente haciendo cosas como employee.user.name, donde si las mantuviera juntas, sería solo employee.name o user.name.
Desde el punto de vista del rendimiento, está golpeando dos tablas en lugar de una, pero dados los índices adecuados, debería ser insignificante. Si tuvieras un índice que contuviera la clave primaria y el nombre de la persona, por ejemplo, la base de datos golpearía la tabla de usuario, luego el índice de la tabla de personas (con un impacto casi directo), por lo que el rendimiento sería casi el mismo tener una mesa
También podría crear una vista en la base de datos para mantener ambas tablas unidas para brindarle mejoras de rendimiento adicionales. Sé que en las versiones posteriores de Oracle incluso puede poner un índice en una vista si es necesario para aumentar el rendimiento.
Lo hago rutinariamente porque, para mí, el concepto de "usuario" (nombre de usuario, contraseña, fecha de creación, última fecha de inicio de sesión) es diferente de "persona" (nombre, dirección, teléfono, correo electrónico). Una de las desventajas que puede encontrar es que sus consultas a menudo requieren más combinaciones para obtener la información que está buscando. Si todo lo que tiene es un nombre de usuario, deberá unirse a la tabla "personas" para obtener el nombre y apellido, por ejemplo. Si basa todo en la clave principal de identificación de usuario, esto se mitiga un poco, pero aún aparece.
Muy razonable.
Como ejemplo, eche un vistazo a las tablas de servicios aspnet_ * aquí .
Su esquema integrado tiene aspnet_Users
y aspnet_Membership
con la tabla posterior con más información extendida sobre un usuario dado (contraseñas hash, etc.) pero el aspnet_User.UserID
se usa en las otras partes del esquema para la integridad referencial, etc.
En pocas palabras, es muy común, y un buen diseño, tener atributos en una tabla separada si son entidades diferentes, como en su caso.
Si user_tb tiene información de autenticación, lo mantendría separado de people_tb. Sin embargo, mantendría una relación entre los dos, y la mayoría de la información de los usuarios se almacenaría en people_tb, excepto toda la información necesaria para auth (que supongo que no se utilizará para mucho más) Es una buena compensación entre el diseño y la eficiencia i pensar.
Siempre trato de evitar tanta repetición de datos como sea posible. Si no todas las personas necesitan iniciar sesión, puede tener una tabla genérica de people
con la información que se aplica a personas y usuarios (por ejemplo, nombre, apellido, etc.).
Luego, para las personas que inician sesión, puede tener una tabla de users
que tenga una relación de 1 a 1 con las people
. Esta tabla puede almacenar el nombre de usuario y la contraseña.
Yo diría que elegir el diseño normalizado (dos tablas) y solo desnormalizar (bajar a una tabla de usuario / persona) si realmente hará su vida más fácil en la línea. Sin embargo, si prácticamente todas las personas también son usuarios, puede ser más simple denormalizar por adelantado. Tu decides; He usado el enfoque normalizado sin problemas.
Eso es definitivamente lo que hacemos ya que tenemos registros de millones de personas y solo miles de usuarios. También separamos direcciones, teléfonos y correos electrónicos en tablas relacionales ya que muchas personas tienen más de una de estas cosas. Crítica es no confiar en el nombre ya que el identificador como nombre no es único. Asegúrese de que las tablas estén unidas mediante algún tipo de clave sustituta (un entero o un GUID es preferible) sin nombre.