[Php-avanzado] Normalizacion Juan Manuel V3

Juan Manuel P. tucu_21 en hotmail.com
Sab Dic 8 02:18:32 ART 2012


Leo, te respondo abajo de cada consulta y pego al final la ultima version de la normalizacion que acabo de corregir.


> From: leonardot en pegasusnet.com.ar
> To: php-avanzado en pato2.fi.mdp.edu.ar
> Date: Sat, 8 Dec 2012 01:33:41 -0300
> Subject: Re: [Php-avanzado] Normalizacion Juan Manuel V2
> 
> Hola Juan Manuel,
> 
> El vie, 07-12-2012 a las 21:42 -0300, Juan Manuel P. escribió:
> > Leo te contesto abajo y copio la V2 de la normalizacion abajo de todo.
> 
> 	Ok. La estuve ojeando y venís avanzando muy bien.
> 	Si te quedan dudas de algo, consultame por acá o lo charlamos en clase,
> porque la idea de este proceso no es que me des la razón, sino que
> comprendas el software que tenés que construir y cómo se crea un
> almacenamiento normalizado para este caso en particular.
> 
> 
> 	Como siempre, dejo solo la parte que requiere algún comentario,
> pregunta o corrección:
> 
> > > Eso es una falacia ad hominem!
> > > Son muchos más los seres humanos que no saben normalizar que los que
> > sí
> > > saben, y esto no significa que normalizar esté mal.
> > > Sin embargo, si creés que estoy interpretando mal la teoría de
> > > Boyd-Codd, me gustaría conocer tu opinión al respecto, porque todos
> > > podemos equivocarnos.
> > > 
> > 
> > No para nada sino que luego de trabajar durante un año ahi me
> > acostumbre a que cuando tenia datos de esta forma los manejaba con
> > codigos numericos y era el codigo el que sabia como interpretarlos.
> > Pero son vicios que quedan de experiencias laborales, las cuales no
> > siempre estan bien hechas.
> 
> 	A veces pasa, y a veces es bueno saber "hacer trampas", pero para eso,
> primero hay que conocer bien las reglas, porque si no no se pueden
> evaluar pros y contras para elegir bien.
> 
> > > > Si va en la SRS, seria un Req No Funcional? y como deberia de
> > > > redactarlo para que quedara correctamente expresado?
> > > 
> > > De hacer algo así, tendrías que desglosar la "gestión" de cada cosa
> > > afectada por esta restricción en subrequerimientos, y en el de
> > > modificación y en el de borrado, especificar cómo es el mecanismo y
> > las
> > > condiciones para hacerlo.
> > > 
> > 
> > Me parece que hacer eso seria muy complicado y dar un paso atras en la
> > SRS, por lo que prefiero hacer como nos explicaste en su momento en
> > clase.
> > En lugar del ID se guarda el valor de ese campo, es por ello que puse
> > los campos con la misma longitud que el campo de la tabla original y a
> > demas agregue provincias.
> 
> 	Bueno, te perdiste una cosa de esto en clase: lo que dije es que
> _además_ del ID, se guarda el valor que tenía el dato en ese momento.
> 

Si, me lo perdi, o capaz no lo entendi cuando lo explicaste, con ese dato ahi si me cierra mucho mas el almacenamiento que recomendabas.

> > Debo reconocer que esto me complica totalmente, porque cuando tenga
> > que hacer los filtros o busquedas si un administrador borro "Mar del
> > Plata" y ahora pasa a llamarla "MDP" las Mascotas Perdidas o
> > Encontradas o Reunidas posteriores al cambio no voy a tener una
> > referencia valida.
> > Como podria hacer segun vos para corregir esto? o para que no suceda
> > este problema?
> 
> 	Primero, no es tanto un problema porque como te digo arriba, los ID de
> las cosas siguen estando.
> 	Con respecto a los filtros, es muy simple: si querés filtrar por "las
> ciudades que existen actualmente", lo hacés como lo habías pensado en un
> principio. Si la ciudad fue editada y cambió de nombre, como mostras el
> nombre guardado en vez del actual, cada Mascota X se verá con el nombre
> de lo ciudad como fue ingresado.
> 	Si en cambio querés filtrar por ciudad "que exista o haya existido"
> obtenés la lista de localidades distintas usadas de la propia tabla de
> Mascotas X para armar la lista del filtro, y luego buscás por el ID
> igual que antes, con la diferencia que si una vez existió Balcarce y
> ahora no existe más, esta ciudad va a seguir apareciendo en el filtro.
> 
> > > Dos cosas: 
> > > 1) con la aclaración y el agregado de la referencia la tabla tiene
> > > sentido.
> > > 2) esta implementación contradice tus RF 15.4 y RF16.4 así que no
> > podés
> > > seguir este camino, porque la normalización va para otro lado :-(
> > > 
> > > Como nota al margen, me causó simpatía tu expresión "preferi
> > normalizar
> > > a tener 3 tablas diferentes"... porque la normalización no es una
> > > cuestión de preferencias, sino de aplicar la norma.
> > > 
> > 
> > Hice el cambio, ahora estan las tablas Mascotas_Perdidas,
> > Mascotas_Encontradas, Mascotas_Reunidas.
> 
> 	Ok.
> 
> > Tuve que dejar Mas_Situaciones porque ahora se me genera un problema
> > con las tablas Mas_Pics, Mas_Reuniones, Mas_Observaciones (excepto que
> > estas tablas tambien deban pasar a ser Mas_Reuniones_Perdidas,
> > Mas_Reuniones_Encontradas, etc, etc). 
> > Es por eso que agregue un campo en estas tablas mencionadas, que las
> > relaciona con Mas_Situaciones en la cual se hace referencia a que
> > tabla corresponde la mascota, pero como explique decime si esto es
> > correcto o si deberia desglosar Mas_Reuniones, Mas_Observaciones y
> > Mas_Pics
> 
> 	Usar un "campo discriminador" para saber a qué tabla apuntar indica
> casi siempre una falla en la normalización.
> 	Lo correcto sería tener una tabla para cada cosa.
> 
> 	Sin embargo, como es un almacenamiento bastante lateral a la
> problemática del sistema que planteás, en lo personal no tendría
> problema en que lo dejes así... pero poné una nota aclaratoria de esta
> situación, porqeu si no cada vez que lo veamos vamos a volver a decir
> que está mal normalizado.
> 
> 	Lo dejo a tu criterio: o normalizás bien esto o ponés una aclaración
> del motivo por el que no estás normalizando.
> 

Preferi normalizar bien, y cree las tablas correspondientes, pero de todas formas aclaro abajo que fue lo que hice y porque lo hice.

> > > Seguimos con esto luego de resuelto el tema de la otra conversación,
> > > por si implica cambios en la SRS.
> > > 
> > > Saludos cordiales!
> > > 
> > > -- 
> > > Leonardo Tadei
> > > leonardot en pegasusnet.com.ar
> > > Web: http://leonardo.tadei.com.ar
> > > Firma pública: http://www.pegasusnet.com.ar/LeonardoTadei-public.key
> > > 
> > Mascotas_Perdidas
> > [
> >     mas_id: integer(autoincremental);
> >     mas_name: Varchar(50);
> >     mas_sex:Varchar(20);
> >     mas_raza: Varchar(150);
> >     mas_edad: integer;
> >     mas_obs: text;
> >     mas_tamano: Varchar(25);
> >     mas_loc: Varchar(150);
> >     mas_prov: Varchar(100);
> >     mas_est_id: integer; (FK)
> >     mas_con_id:integer(FK);
> >     mas_fecalta: timestamp;
> > ]
> 
> 	Acá y en las otras tablas de Mascotas, faltan como te decía más arriba
> los ID además del nombre de la entidad referenciada.
> 

> > Mas_Pics
> > [
> >     mpic_id: integer(autoincremental);
> >     mpic_mas_id: integer; (FK)
> >     mpic_name: Varchar(50);
> >     mpic_sit_id:integer;(FK)
> > ]
> 
> 	Las dos tablas de arriba, si quedan así, es con comentario aclaratorio.
> Si no, será una tabla para las imágenes de cada tipo de mascota.
> 

Hice una modificacion, en la Normalizacion que adjunto al final esta todo, pero paso a detallar lo que hice, decime si es correcto o sigo creando problemas. Porque como decis Mas_Pics es un almacenamiento lateral, por lo tanto decidi agregar 2 campos, modificar el de pic_mas_id actual y eliminar el de situaciones ya que elimine tambien la tabla.
Los campos que agregue y que modifique al final son los que relacionan con las tablas de Mascotas, en este caso cada campo corresponde a una tabla, como aclaro que aceptan nulos, por codigo buscaria cual no es nulo y ahi lo relaciono con la tabla que corresponde. O si necesito buscarlo partiendo de la mascota ya iria directamente al campo en cuestion, se supone que si o si uno y solo uno de los tres deberia tener un valor distinto de nulo que relacione a una mascota.

Seria esta una solucion aceptable? me imagino que buena no es pero me parece mejor que el campo discriminador de antes.

> > Mas_Codigos
> > [
> >     mcod_id: integer(autoincremental);
> >     mcod_link: varchar(100);
> >     mcod_mas_id: integer; (FK)
> >     mcod_sit_id:integer;(FK)
> >     mcod_fecalta: timestamp;
> > ]
> 
> 	Esta tabla no va.
> 	El link de aprobación depende directamente y solo depende de la Mascota
> X a que corresponde, por tanto la normalización no dice que tiene que
> estar en tabla aparte, sino como parte de la entidad de la que depende.

Ok, la borre. Igual el sentido de esta tabla era no almacenar los codigos por demasiado tiempo. Se supone que pasado los 3 dias cada codigo se borraria, incluso antes si el contacto valida el email.


> > Mas_Observaciones
> > [
> >     mobs_id: integer(autoincremental);
> >     mobs_mas_id: integer; (FK)
> >     mobs_con_id: integer; (FK)
> >     mobs_cext_id: integer; (FK)
> >     mobs_calle: Varchar(100);
> >     mobs_loc_id: integer; (FK)
> >     mobs_sit_id:integer;(FK)
> > ]
> 
> 	El campo mobs_con_id, si se refiere al ID del Contacto de Mascota, es
> una repetición y acá no va. Llegás a este dato vía la relación con la
> Mascota.

No me habia dado cuenta, tenes razon!

> 	La Localidad de la observación, además del ID, requiere que pongas el
> nombre, por el mismo motivo que está en las tablas de Mascotas X.
> 
Ok, me parece correcto, asi la BD tiene todo el mismo formato.

> 	Con el id de situación, estás usando acá de nuevo un campo
> discriminador. En este caso, no es una cuestión lateral del
> almacenamiento, así que sí vas a tener que normalizarlo y crear un
> almacenamiento para las Observaciones de cada Mascota X que las use.
> 
> 	Releyendo la SRS para validar la normalización, me acabo de dar cuenta
> de que no le encuentro sentido a tener una Observación de Mascota
> Encontrada.
> 	Está bueno que si uno ve una Mascota Perdida, pueda avisar que la vio
> en determinado lugar. Pero en qué situación alguien reportaría que vio
> una Mascota Encontrada? 

La reportaria si la conoce, actualmente tengo 2 conocidos que han encontrado en la calle a 2 perros. Suponete que hay alguien que ve la foto y los reconoce, entonces completaria un Aviso de Observacion de Mascota Encontrada, de esta forma el sistema pone en contacto a la persona que reporta que lo conoce al perro y la persona que actualmente lo encontro.

> 	No cambies nada en la SRS sobre esto: te quería comentar esta cuestión.
> 	
> 
> 
> > Mas_Reuniones
> > [
> >     mreu_id: integer(autoincremental);
> >     mreu_mas_id: integer;
> >     mreu_sit_id:integer;(FK)
> >     mreu_con_id: integer;
> > ]
> 
> 	No me doy cuenta qué es esta tabla... 
> 	Me explicás?
> 
Es para los avisos de Reunion. Cuando un contacto encuentra a la mascota,(ya sea si esta perdido que lo encontro, o si es encontrado que se ubico a la familia)  completa este aviso, para que el sistema pase la mascota como Reunida. Sucede que esto es necesario almacenarlo porque si alguien no confirma el mail enviado la mascota no pasaria nunca a Reunida.


NORMALIZACION V3


Provincias
[
    pro_id: integer(autoincremental);
    pro_name: Varchar(100);
]

Localidades
[
    loc_id: integer(autoincremental);
    loc_name: Varchar(150);
    loc_pro_id: integer; (FK)
]

Especies
[
    esp_id: integer(autoincremental);
    esp_name: Varchar(100);
]

Razas
[
    raz_id: integer(autoincremental);
    raz_name: Varchar(150);
    raz_esp_id:integer;(FK)
]

Tamanos
[
    tam_id: integer(autoincremental);
    tam_name: Varchar(25);
]

EstadosPublicacion
[
    est_id: integer(autoincremental);
    est_name: Varchar(25); [Activo | Pendiente de Confirmación | Pendiente de Publicación | Rechazado]
]

Contactos_Mascotas
[
    con_id: integer(autoincremental);
    con_name: Varchar(50);
    con_email: Varchar(100);
]

Contactos_Externos
[
    cext_id: integer(autoincremental);
    cext_name: Varchar(50);
    cext_email: Varchar(100);
]

Sexos
[
    sex_id:integer(autoincremental);
    sex_name:Varchar(20);
]

Mascotas_Perdidas
[
    mas_id: integer(autoincremental);
    mas_name: Varchar(50);
    mas_sex:Varchar(20);
    mas_sex_id:integer;(FK)
    mas_raza: Varchar(150);
    mas_raz_id:integer;(FK)
    mas_edad: integer;
    mas_obs: text; - allow NULL
    mas_tamano: Varchar(25);
    mas_tam_id:integer;(FK)
    mas_loc: Varchar(150);
    mas_loc_id:integer:(FK)
    mas_prov: Varchar(100);
    mas_est_id: integer; (FK)
    mas_con_id:integer(FK);
    mas_link: varchar(100);
    mas_fecalta: timestamp;
]

Mascotas_Encontradas
[
    mas_id: integer(autoincremental);
    mas_name: Varchar(50);
    mas_sex:Varchar(20);
    mas_sex_id:integer;(FK)
    mas_raza: Varchar(150);
    mas_raz_id:integer;(FK)
    mas_edad: integer;
    mas_obs: text; - allow NULL
    mas_tamano: Varchar(25);
    mas_tam_id:integer;(FK)
    mas_loc: Varchar(150);
    mas_loc_id:integer:(FK)
    mas_prov: Varchar(100);
    mas_est_id: integer; (FK)
    mas_con_id:integer(FK);
    mas_link: varchar(100);
    mas_fecalta: timestamp;
]


Mascotas_Reunidas
[
    mas_id: integer(autoincremental);
    mas_name: Varchar(50);
    mas_sex:Varchar(20);
    mas_sex_id:integer;(FK)
    mas_raza: Varchar(150);
    mas_raz_id:integer;(FK)
    mas_edad: integer;
    mas_obs: text; - allow NULL
    mas_tamano: Varchar(25);
    mas_tam_id:integer;(FK)
    mas_loc: Varchar(150);
    mas_loc_id:integer:(FK)
    mas_prov: Varchar(100);
    mas_est_id: integer; (FK)
    mas_con_id:integer(FK);
    mas_link: varchar(100);
    mas_fecalta: timestamp;
]

Mas_Pics
[
    mpic_id: integer(autoincremental);
    mpic_name: Varchar(50);
    mpic_masp_id: integer; (FK) - allow NULL
    mpic_mase_id: integer; (FK) - allow NULL
    mpic_masr_id: integer; (FK) - allow NULL
]

Mas_Observaciones_Perdidas
[
    mop_id: integer(autoincremental);
    mop_masp_id: integer; (FK) - allow NULL
    mop_cext_id: integer; (FK)
    mop_calle: Varchar(100);
    mop_loc_id: integer; (FK)
    mop_loc:Varchar(150);
    mop_prov:Varchar(100);
    mop_link: varchar(100);
]

Mas_Observaciones_Encontradas
[
    moe_id: integer(autoincremental);
    moe_mase_id: integer; (FK) 
    moe_cext_id: integer; (FK)
    moe_calle: Varchar(100);
    moe_loc_id: integer; (FK)
    moe_loc:Varchar(150);
    moe_prov:Varchar(100);
    moe_link: varchar(100);
]

Mas_Reuniones_Perdidas
[
    mrp_id: integer(autoincremental);
    mrp_masp_id: integer; (FK) 
    mrp_link: varchar(100);
]

Mas_Reuniones_Encontradas
[
    mre_id: integer(autoincremental);
    mre_mase_id: integer; (FK) 
    mre_link: varchar(100);
]

Sugerencias
[
    sug_id: integer(autoincremental);
    sug_name: varchar(50);
    sug_email: varchar(100);
    sug_texto: varchar(500);
]

TAdmins
[
    tad_id: integer(autoincremental);
    tad_name: Varchar(100);
]

Admins
[
    adm_id: integer(autoincremental);
    adm_nombre: Varchar(50);
    adm_apellido: Varchar(50);
    adm_user: Varchar(20);
    adm_pass: Varchar(20);
    adm_email: Varchar(100);
    adm_tad_id: integer; (FK)
]
 		 	   		  
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://www3.fi.mdp.edu.ar/pipermail/php-avanzado/attachments/20121208/7de56a46/attachment-0001.html>


Más información sobre la lista de distribución Php-avanzado