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

Base de datos + relaciones "raras"

Estas en el tema de Base de datos + relaciones "raras" en el foro de Bases de Datos General en Foros del Web. Antes que nada aclaro que pongo el thread en este foro por dos cosas: 1- En el foro de db nadie ha sabido responderme. 2- ...
  #1 (permalink)  
Antiguo 03/03/2008, 08:48
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 20 años
Puntos: 34
Base de datos + relaciones "raras"

Antes que nada aclaro que pongo el thread en este foro por dos cosas:

1- En el foro de db nadie ha sabido responderme.
2- Puede que acá alguien ya se haya cruzado con este problema/tema.

Tratare de ser practico; supongamos que tengo el siguiente esquema:

Usuarios>Bebidas>Comidas

Ahora, en cuanto a datos podría tener:

Nicolás>Vino, agua>Pure, Milanesa, Ensalada

Hasta acá todo bien, pero que pasa si yo quiero que exista una relación entre milanesa y vino solo por estar ambas relacionadas a Nicolás?

Como plantean esto? Como se llaman estas relaciones? alguien tiene idea, cualquier sugerencia ayudará...?
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #2 (permalink)  
Antiguo 03/03/2008, 09:07
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 6 meses
Puntos: 2135
Re: Php + Base de datos + relaciones "raras"

Si tienes tus tablas diferentes (una tabla usuarios, otra bebidas y otra comidas), solo haz relaciones 1:n, por cada tabla:

rel_bebidas:
- idrel
- idusuario
- idbebida

rel_comidas:
- idrel
- idusuario
- idcomida

Así podrás consultar con un query todas las relaciones que tenga un usuario, e imprimirlas.

Saludos.

Trasladado a Base de Datos
  #3 (permalink)  
Antiguo 03/03/2008, 09:37
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 20 años
Puntos: 34
Re: Base de datos + relaciones "raras"

Gracias por responder!. Y si, hasta ahí estamos bien. Pongamos a modo de ejemplo esta db:
Código:
/*Table structure for table `tbl_bebidas` */
CREATE TABLE `tbl_bebidas` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `nombre` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `tbl_bebidas` */
insert into `tbl_bebidas` (`id`,`nombre`) values (1,'Pure'),(2,'Milanesas'),(3,'Siuza'),(4,'Asado');

/*Table structure for table `tbl_comidas` */
CREATE TABLE `tbl_comidas` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `nombre` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `tbl_comidas` */
insert into `tbl_comidas` (`id`,`nombre`) values (1,'Coca Cola'),(2,'Vino'),(3,'Agua'),(4,'Soda');

/*Table structure for table `tbl_rel_bebidas` */
CREATE TABLE `tbl_rel_bebidas` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `usuario` int(11) unsigned NOT NULL default '0',
  `bebida` int(11) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `tbl_rel_bebidas` */
insert into `tbl_rel_bebidas` (`id`,`usuario`,`bebida`) values (1,1,1),(2,1,2);

/*Table structure for table `tbl_rel_comidas` */
CREATE TABLE `tbl_rel_comidas` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `usuario` int(11) unsigned NOT NULL default '0',
  `comida` int(11) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `tbl_rel_comidas` */
insert into `tbl_rel_comidas` (`id`,`usuario`,`comida`) values (1,1,2),(2,1,3);

/*Table structure for table `tbl_usuarios` */
CREATE TABLE `tbl_usuarios` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `nombre` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `tbl_usuarios` */
insert into `tbl_usuarios` (`id`,`nombre`) values (1,'Nico'),(2,'Pepe');
Pero para levantar las comidas que tengan "relacionadas" alguna bebida a algun usuario debería hacer algo como:

Código:
select 
    b.nombre
from 
    tbl_bebidas b
where
    exists( 
        select 
            b2.bebida 
        from 
            tbl_rel_bebidas b2
        where 
            b2.bebida = b.id
            and exists(select c.usuario from tbl_rel_comidas c where c.usuario = b2.usuario )            
        )
Y esto, cuando hay mucho contenido explota!..., alguna sugenrencia al query o estructura?
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #4 (permalink)  
Antiguo 03/03/2008, 10:17
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 9 meses
Puntos: 13
Re: Base de datos + relaciones "raras"

uffff
tu problema es de sql. Mira el tema de utilizar join de tablas.

select distinct b.nombre
from bebidas b
join rel_bebidas rb on b.id = rb.bebida
join rel_comidas rc on rc.usuario = rb.usuario


Y meter claves ajenas tambien sería conveniente.
Lo de dejar default null al nombre... es por algo en concreto.

Deberias darle una mirada a algun manual.

Un saludo
  #5 (permalink)  
Antiguo 03/03/2008, 11:04
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 20 años
Puntos: 34
Re: Base de datos + relaciones "raras"

El join es más lento en las pruebas que he realizado, el exists se comporta más óptimo; aún así es la muerte. He pensado de pasarlo a php en forma de arrays y hacer algo de ese lado...el pero de esto es que no se si será mejor o no.

Con el tema del manual he leído muchos y jamás vi estos casos, decime puntualmente que busco, como se les llama a estas relaciones y leeré sin problema alguno.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #6 (permalink)  
Antiguo 03/03/2008, 12:37
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 9 meses
Puntos: 13
Re: Base de datos + relaciones "raras"

Imposible que el join sea más lento, crea FK e indexa los campos de las FK.
Puede que se comporte más lento con muy pocos registros porque el planificador entienda que para tan pocos registros es más rapido utilizar un recorrido secuencial (cosa que es totalmente cierta), pero con muchos datos es imposible que se comporte más lento.

A la espera
  #7 (permalink)  
Antiguo 03/03/2008, 13:03
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 20 años
Puntos: 34
Re: Base de datos + relaciones "raras"

Ya lo hice, es algo que esta testeado, lo más veloz en join creo que era un híbrido con exists, algo como:

Código:
select 
    b.id, b.nombre
from 
    tbl_bebidas b
inner join tbl_rel_bebidas r on r.bebida = b.id and exists (select 1 from tbl_rel_comidas where usuario = r.usuario )

-- Sino algo como solo con joins:
select 
    b.id, b.nombre
from 
    tbl_bebidas b
inner join tbl_rel_bebidas r on r.bebida = b.id
inner join tbl_rel_comidas c on c.usuario = r.usuario
Esto lo testié con no muchos registros (unos 500 usuarios, con 30 items en cada tabla (comidas y bebidas), y relaciones al azar), y los tiempos son menores con query del exists.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #8 (permalink)  
Antiguo 04/03/2008, 02:10
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 9 meses
Puntos: 13
Re: Base de datos + relaciones "raras"

jajajaja como tu quieras.

Cita:

Puede que se comporte más lento con muy pocos registros porque el planificador entienda que para tan pocos registros es más rapido utilizar un recorrido secuencial (cosa que es totalmente cierta), pero con muchos datos es imposible que se comporte más lento.
Un pequeño apunte 30 registros en una tabla son muy muy muy pocos.
Y en esas pruebas existian PK y FK y estaban indexados los campos que las formaban?
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 14:31.