Se puede hacer esto?

Iniciado por mark182, 22 Noviembre 2009, 10:30 AM

0 Miembros y 1 Visitante están viendo este tema.

Nakp

pues hasta donde entiendo, la clave foránea debe ser única en la tabla referenciada, donde es primaria, así se pueden relacionar varios registros de la tabla donde es foránea, con 1 donde es primaria...

Preguntas
ID_Preguntas(pk)
Texto
1
como estan?
2
cual es tu nick?
Respuestas
ID_Respuestas(pk)
ID_Preguntas(fk)
Texto
1
1
bien, gracias :P
2
1
no tan bien...
3
1
situación suicida xD
4
2
mi nick es Nakp
5
2
mi nick es...
ahora... si no me equivoco cada que haces esto automaticamente se crea la tabla de indices?
Ojo por ojo, y el mundo acabará ciego.

^Tifa^

Ok.. aplicando lo que acabas de mostrar (Si es que entendi correctamente).

ID_Preguntas(fk)  No es una llave primaria ni una llave unique. Porque si lo fuese no acceptara los valores repetidos que expones en tu ejemplo. Asumire que ID_Preguntas(fk) es un INDEX de lo contrario no puedes colocar valores repetidos, por esa razon es que hasta ahora me ha gustado mas el modelado de CarlosNuel  :-* (No te sientas celoso Napk no tengo nada contra tu modelado) hasta ahi estamos de acuerdo.

Citarahora... si no me equivoco cada que haces esto automaticamente se crea la tabla de indices?

Ese punto no lo he entendido muy claro, se genera automaticamente si el motor en este caso MySQL lleva auto_increment o si es otro motor como Oracle pues con sequence... o sino te referias a esto, podrias exponerlo mejor porque no entiendo.

Nakp

eso... no es unique ni pk xD... es pk en la tabla referenciada (en este caso, la tabla preguntas), y si, es un index

sobre los indices... ni yo lo tengo claro jaja asi que no hagas caso :P pero no, no me refiero a eso xD
Ojo por ojo, y el mundo acabará ciego.

^Tifa^

Ahhhhhhhh ok ahora si aplica el ejemplo dado por ti  ;D

Solo si el campo ID_Preguntas(fk) es un INDEX o KEY (En MySQL ya que estos dos no existen en todos los motores).

INDEX o KEY son indices ordinarios, digase acceptan nulos no tienen restricciones de repeticion de valores, por ende son ideales para este caso. El modelado de CarlosNuel es lo mismo como si usases INDEX o KEY en tablas como tu ejemplo, a diferencia que hay que crear una tercera tabla (para mi visualmente estetico mas bonito y organizado  :-* )

^Tifa^

Hola.

A todo esto no te hemos colocado un simple ejemplo que te podria servir de guia en todo lo que hemos expuesto. Lo siguiente es sencillo, pero podria servirte como una guia basica de por donde empezar para completar tus ideas. Supongo que tu peticion es que X usuario genere una pregunta donde solo el Administrador y el usuario que genero la pregunta puedan responder a la dichosa pregunta del libro de visitas.

Supondre que estas trabajando bajo una base de datos MySQL. Y utilizare el modelado antiguo expuesto por CarlosNuel (Es que me encantan  ;D)

Tengo de ejemplo estas 3 tablas:

Código (sql) [Seleccionar]


mysql> show tables;
+--------------------+
| Tables_in_primaria |
+--------------------+
| Libro              |
| Respuesta          |
| Usuarios           |
+--------------------+
3 rows in set (0.00 sec)



La tabla Usuarios validara que usuario genero que pregunta y en base a ello le permitira responder en su propia pregunta o no... (dicha validacion ya te tocara hacerle dentro del codigo PHP)

Los campos de cada una son:

Código (sql) [Seleccionar]


mysql> explain Libro;
+----------+------------+------+-----+---------+----------------+
| Field    | Type       | Null | Key | Default | Extra          |
+----------+------------+------+-----+---------+----------------+
| id_libro | tinyint(4) | NO   | PRI | NULL    | auto_increment |
| titulo   | char(20)   | YES  |     | NULL    |                |
| pregunta | char(40)   | YES  |     | NULL    |                |
+----------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> explain Respuesta;
+------------+------------+------+-----+---------+-------+
| Field      | Type       | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| id_usuario | tinyint(4) | YES  | MUL | NULL    |       |
| id_res     | tinyint(4) | YES  |     | NULL    |       |
| respuesta  | char(100)  | YES  |     | NULL    |       |
+------------+------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> explain Usuarios;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id_usuario | tinyint(4)  | NO   | PRI | NULL    | auto_increment |
| usuario    | char(10)    | YES  |     | NULL    |                |
| contrasena | varchar(50) | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)



PD: Lo anterior son tablas creadas como ejemplo, recuerda no crear campos que accepten valores nulos para no desviarte de la normalizacion  ;)

Ahora suponte que la tabla Usuarios tiene ya 3 usuarios con contrasena registrados.

Código (sql) [Seleccionar]


mysql> select * from Usuarios;
+------------+---------+----------------------------------+
| id_usuario | usuario | contrasena                       |
+------------+---------+----------------------------------+
|          1 | coco    | 202cb962ac59075b964b07152d234b70 |
|          2 | maria   | 202cb962ac59075b964b07152d234b70 |
|          3 | pedro   | 202cb962ac59075b964b07152d234b70 |
+------------+---------+----------------------------------+
3 rows in set (0.00 sec)



Las contrasenas estan encriptadas en md5 por eso se ven de esa manera.

Ahora imagina que los 3 usuarios existentes ya realizaron 1 pregunta en el libro de visitas.

Código (sql) [Seleccionar]


mysql> select * from Libro;
+----------+--------------------+---------------------------------+
| id_libro | titulo             | pregunta                        |
+----------+--------------------+---------------------------------+
|        1 | Como es el Sol?    | Quisiera saber porque es blanco |
|        2 | Como es la lluvia? | Porque es transparente          |
|        3 | Juego Favorito     | Cual me recomiendan             |
+----------+--------------------+---------------------------------+
3 rows in set (0.00 sec)



PD: En el caso anterior al campo id_libro ser una clave primaria dicho usuario solo podra tener capacidad de generar 1 sola pregunta ninguna mas eternamente. Ya que el campo id_libro tiene el mismo valor que id_usuario de Usuarios, pero aunque reconozco esta limitacion esto solo es un ejemplo de guia y en la tabla siguiente te podria dar una idea mas clara de como trabajar con doble indices (un primario y secundario) para que dicho usuario pueda regresar a generar un tema nuevo  ;)

Ahora se insertan varios datos segun la pregunta solicitada.

Código (sql) [Seleccionar]

mysql> insert into Respuesta values((select id_usuario from Usuarios where usuario = 'coco'), (select id_usuario from Usuarios where usuario = 'coco'), 'Es blanco por su iluminacion interna');                                                                                                 
Query OK, 1 row affected (0.00 sec)                                                                                                             

mysql> insert into Respuesta values((select id_usuario from Usuarios where usuario = 'coco'), (select id_usuario from Usuarios where usuario = 'coco'), 'Entonces porque cambia a amarillo');
Query OK, 1 row affected (0.00 sec)         

mysql> insert into Respuesta values((select id_usuario from Usuarios where usuario = 'coco'), (select id_usuario from Usuarios where usuario = 'coco'), 'por efecto de alejacion');
Query OK, 1 row affected (0.00 sec)

mysql> insert into Respuesta values((select id_usuario from Usuarios where usuario = 'maria'), (select id_usuario from Usuarios where usuario = 'maria'), 'por la gravedad');
Query OK, 1 row affected (0.00 sec)

mysql> insert into Respuesta values((select id_usuario from Usuarios where usuario = 'maria'), (select id_usuario from Usuarios where usuario = 'maria'), 'Por la densidad');
Query OK, 1 row affected (0.00 sec)


Quedando en un total asi:

Código (sql) [Seleccionar]


mysql> select * from Respuesta;                                                                                                                  +------------+--------+--------------------------------------+
| id_usuario | id_res | respuesta                            |
+------------+--------+--------------------------------------+
|          1 |      1 | Es blanco por su iluminacion interna |
|          1 |      1 | Entonces porque cambia a amarillo    |
|          1 |      1 | por efecto de alejacion              |
|          2 |      2 | por la gravedad                      |
|          2 |      2 | Por la densidad                      |
+------------+--------+--------------------------------------+
5 rows in set (0.00 sec)

mysql> select * from Respuesta where id_usuario = ( select id_usuario from Usuarios where usuario = 'coco');
+------------+--------+--------------------------------------+
| id_usuario | id_res | respuesta                            |
+------------+--------+--------------------------------------+
|          1 |      1 | Es blanco por su iluminacion interna |
|          1 |      1 | Entonces porque cambia a amarillo    |
|          1 |      1 | por efecto de alejacion              |
+------------+--------+--------------------------------------+
3 rows in set (0.00 sec)

mysql> select * from Respuesta where id_usuario = ( select id_usuario from Usuarios where usuario = 'maria');
+------------+--------+-----------------+
| id_usuario | id_res | respuesta       |
+------------+--------+-----------------+
|          2 |      2 | por la gravedad |
|          2 |      2 | Por la densidad |
+------------+--------+-----------------+
2 rows in set (0.00 sec)



PD: Por optimizacion los campos 'usuario' de la tabla Usuarios deberian asignarseles un index para aprovechar la rapidez de consultas:

Código (sql) [Seleccionar]


mysql> explain select * from Respuesta where id_usuario = ( select id_usuario from Usuarios where usuario = 'maria');
+----+-------------+-----------+------+---------------+------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys | key        | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+---------------+------------+---------+-------+------+-------------+
|  1 | PRIMARY     | Respuesta | ref  | id_usuario    | id_usuario | 2       | const |    2 | Using where |
|  2 | SUBQUERY    | Usuarios  | ref  | indice        | indice     | 11      |       |    1 | Using where |
+----+-------------+-----------+------+---------------+------------+---------+-------+------+-------------+
2 rows in set (0.01 sec)



Lo anterior repito es un mero ejemplo que sirve de guia basica para llevarte a tu objetivo.

mark182

Muchísimas gracias nuevamente ^TiFa^ otra ves salvándome las papas jeje, justo estaba escribiendo mis tablas y demas a ver si me podrian dar un ejemplo porque la verdad que quede mariado. El sistema me informo que " mientras estabas escribiendo, una nueva respuesta fue publicada" y era justo lo que estaba pidiendo. Muchas gracias a vos y a todos los que han colaborado.

Aguante el foro de elhacker.net ! ! !    ;D

^Tifa^

De nada encanto  :D   :D

Si tienes alguna duda mas cuando organizes tus ideas de las tablas, no dudes en preguntar nuevamente  ;)