2009-01-09 9 views
7

Estoy en el proceso de trabajar en un sistema de perfil de usuario para un sitio web y estoy reflexionando sobre cuál sería un enfoque mejor (escalable). He encontrado dos soluciones y estoy buscando insumos o tal vez consejos sobre algo que podría haber perdido.¿Elegir un método para almacenar perfiles de usuario?

Las siguientes instrucciones de creación de tablas no están destinadas a ser ejecutables, sino que están simplemente ahí para dar una idea del diseño de las tablas involucradas.

Mi idea inicial era algo como esto:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, 

    user_email VARCHAR(320), 

    user_joined DATATIME, 
    user_last_seen DATATIME, 

    user_name_first VARCHAR, 
    user_name_last VARCHAR, 

    user_name_alias VARCHAR, 

    user_location_country VARCHAR, 
    user_location_region VARCHAR, 
    user_location_city VARCHAR 

    # ... 
); 

Obviamente, esto no es muy escalable en absoluto y añadiendo propiedades adicionales i molesto. La única ventaja es que puedo buscar rápidamente usuarios que coincidan con un conjunto específico de propiedades. He hecho un poco de mirar alrededor y este es un enfoque bastante común (por ejemplo, Wordpress).

Mi segundo enfoque (el que actualmente estoy jugando un poco con) es mucho más escalable, pero estoy un poco preocupado por el rendimiento:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, 

    user_email VARCHAR(320) 
); 

CREATE TABLE user_profile(
    user_id INT UNSIGNED NOT NULL, 

    visibility ENUM('PRIVATE', 'PUBLIC'), 

    name VARCHAR, 
    value VARCHAR 
); 

uso de este enfoque de cada uso tiene un conjunto de valor clave pares asociados con él, lo que hace que agregar propiedades adicionales sea trivial, así como cargar el perfil de los usuarios cuando inician sesión. Sin embargo, pierdo toda la información de tipo que tenía en el primer enfoque (por ejemplo, DATETIME ahora está almacenado como una cadena formateada), por lo que algunas búsquedas se vuelven molestas. Esto me da más control sobre la selección de las propiedades que el usuario quiere que se muestren públicamente.

¿Sería mejor un enfoque híbrido, permitiéndome equilibrar las ventajas y desventajas de ambos métodos? ¿Qué método usa SO? ¿Hay algún otro enfoque al respecto que no haya pensado o pasado por alto?

Extensión: Con un enfoque híbrido ¿sería ventajoso también insertar las propiedades de la tabla de usuario en la tabla de perfil de usuario para controlar su visibilidad a otros usuarios o podría ser vista como una sobrecarga adicional?

Respuesta

3

La solución híbrida no es buena. Básicamente, está almacenando propiedades adicionales en una tabla de bolsas de propiedades. Eso hará que hacer reportes y consultas sea complicado a largo plazo. Además, almacenar fechas, int, decimal, ntext, etc. como varchar no va a ser un intercambio de rendimiento aceptable para la escalabilidad. ¿Cómo crearías relaciones fuera de esa mesa, si surgiera la necesidad?

Un mejor enfoque es tener una tabla de usuario para la información del usuario.Luego, a medida que crezcan sus necesidades, cree nuevas clases que representen las nuevas funciones. Esas nuevas clases probablemente tendrán las tablas correspondientes. De esta forma, su clase de "usuario" no se expande exponencialmente cuando las propiedades asociadas con un usuario pertenecen a su propio espacio. Sí, en el futuro es posible que realmente tenga una propiedad nueva que pertenezca a la tabla de usuarios. En ese momento, tendrá que volver atrás y ajustar su esquema y DBAL, pero ese es el precio del código que es fácil de entender.

En su ejemplo, tiene información de dirección para el usuario en la primera tabla de usuario. Una cosa que hago es saber que necesitaré almacenar direcciones no solo para los usuarios. Así que tendré una tabla de direcciones por separado y luego incluiré un AddressId nulo en la tabla de usuarios. De esa manera, cuando tengo una tabla de tiendas, una tabla de eventos, puedo incluir también las relaciones de AddressId. Un efecto secundario de ese enfoque es que cuando regreso y agrego lat/long al objeto Address, todos en mi modelo de datos también obtienen esas nuevas propiedades.

+0

Me parece que (y corríjanme si me equivoco) que este enfoque estaría sujeto a lo largo del tiempo a la "infinidad de mesas" con muchas tablas añadidas a la base de datos para agregar diferentes funcionalidades. –

+0

No estoy seguro de que la hinchazón de la mesa sea realmente un problema. Si tiene una aplicación con 1000 puntos de característica pero solo 5 tablas, sería muy escéptico sobre la normalización de las tablas. Martin Fowler analiza el patrón de diseño del módulo de tabla aquí: http://martinfowler.com/eaaCatalog/tableModule.html – DavGarcia

4

Utilizaría un enfoque híbrido. Algunas propiedades básicas como nombre de usuario, correo electrónico, lastlogindate, etc. deben agregarse a su tabla de usuarios. Los elementos de importancia secundaria se pueden agregar como pares clave/valor.

De esta forma, aún puede buscar fácilmente la información más importante y seguir agregando elementos de perfil sin cambios de esquema.

0

Me gustaría ir con la solución híbrida también, por razones de rendimiento y escalabilidad de diseño.

Tiendo a pensar que tablas como users (también me gusta el plural en los nombres de tablas) deben dividirse en un conjunto de datos comúnmente utilizados por otros objetos, y esos bits extendidos de datos básicamente de solo escritura en el especificaciones como "región", "medio-inicial", "tamaño del zapato" se pueden desplazar a un área extensible y menos actualizada con frecuencia.

0

¿Por qué no tener un campo XML para almacenar la información adicional que no es esencial.

Esto se puede configurar en el archivo de configuración e incluso se puede ir un paso más allá y generar los controles de la interfaz de usuario desde la configuración.

+0

XML es la herramienta incorrecta para esto, resultaría en consultas increíblemente ridículas si tuviera que hacer algo con esa información no esencial. Tendría que analizar el XML de cada resultado antes de poder hacer algo que matara el rendimiento. –

+0

Microsoft usa el mismo enfoque para su proveedor de membresía. Échale un vistazo. También hay soluciones similares del proveedor como los chicos han explicado anteriormente. Probablemente tenga razón sobre el rendimiento, por lo que se recomienda que solo almacene información en el XML que no desee consultar. –

Cuestiones relacionadas