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

Distintas llaves foráneas en el mismo campo?

Estas en el tema de Distintas llaves foráneas en el mismo campo? en el foro de Mysql en Foros del Web. Antes que nada un cordial saludo y entremos directamente en materia. En varias ocasiones me he visto en la necesidad de ligar varias tablas a ...
  #1 (permalink)  
Antiguo 26/04/2011, 09:31
Avatar de pancho_k  
Fecha de Ingreso: julio-2007
Mensajes: 32
Antigüedad: 16 años, 8 meses
Puntos: 4
Pregunta Distintas llaves foráneas en el mismo campo?

Antes que nada un cordial saludo y entremos directamente en materia.

En varias ocasiones me he visto en la necesidad de ligar varias tablas a una sola ( A, B, C ligarla a la tabla D ), pongamos el típico ejemplo y posiblemente muchos se vean identificados.

Supongamos que tenemos las tablas EMPLEADOS, PROVEEDORES y CLIENTES ( también debo comunicarles que en esto de MySQL soy mas autodidacta y tengo muy pocas y escasas referencias del correcto uso y manejo de esta tecnología ), también tenemos la tabla TELEFONOS que aunque podemos agregar uno o varios capos para varios teléfonos a las tablas anteriores, las reglas de normalización dictan que es mejor crear una tabla independiente en donde almacenemos los teléfonos para todos ( o al menos así lo he entendido yo) y ligarlas a través de una llave foránea, en el caso de que unicamente tengamos las tablas EMPLEADOS y TELEFONOS no le veo ningún problema, ya que la llave primaria del empleado se almacenaría en la tabla TELEFONOS n número de veces según el n numero de teléfonos tenga el empleado como una llave foránea.

Ahora, que pasa si queremos almacenar los teléfonos de los EMPLEADOS, PROVEEDORES y de los CLIENTES?

- Crear una tabla de teléfonos para cada tipo de persona se me hace demasiado redundante.
- Crear una llave foránea para cada tipo de persona en la tabla TELEFONOS no se puede.

Mi primer pregunta es ¿QUE SE HACE EN ESTOS CASOS?

Lo que normalmente hago es agregar un campo tipo_propietario a la tabla TELEFONOS para identificar a quien corresponde ese teléfono ( si es de un empleado, de un cliente o de un proveedor ) y en otro campo que no es ni llave foránea ni es indice y no tiene ninguna propiedad especial almaceno el id o la llave primaria de la persona a la que le corresponde ese teléfono, obviamente esto lo hago a nivel programación y con mucho cuidado para garantizar la consistencia de los datos.

Mis siguientes preguntas son:

¿Mi forma de resolverlo es una buena o mala practica?
¿Existe algún tipo de relación en MySQL que me permita resolver este problema, cual es?
¿Cual es la manera correcta de resolverlo?

Me eche un clavado en las FAQ's y unicamente encontré un tema que habla mas o menos del mismo problema ( http://www.forosdelweb.com/f21/dudas-como-ligar-tablas-mysql-301016/ ), pero la respuesta, mas que respuesta es otra pregunta y pues la verdad no convence.

De antemano agradezco la atención prestada y ojala puedan ayudarme con mis dudas.

P.D.: Se agradecen links a artículos o referencias para evitarles dar toda una explicación.
  #2 (permalink)  
Antiguo 26/04/2011, 10:10
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: Distintas llaves foráneas en el mismo campo?

En primer lugar, tienes que considerar que "Telefono" no es una entidad abstracta, sino un atributo de una entidad determinada, y esto implica que existe una dependencia funcional entre ambas cosas.
También significa que no puedes separar el teléfono de un Cliente y abstraerlo como si su existencia fuese neutral. No. La existencia de esa tabla relacionada con el Cliente no se origina en su calidad de telefono sino por normalización de bases de datos, que es un problema completamente diferente. En estos casos, y por más que te parezca redundante, los teléfonos dependientes de las instancias de una entidad se crean como tablas independientes entre sí. No pueden compartirse entre diferentes tablas.
Sé que este nivel de abstracción puede parecerte extraño, precisamente porque se trata de una visión diferente a la de la programación orientada a objetos. Esto se debe a que son temas que sólo se estudian en Bases de Datos en la universidad, y raramente tratados en los tutoriales con mucha profundidad.
Si luego estos teléfonos se modelan en el modelo de clases programadas como un sólo objeto, es un tema totalmente diferente, porque no existe necesidad de que los modelos de clases y el modelo de datos sea iguales ya que no representan la misma visión de la realidad. Son diagramas y visualizaciones interrelacionados del sistema, pero a la vez independientes.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 26/04/2011, 17:27
Avatar de pancho_k  
Fecha de Ingreso: julio-2007
Mensajes: 32
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Distintas llaves foráneas en el mismo campo?

Muchas gracias gnzsoloyo, agradezco mucho tu respuesta y fijate que lo que me escribes tiene mucha coherencia incluso estoy de acuerdo con algunas cosas que mencionas, pero por ejemplo, y siguiendo con el ejemplo que mencione en el primer post, que pasa cuando te piden al menos 5 teléfonos de espacio para cada tipo de persona y toma en cuanta que obviamente no siempre se llenan todos los teléfonos en el formulario y para cada teléfono tipos de teléfono que van desde móvil, fijo, nextel, etc etc etc. Por lo que dejar esos campos en la tabla de empleados o de clientes, se traduciría en muchos espacios vacíos y de igual manera espacio reservado que no se utiliza. Esto, desde mi punto de vista, me obliga a separar la tabla de teléfonos, por otra parte en mas de una ocasión he escuchado y leído ( no encontré esos artículos para referenciarlo ) que una base de datos es mas funcional si se va clasificando la información en tablas, es decir personas con personas, direcciones con direcciones o teléfonos con teléfonos y las relaciones hacen el trabajo.

Al final de cuentas lo de los teléfonos fue lo primero que se me bino a la mente y ese problema en especifico se puede resolver agregando un campo tipo a una tabla personas en donde puedas definir si la persona es un cliente o un proveedor o un empleado y de igual manera mantener los teléfonos por separado por las razones ya explicadas.

Pero supongamos nuevamente, tienes tu tabla de clientes y ahora tienes una tabla de anuncios, en donde las personas se van registrando y al registrarse tienen la oportunidad de registrar un anuncio, en especifico anuncios de negocios, el cliente al registrase también puede registrar sus teléfonos y con las mismas facilidades explicadas ( hasta 5 teléfonos y pueden variar entre fijo, móvil, fax, etc etc ) pero se da el caso y esto me ha pasado, que el cliente quiere que en su anuncio aparezcan teléfonos completamente distintos a los que registró en su cuenta ( en la tabla de clientes ). Estamos de acuerdo que el anuncio ya no es persona y puede usar los mismos teléfonos de el cliente o utilizar otros completamente distintos.

Entonces por favor, ayudame con esta ultima pregunta. ¿ Cual es la forma correcta de resolver esto ?
  #4 (permalink)  
Antiguo 27/04/2011, 05:35
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: Distintas llaves foráneas en el mismo campo?

Cita:
y siguiendo con el ejemplo que mencione en el primer post, que pasa cuando te piden al menos 5 teléfonos de espacio para cada tipo de persona y toma en cuanta que obviamente no siempre se llenan todos los teléfonos en el formulario y para cada teléfono tipos de teléfono que van desde móvil, fijo, nextel, etc etc etc. Por lo que dejar esos campos en la tabla de empleados o de clientes, se traduciría en muchos espacios vacíos y de igual manera espacio reservado que no se utiliza. Esto, desde mi punto de vista, me obliga a separar la tabla de teléfonos,
Es un poquitín difícil sintetizar cuatro materias de la facultad en un post, pero voy a intentar describirlo de una forma simplificada:
Cuando analizas un sistema y defines las entidades que lo componen (ver entidad en el modelo entidad-relación), lo haces en base a atributos (datos o valores) que definen su existencia y que le pertenecen. Es el caso de Nombre, Direccion, Documento, etc.; en ocasiones te encuentras con un atributo que es iterativo, es decir, que puede contener más de un valor asignable o incluso ninguno.
Esto, a nivel de sistema, es aceptable, pero el modelo relacional de bases de datos no admite iteraciones de valores en una tabla, es decir, no puede haber valores múltiples en un mismo campo. Por eso existen las formas normales, que te permiten resolver eso.
En las Formas Normales se determina que todo atributo iterativo debe forzosamente se extraído de la tabla y separado en una tabla propia. Pero eso no implica necesariamente que ese atributo pueda ser derivado a una tabla general, porque ese mismo atributo le sigue perteneciendo a esa única entidad. En otras palabras, si esa tabla existe es porque ese atributo existe en ella, entonces depende de ella para existir.
En el contexto de Usuarios -> Telefonos, los teléfonos son de los usuarios, y nada más que de los usuarios. Lo mismo pasa con otro tipo de cosas, como estudios cursados, domicilios, etc.
En el caso de los teléfonos, el que sea fijo, celular, Nextel o lo que sea, es un atributo del teléfono, lo que normalmente se implementa en la tabla de teléfonos sea como un campo ENUM, o una FK a otra tabla que contenga los tipos de teléfonos aceptados (es una decisión del diseñador del sistema). Por ello no es necesario hacer diferentes tipos de campo para diferentes tipos de teléfono. Además ten en cuenta que sea de donde sea, el sistema telefónico mundial sólo acepta una cantidad determinada de dígitos (creo que el máximo son 14) para marcado. O sea que no necesitas nunca mas de eso.
Este modelo de relación permite que haya cero o más teléfonos, por ejemplo. Eso surge de analizar si ese atributo es obligatorio u opcional.
Este tipo de esquema de razonamiento se repite siempre que haya un conjunto de atributos que sea iterativo en el mismo contexto. Con esto me refiero que si hay un domicilio con varios numeros, pero el resto de los datos de la dirección no se repite, eso no es iteratividad. Uno sólo de los valores es lícito y el resto son optativos.

Cita:
por otra parte en mas de una ocasión he escuchado y leído ( no encontré esos artículos para referenciarlo ) que una base de datos es mas funcional si se va clasificando la información en tablas, es decir personas con personas, direcciones con direcciones o teléfonos con teléfonos y las relaciones hacen el trabajo.
Hay que tener mucho cuidado con la atomización innecesaria de las entidades. La normalización de las tablas tiene un límite práctico (demasiadas tablas innecesariamente complican la base), y un límite analítico.
El límite práctico está dado por la normalización. Si no es estrictamente necesario, no se debe hacer. El analítico está dado por los requerimientos del cliente, ya que ciertas separaciones de datos pueden surgir de lo que el cliente pide, y porque el sistema toma los datos de una determinada forma (Caso: ventas telefónicas. Los datos del cliente pueden llegar a separarse en tablas, dependiendo de los formularios de entrada que el sistema considere).
Lo que no hay es una regla o ley general, pero si te remarco algo que ya dije: Si, por ejemplo, un usuario sólo puede tener una dirección (reglas de negocio), no tiene ningún sentido separar la dirección en otra tabla. Si tiene más de una tarjeta de crédito, sí, las tarjetas van en otra tabla.

¿Se va entendiendo un poco?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 27/04/2011, 09:08
Avatar de pancho_k  
Fecha de Ingreso: julio-2007
Mensajes: 32
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Distintas llaves foráneas en el mismo campo?

Antes que nada gnzsoloyo, mis respetos y gracias por tus respuestas.

Eso es precisamente lo que me lleva a apartar los teléfonos de la tabla de personas, mi razonamiento se baso en el hecho de que: Si se tratara de un único y obligado teléfono, solo uno, pues no tiene caso crear otra tabla, el campo teléfono se agregaría a la tabla personas e incluso el campo enum para definir el tipo de teléfono, independientemente de la numeración mundial, pero como se trata de varios números, opte por crear una tabla que obviamente depende de la existencia de personas con su campo enum y su foránea tal cual lo especificas. (Por favor marca como "A.-" tu comentario a esta parte)

Por otra parte, estoy completamente de acuerdo en que muchas tablas complican la base, pero que hay de las tablas que contienen muchos campos, creo yo que también representan una complicación en la base por que ademas de hacer una búsqueda vertical de cierto registro, obligas a MySQL a hacer una búsqueda horizontal para ubicar los campos requeridos en la consulta y no se a que grado esto afecte la velocidad de respuesta, por que estarás de acuerdo en que ( y también lo he experimentado ) las tablas con menor número de campos son mas rápidas y eficientes, sobretodo en las consultas y generación de reportes, es por eso que en ocasiones he separado la tabla de personas y la tabla de direcciones y es que para este caso en particular la tabla de personas creció bastante y en segundo lugar, eran pocas las consultas que requerían la totalidad de los campos o los campos de las direcciones y creo que eso también debe tomarse en cuenta. (Por favor marca como "B.-" tu comentario a esta parte)

Ahora, eso es lo que he comprendido yo en en estas valiosas lecciones que me has dado, ¿ Estoy en lo correcto o me equivoco ?

Etiquetas: distintas, llaves, campos
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 08:47.