MySQL - 1 columna integer grande vs 2 columnas integers pequeños

 
Vista:
sin imagen de perfil
Val: 3
Ha disminuido su posición en 14 puestos en MySQL (en relación al último mes)
Gráfica de MySQL

1 columna integer grande vs 2 columnas integers pequeños

Publicado por Alberto J. (2 intervenciones) el 03/11/2017 21:44:39
La situación es la siguiente:

Tengo dos columnas cuyos datos son dos números enteros, uno de unos 4 o más dígitos (que es una puntuación) y el otro de 2 dígitos (que es un porcentaje), por ejemplo: 4444 y 22. Además dichos datos siempre van de la mano, es decir; el segundo número (el porcentaje en este caso) complementa la información que da el primero.

La cuestión es: ¿merece la pena tener sólo una columna con los dos datos (por ejemplo de la forma 444422)?, en tal caso, quiera usarlos bastaría realizar un cálculo (php) para separar los valores.

Cuando digo si merece la pena, lo pregunto desde el punto de vista de la velocidad y rendimiento, es decir; ¿lo que se gana al operar con 1 columna en lugar de con 2 columnas en este caso reporta un beneficio claro teniendo en cuenta que cada vez que quiera recuperar y separar los datos el servidor tendrá que, además de leer el dato, realizar una operación con él?

(Tengan en cuenta que son muchos usuarios y muchos registros, obviamente)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 953
Oro
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

1 columna integer grande vs 2 columnas integers pequeños

Publicado por leonardo_josue (414 intervenciones) el 03/11/2017 23:26:21
Hola AlbertoJ.

En realidad, en el diseño de BD's no hay una "mejor" o "peor" forma de modelar tus datos, sino que depende completamente de tus necesidades, sin embargo, también hay algunas reglas que te pueden ayudar al momento de diseñar tus tablas y que tienen que ver también con el concepto de Bases de Datos NORMALIZADAS (si no conoces este tema, te sugiero que investigues sobre este tema

https://es.wikipedia.org/wiki/Normalización_de_bases_de_datos

en este sentido, la 1FN dice lo siguiente:

1
2
3
4
Una tabla está en Primera Forma Normal si:
 
Todos los atributos son atómicos. Un atributo es atómico si los elementos del dominio son simples e indivisibles.
...

En otras palabras: NO DEBES TENER MÚLTIPLES VALORES EN UN CAMPO... por lo tanto la idea de poner algo tus valores "juntos" (444422) es completamente inaceptable así es que OLVIDATE DE ELLA.

Segundo, si un campo es CALCULADO, PUEDES PRESCINDIR DE TENERLO EN UNA TABLA...

Por ejemplo, si tuvieras una tabla CIRCULO, podrías tener los atributos RADIO, DIAMETRO y ÁREA, además el valor de Pi, por lo tanto, podrías tener una estructura así:

1
2
3
4
5
6
7
8
9
10
11
mysql> SELECT * FROM circulos;
+-------+----------+----------+----------------+-----------+
| radio | PI     | diametro | circunferencia | AREA      |
+-------+----------+----------+----------------+-----------+
|     1 | 3.141593 |        2 |       6.283185 |  3.141593 |
|     2 | 3.141593 |        4 |      12.566371 | 12.566371 |
|     3 | 3.141593 |        6 |      18.849556 | 28.274334 |
|     4 | 3.141593 |        8 |      25.132741 | 50.265482 |
|     5 | 3.141593 |       10 |      31.415927 | 78.539816 |
+-------+----------+----------+----------------+-----------+
5 rows in set (0.00 sec)

Sin embargo, la mayoría de estos campos SON COMPLETAMENTE INÚTILES, ya que el único dato que realmente necesitas es el valor del RADIO, el resto de los campos, los puedes calcular:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mysql> select * from circulos;
+-------+
| radio |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
|     5 |
+-------+
5 rows in set (0.00 sec)
mysql> SELECT
    ->   radio,
    ->   PI() PI,
    ->   2*radio diametro,
    ->   2*PI()*radio circunferencia,
    ->   PI()*radio*radio AREA
    -> FROM circulos;
+-------+----------+----------+----------------+-----------+
| radio | PI       | diametro | circunferencia | AREA      |
+-------+----------+----------+----------------+-----------+
|     1 | 3.141593 |        2 |       6.283185 |  3.141593 |
|     2 | 3.141593 |        4 |      12.566371 | 12.566371 |
|     3 | 3.141593 |        6 |      18.849556 | 28.274334 |
|     4 | 3.141593 |        8 |      25.132741 | 50.265482 |
|     5 | 3.141593 |       10 |      31.415927 | 78.539816 |
+-------+----------+----------+----------------+-----------+
5 rows in set (0.00 sec)

¿Se entiende la idea?

Y en cuanto al rendimiento, en realidad depende de muchos factores, no solo de este tipo de cálculos. si tienes millones de registros, entonces podrías "preocuparte" un poco, pero si no es así, en realidad no hace diferencia el cómo lo hagas.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 3
Ha disminuido su posición en 14 puestos en MySQL (en relación al último mes)
Gráfica de MySQL

1 columna integer grande vs 2 columnas integers pequeños

Publicado por Alberto J. (2 intervenciones) el 04/11/2017 10:18:28
Efectivamente, en mi caso, los datos son independientes claro, pero al estar relacionados me podría plantear juntarlos para que a la hora de recuperarlos, mediante una operación, obtenerlos por separado. Ejemplo:

Opción A:

+-------+------------+-------------------------------
| Nivel | Capítulo | Título
+-------+------------+-------------------------------
| 1 | 1 | Capítulo 1 del nivel 1
| 1 | 2 | Capítulo 2 del nivel 1
| 1 | 3 | Capítulo 3 del nivel 1
| 1 | 4 | Capítulo 4 del nivel 1
| 2 | 1 | Capítulo 1 del nivel 2
| 2 | 2 | Capítulo 2 del nivel 2


Opción B:

+--------------------+-------------------------------
| Nivel_Capitulo | Título
+--------------------+-------------------------------
| 101 | Capítulo 1 del nivel 1
| 102 | Capítulo 2 del nivel 1
| 103 | Capítulo 3 del nivel 1
| 104 | Capítulo 4 del nivel 1
| 201 | Capítulo 1 del nivel 2
| 202 | Capítulo 2 del nivel 2

Con la Opción B, al recuperar el campo nivel_capitulo, tomaría, por ejempo:

nivel = floor(nivel_capitulo/100)
capitulo = nivel_capitulo-nivel*100

No obstante, el número de registros de la tabla en cuestión no llega al millón, así que lo dejaré en dos columnas. No obstante, me lo plantearé para otras tablas que sí llegarán a tener millones de registros.

Muchas gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 953
Oro
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

1 columna integer grande vs 2 columnas integers pequeños

Publicado por leonardo_josue (414 intervenciones) el 06/11/2017 15:32:44
Hola de nuevo Alberto:

1
los datos son independientes claro, pero al estar relacionados me podría plantear juntarlos para que a la hora de recuperarlos, mediante una operación, obtenerlos por separado.

Vuelvo a poner mi comentario:

1
NO DEBES TENER MÚLTIPLES VALORES EN UN CAMPO... por lo tanto la idea de poner algo tus valores "juntos" (444422) es completamente inaceptable así es que OLVIDATE DE ELLA.

Si tanto te "preocupa" el rendimiento, mejor pon atención a un correcto uso de índices y en optimización de consultas más que en andar pensando en "ahorrarte" un campo si es que los pones juntos.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar