Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

[SOLUCIONADO] cumpliendo la 1FN (atomicidad)

Estas en el tema de cumpliendo la 1FN (atomicidad) en el foro de Mysql en Foros del Web. Hola a todos. Vereis, tengo un problema con la estructura de una tabla en una base de datos. El problema es que no cumple la ...
  #1 (permalink)  
Antiguo 12/04/2013, 04:18
 
Fecha de Ingreso: junio-2010
Mensajes: 373
Antigüedad: 13 años, 10 meses
Puntos: 11
cumpliendo la 1FN (atomicidad)

Hola a todos.

Vereis, tengo un problema con la estructura de una tabla en una base de datos.
El problema es que no cumple la 1ª forma normal (1FN).

La tabla almacena datos de una clasificacacion de usuarios, de esta forma:

ID------------pos
1----------12,3,11,...
2----------17,6,16,...
3----------14,4,7,...
4----------22,21,20,...
...

El caso es que no cumple la 1FN porque meto en el registro de cada usuario todos los datos de la clasificacion. Lo hice asi en un principio (a sabiendas de que lo estaba haciendo mal) porque no se me ocurria otra forma de hacerlo, pero hoy dia esto ya me esta resultando molesto.

La cosa es que desde el dia 1 se me ocurren otras formas de hacerlo pero tampoco a esto se le puede llamar "hacerlo bien":

ID------------dia1------------dia2--------dia3
1---------------12--------------3------------11
2---------------17--------------6------------16
3---------------14--------------4-------------7

Estamos en las mismas porque los campos no serian fijos.

ID------------dia------------pos
1---------------1--------------12
1---------------2--------------3
1---------------3--------------11
2---------------1--------------17
2---------------2--------------6
2---------------3--------------16
3---------------1--------------14
3---------------2--------------4
3---------------3--------------7

Mas de lo mismo. El ID pierde su unicidad, aparte de que el nº de registros se haria brutal.

En definitiva....que puedo hacer para hacer esto bien de una puñetera vez???

Desde ya mismo, muchas gracias por la atencion.

Un saludo a todos.
  #2 (permalink)  
Antiguo 12/04/2013, 06:25
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: cumpliendo la 1FN (atomicidad)

No es mas de lo mismo.

Resultados
ID FK referenciando usuarios
dia
pos
<- PK (ID,dia)

ID------------dia------------pos
1---------------1--------------12
1---------------2--------------3
1---------------3--------------11
2---------------1--------------17
2---------------2--------------6
2---------------3--------------16
3---------------1--------------14
3---------------2--------------4
3---------------3--------------7

Con la información que das la forma correcta es esta.

Cita:
El ID pierde su unicidad
Esa tabla no es de usuarios si no de resultados, puedes agregar un idResultado (autoinc) y usarlo como PK mas un indice único sobre ID+Dia, o usar la PK compuesta ID+Dia, ya tenemos la unicidad perdida. Más una tabla de usuarios aparte donde el id sea único (PK).

Usuarios
ID PK
nombre
....otros

Cita:
el nº de registros se haria brutal
No es un dato relevante a nivel teórico. Otra cosa es que tu equipo no este dimensionado para el volumen de datos a manejar.

Hay dos formas de salvar la situació,
1. crear indices, la PK compuesta lo es por definición, los indices permiten trabajar con muchos registros de forma rápida. No puedo decirte que indices crear puesto que no se que vas a hacer con los datos pero con esos campos no hay muchos mas.
2. crear procesos de mantenimiento de la bbdd que eliminen los resgistros no necesarios o que los guarden en una tabla resultados historicos, de tal forma que la tabla operativa solo tenga los registros imprescindibles.

He dicho
Cita:
Con la información que das la forma correcta es esta.
Si explicas como se calcula o de donde sale esa "posición" quizas encontrariamos otras formas de hacerlo.

En cualquier caso tu error es intentar resolverlo en una sola tabla.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 12/04/2013 a las 06:36
  #3 (permalink)  
Antiguo 12/04/2013, 06:30
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: cumpliendo la 1FN (atomicidad)

Un detalle: En realidad, no estás cumpliendo con la 1FN al separar los datos de esa forma, porque la atomicidad no sólo implica que no haya campos multivaluados, sino que tampoco haya dominios solapados (Ver Ejemplo 2 en Wikipedia). Es decir, no deben existir dos o más campos cuyo dominio de existencia sea el mismo.
Para dar un ejemplo: No puedes tener dos campos para ciudades en un mismo registro referidas a un sólo domicilio.
Si tienes N fechas referidas a N usuarios, lo que tienes es una relación N:N entre fechas y usuarios, lo que implica obligatoriamente la existencia de una tabla relacional en que cada fecha se relacione con un usuario una única vez, tal como te lo explica quimfv.
De hecho, como también menciona correctamente quimfv, no se requiere un identificador adicional en esa tabla, a menos que un mismo usuario pueda tener la misma fecha más de una vez al mismo tiempo. En vez de eso, simplemente creas una PK compuesta.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #4 (permalink)  
Antiguo 12/04/2013, 13:46
 
Fecha de Ingreso: junio-2010
Mensajes: 373
Antigüedad: 13 años, 10 meses
Puntos: 11
Respuesta: cumpliendo la 1FN (atomicidad)

Ok, creo que lo he entendido bastante bien.

Respondiendo a lo que me preguntabas, quimfv:

Cita:
Si explicas como se calcula o de donde sale esa "posición" quizas encontrariamos otras formas de hacerlo.
La posicion sale de un ordenado standart de datos, como por ejemplo podria ser el nº de mensajes publicados aqui, o los puntos (antiguo karma).

No dispongo ahora mismo del codigo pero es algo muy parecido a esto:
Código SQL:
Ver original
  1. SELECT nombre, experiencia AS total FROM usuarios ORDER BY total DESC
Luego le asigno a cada usuario la posicion y hago el UPDATE (con un CONCAT).
El motivo de "la guarrada esa" de guardar las antiguas posiciones es para tener un historial de dicha posicion.

Por otro lado, en esto que me comentas, gnzsoloyo:
Cita:
...a menos que un mismo usuario pueda tener la misma fecha más de una vez al mismo tiempo...
Resulta que esa posicion sí que se actualiza varias veces al día, pero os habeis explicado ambos bastante bien y creo que "lo he pillado".

Deberia (en total) hacer algo como lo siguiente:

Campos:
ID
dia
numero de actualizacion
posicion
<-- ID es una FK
<--(ID,dia,num.actualizacion) es una PK compuesta.


Bueno, muchisimas gracias a ambos pq llevaba ya bastante tiempo dandole vueltas a esto y en unos minutos me lo habeis resuelto.
  #5 (permalink)  
Antiguo 14/04/2013, 05:05
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: cumpliendo la 1FN (atomicidad)

Cita:
"la guarrada esa"
Es en si misma un error puesto que esas posiciones son calculos sobre datos que ya tienes, el historico debes buscarlo de otra forma.

Como la "puntuación" tiene o deberia tener una fecha (en formato DATETIME) siempre puedes hacer una consulta que te de la posición de los usuarios en una fecha determinada, apartir de las "puntuaciones" y sus fechas. Pero debería ver la estructura de la tabla donde guardas las puntuaciones para estar seguro de lo que te digo.

Si optas por la solución, mala, que tienes planteada no necesitas ese "numero de actualización" si dia tiene formato DATETIME puesto que no tendras dos actualizaciones con la misma fecha y hora+minuto+segundo+milisegundo.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #6 (permalink)  
Antiguo 14/04/2013, 17:09
 
Fecha de Ingreso: junio-2010
Mensajes: 373
Antigüedad: 13 años, 10 meses
Puntos: 11
Respuesta: cumpliendo la 1FN (atomicidad)

Cita:
Como la "puntuación" tiene o deberia tener una fecha (en formato DATETIME) siempre puedes hacer una consulta que te de la posición de los usuarios en una fecha determinada, apartir de las "puntuaciones" y sus fechas.
Perfecto, ya comprendo como me aconsejas hacerlo. Mucho más fácil y adecuado.

PD: prefiero no mostrarte la tabla porque te ibas a echar a llorar.

Gracias de nuevo.

Etiquetas: campo, registros, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:00.