2008-09-18 5 views
9

He realizado muchas aplicaciones web donde 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 elementos 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.Separación de la tabla de usuarios de la tabla de personas en una base de datos relacional

¿Es razonable crear una segunda tabla, people_tb, que es la tabla relacional principal y el almacén de datos, y solo usar el 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?

Respuesta

8

Esto 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 usa 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 instrucció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.

1

Si user_tb tiene información de autenticación, la mantendría separada 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 usará para mucho más) Es una buena compensación entre el diseño y la eficiencia i pensar.

3

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, tendrá que 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.

0

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 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 users que tiene una relación 1 ~ 1 con people. Esta tabla puede almacenar el nombre de usuario y la contraseña.

0

Eso es definitivamente lo que hacemos ya que tenemos millones de registros 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.

+2

Tenga en cuenta que los UUID (GUID en MS land) realmente hacen claves pobres en muchos casos porque su aleatoriedad y tamaño anulan los mecanismos de indexación. Mejor es usar un número entero simple cuando sea posible. –

0

Me gustaría ir por 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.

0

Muy razonable.

Como ejemplo, eche un vistazo a las tablas de servicios aspnet_ * here.

Su construido en el esquema tiene un aspnet_Users y aspnet_Membership con la tabla de más adelante que tiene información más extensa acerca de un usuario dado (contraseñas hash, etc) pero el aspnet_User.UserID se utiliza en las otras porciones 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.

Cuestiones relacionadas