MySQL: varias tablas o una tabla con muchas columnas?

124

Entonces esta es más una pregunta de diseño.

Tengo una clave principal (por ejemplo, la identificación del usuario) y tengo toneladas de información asociada con ese usuario.

¿Debería tener varias tablas desglosadas en categorías según la información, o debería tener solo una tabla con muchas columnas?

La forma en que solía hacerlo era tener varias tablas, por ejemplo, una tabla para los datos de uso de la aplicación, una tabla para la información del perfil, una tabla para los tokens de back-end, etc. para mantener las cosas organizadas.

Recientemente, alguien me dijo que es mejor no hacerlo de esa manera y que tener una tabla con muchas columnas está bien. La cuestión es que todas esas columnas tienen la misma clave primaria.

Soy bastante nuevo en el diseño de bases de datos, ¿qué enfoque es mejor y cuáles son los pros y los contras?

¿Cuál es la forma convencional de hacerlo?

Xavier_Ex
fuente
Para mayor claridad, corríjame si me equivoco, pero creo que las "tablas múltiples" se pueden entender como enlace / tabla asociativa: en.wikipedia.org/wiki/Associative_entity
cellepo
1
¿Es necesaria esta base de datos para fines analíticos o para el procesamiento operacional / transaccional?
Alexander Radev

Respuestas:

112

Cada vez que la información es uno a uno (cada usuario tiene un nombre y una contraseña), entonces probablemente sea mejor tener una tabla, ya que reduce el número de uniones que la base de datos tendrá que hacer para recuperar resultados. Creo que algunas bases de datos tienen un límite en el número de columnas por tabla, pero no me preocuparía en casos normales, y siempre puede dividirlo más tarde si es necesario.

Si los datos son uno a muchos (cada usuario tiene miles de filas de información de uso), entonces se debe dividir en tablas separadas para reducir los datos duplicados (los datos duplicados desperdician espacio de almacenamiento, espacio de caché y dificultan el mantenimiento de la base de datos )

Puede encontrar interesante el artículo de Wikipedia sobre normalización de bases de datos , ya que analiza las razones de esto en profundidad:

La normalización de la base de datos es el proceso de organizar los campos y las tablas de una base de datos relacional para minimizar la redundancia y la dependencia. La normalización generalmente implica dividir tablas grandes en tablas más pequeñas (y menos redundantes) y definir relaciones entre ellas. El objetivo es aislar datos para que las adiciones, eliminaciones y modificaciones de un campo puedan realizarse en una sola tabla y luego propagarse por el resto de la base de datos a través de las relaciones definidas.

La desnormalización también es algo a tener en cuenta, porque hay casos en los que es mejor repetir datos (ya que reduce la cantidad de trabajo que la base de datos debe hacer al leer los datos). Recomiendo encarecidamente que sus datos estén lo más normalizados posible para comenzar, y solo desnormalizar si conoce problemas de rendimiento en consultas específicas.

Brendan Long
fuente
Gracias por su respuesta, así que después de leerlo, creo que de lo que estaba hablando era de la situación de información uno a uno, cuando un usuario tiene muchas columnas uno a uno.
Xavier_Ex
@Xavier_Ex: Sí, si solo hay una columna por usuario, entonces será más fácil trabajar con una gran tabla de usuarios (y mucho más fácil de optimizar para el motor DB).
Brendan Long
¡Tu publicación editada proporciona más información útil! Tengo una nueva preocupación de que si algunas de las columnas se actualizan con frecuencia, ¿debo ponerlas en tablas separadas? Por ejemplo, la fecha de nacimiento de un usuario no se actualizará nunca, pero el token de fondo puede invalidarse después de un período de tiempo y requerirá actualizaciones frecuentes. ¿Sería mejor si separo las tablas de esta manera para mejorar el rendimiento? Ahora iré a leer sobre el wiki que mencionaste :)
Xavier_Ex
@Xavier_Ex - No lo recomendaría. Obtiene un rendimiento significativamente mejor cuando puede buscar todos los datos que necesita en una tabla (consulte el artículo sobre desnormalización). Las uniones son caras porque (1) requieren buscar datos en varios lugares, lo que puede implicar búsquedas en un disco giratorio, (2) generalmente requieren múltiples índices y algún tipo de fusión, y (3) dificultan la planificación de consultas, lo que no solo lleva tiempo, pero también aumenta las posibilidades de que el optimizador de consultas obtenga algo incorrecto (y las consultas mal optimizadas pueden ser realmente lentas).
Brendan Long
1
Recientemente me enfrenté con este mismo problema, porque las tablas MySQL InnoDB tienen un límite de longitud relativamente pequeño (~ 8000 bytes). En mi tabla de problemas (datos de formularios de seguros muy largos, más de 100 columnas) tenemos múltiples columnas varchar, todas UTF8. Así que llenamos fácilmente el límite de ~ 8000 bytes y recibimos "error 139 del motor de almacenamiento" todo el tiempo. Entonces tuvimos que dividir la mesa. (Probamos con el nuevo formato Barracuda y funcionó sin división, pero los servidores de nuestros clientes aún usan MySQL 5.0).
MV.
12

Una mesa grande es a menudo una mala elección. Las tablas relacionadas son para qué base de datos relacional fueron diseñadas para trabajar. Si indexa correctamente y sabe cómo escribir consultas de rendimiento, van a funcionar bien.

Cuando las tablas tienen demasiadas columnas, puede tener problemas con el tamaño real de la página en la que la base de datos almacena la información. O bien, el registro puede terminar siendo demasiado grande para la página, en el cual puede que no pueda crear o actualizar un registro específico que haga que los usuarios estén descontentos o que (al menos en SQL Server) se le permita un desbordamiento en particular tipos de datos (con un conjunto de reglas que debe consultar si lo hace), pero si muchos registros desbordan el tamaño de la página, puede crear problemas de rendimiento tremendos. Ahora, cómo MYSQL maneja las páginas y si tiene un problema cuando el tamaño potencial de la página es demasiado grande es algo que tendría que buscar en la documentación de esa base de datos.

HLGEM
fuente
1
Ah voces diferentes! Lo cual siempre es genial. ¡Gracias por su información! Me aseguraré de estar al tanto de eso cuando haga mis tablas ... pero no sabía que tendría que estar al tanto de cosas de bajo nivel originalmente.
Xavier_Ex
4

Tengo un buen ejemplo Base de datos demasiado normalizada con el siguiente conjunto de relaciones:

people -> rel_p2staff -> staff

y

people -> rel_p2prosp -> prospects

Cuando las personas tienen nombres y detalles de personas, el personal tiene solo los detalles de registro del personal, los prospectos tienen solo detalles de prospectos, y las tablas rel son tablas de relaciones con claves externas de personas que se vinculan con el personal y los prospectos.

Este tipo de diseño continúa para toda la base de datos.

Ahora, para consultar este conjunto de relaciones, es una combinación de varias tablas cada vez, a veces 8 y más combinaciones de tablas. Ha estado funcionando bien hasta mediados de este año, cuando comenzó a ser muy lento ahora que superamos los 40000 registros de personas.

La indexación y todas las frutas bajas se utilizaron el año pasado, todas las consultas están optimizadas a la perfección. Este es el final del camino para que el diseño y la gestión normalizados en particular ahora aprueben una reconstrucción de la aplicación completa que depende de ella, así como la reestructuración de la base de datos, en un plazo de 6 meses. $$$$ Ouch.

La solución será tener una relación directa para people -> staffypeople -> prospect

Vlad
fuente
¿Estaría interesado en saber cómo fue la reconstrucción? ¿Terminó diseñando algo similar a la herencia de una sola tabla donde tenía un typeser a staffo a prospect?
Coderama
1
Fui con personas de relación directa -> personal y personas -> prospecto, funciona de maravilla, fácil de usar, rápido de consultar.
Vlad
4

Encontré esto, y como alguien que solía usar MySQL mucho, y luego se cambió a Postgres recientemente, una de las grandes ventajas es que puede agregar objetos JSON a un campo en Postgres.

Entonces, si se encuentra en esta situación, no tiene que decidir necesariamente entre una tabla grande con muchas columnas y dividirla, pero puede fusionar columnas en objetos JSON para reducirla, por ejemplo, en lugar de que la dirección sea 5 columnas, simplemente puede ser uno. También puede consultar sobre ese objeto también.

moinhaque
fuente
¿Qué pasa con el rendimiento cuando se usa el objeto json mientras se consulta?
dagalti
1
@dagalti el rendimiento está bien para las aplicaciones en las que lo he usado. No he hecho mi propia evaluación comparativa, pero esto podría serle útil: arangodb.com/2018/02/…
moinhaque
3

hágase estas preguntas si pone todo en una tabla, ¿tendrá varias filas para ese usuario? Si tiene que actualizar un usuario, ¿desea mantener un seguimiento de auditoría? ¿Puede el usuario tener más de una instancia de un elemento de datos? (como el número de teléfono, por ejemplo) ¿tendrá un caso en el que desee agregar un elemento o conjunto de elementos más adelante? Si responde que sí, lo más probable es que desee tener tablas secundarias con relaciones de clave externa.

Las ventajas de las tablas padre / hijo son la integridad de los datos, el rendimiento a través de índices (sí, también puede hacerlo en una tabla plana) y la OMI es más fácil de mantener si necesita agregar un campo más tarde, especialmente si será un campo obligatorio.

El diseño de contras es más difícil, las consultas se vuelven un poco más complejas

Pero, hay muchos casos en los que una mesa plana grande será apropiada, por lo que debe considerar su situación para decidir.

Brian
fuente
¡Gracias por recordarme! Entonces, en mi caso, solo estaba considerando el caso en el que cada usuario no puede tener más de una fila, por lo que todos los campos de información son uno a uno. Además, el usuario no puede tener más de una instancia del mismo elemento, ya que creo que el concepto de un elemento no puede existir en más de un lugar. Para la tercera pregunta, sí, podría agregar más elementos a la tabla, pero no romperán los requisitos que mencioné anteriormente. Creo que la tabla padre / hijo es buena cuando quiero asociar varias filas a un usuario, pero en este caso mi preocupación es que un usuario tenga muchas columnas uno a uno.
Xavier_Ex
incluso si todos los elementos son actualmente uno a uno, eso no elimina la necesidad o el deseo de tener tablas padre / hijo IMO. Mantener un registro de los datos modificados es un uso. cargar objetos perezosos es otro. Si bien hay beneficios para una estructura de tabla única, también hay beneficios para los diseños de padres e hijos (aunque también he visto a personas llegar a extremos con estos).
Brian
1

Ya he terminado de hacer algún tipo de diseño de base de datos. para mí, depende de la dificultad del sistema con la administración de la base de datos; Sí, es cierto tener datos únicos en un solo lugar, pero es realmente difícil hacer consultas con una base de datos demasiado normalizada con muchos registros. Simplemente combine los dos esquemas; use una tabla enorme si cree que tendrá registros masivos que son difíciles de mantener, como Facebook, Gmail, etc. y usar una tabla diferente para un conjunto de registros para un sistema simple ... bueno, esta es solo mi opinión ... espero que pueda ayudar ... solo hazlo ... puedes hacerlo ... :)

Christopher
fuente
1
"use una tabla enorme si va a tener registros masivos ..." Pero Facebook, Google no almacena los datos del usuario en una sola tabla, sino que los separó en tantas tablas.
Yami Odymel
0

La forma convencional de hacer esto sería usar diferentes tablas como en un esquema de estrella o esquema de copo de nieve. Sin embargo, basaría esta estrategia en dos veces. Creo en la teoría de que los datos solo deberían existir en un lugar, porque el esquema que mencioné funcionaría bien. Sin embargo, también creo que para los motores de informes y las suites de BI, un enfoque columnar sería muy beneficioso porque respalda más las necesidades de informes. Los enfoques de columnas como aquellos con infobright.org tienen enormes ganancias de rendimiento y compresión que hacen que el uso de ambos enfoques sea increíblemente útil. Muchas empresas están empezando a darse cuenta de que tener una sola arquitectura de base de datos en la organización no es compatible con la gama completa de sus necesidades. Muchas empresas están implementando tanto el concepto de tener más de una arquitectura de base de datos.

Craig Trombly
fuente
Gracias por la información, pero lo siento, no entiendo bien tu respuesta ... Haré una búsqueda en los dos esquemas que mencionaste primero ...
Xavier_Ex
-4

Creo que tener una sola tabla es más efectivo, pero debe asegurarse de que la tabla esté organizada de manera que muestre la relación, la tendencia y la diferencia en las variables de la misma fila. por ejemplo, si la tabla muestra la edad y las calificaciones de los estudiantes, debe ordenar la tabla de manera que, gracias al mejor puntaje, esté bien diferenciada con el puntaje más bajo y la diferencia en la edad de los estudiantes sea uniforme.

usuario8081853
fuente