[Php-avanzado] Normalizacion Juan Manuel V2

Leonardo Tadei - Pegasus Tech Supply leonardot en pegasusnet.com.ar
Sab Dic 8 01:33:41 ART 2012


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
>> > 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.

> 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.

> > 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
> > 
> 
> 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 | Rechazad]
> ]
> 
> 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_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.

> Mascotas_Encontradas
> [
>     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;
> ]
> 
> 
> Mascotas_Reunidas
> [
>     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;
> ]
> 
> Mas_Situacion
> [
>     sit_id:integer(autoincremental);
>     sit_name:Varchar(50);
>     sit_tabla:Varchar(50);
> ]
> 
> 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.

> 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.

> 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.
	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.

	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? 
	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?

> 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)
> ]


	Nada más por ahora.
	Seguimos!

-- 
Leonardo Tadei
leonardot en pegasusnet.com.ar
Web: http://leonardo.tadei.com.ar
Firma pública: http://www.pegasusnet.com.ar/LeonardoTadei-public.key



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