2010-06-09 50 views
13

Tengo un MySQL DB en el que almaceno datos sobre cada usuario.MySQL friends table

Me gustaría agregar una lista de amigos para cada usuario. ¿Debo crear una tabla de amigos para cada usuario en la base de datos o hay una forma mejor?

+2

¿Las amistades son bidireccionales o unidireccionales? Si Pete es amigo de María, ¿siempre significa que María también es amiga de Pete? –

+0

También tenga en cuenta que el nombre de lo que desea es "tabla de intersección" o quizás también "tabla de búsqueda". Si está familiarizado con los conceptos de la base de datos, es una tabla de muchos a muchos, ya que un usuario puede tener muchos amigos y muchos amigos con otras personas. También tenga en cuenta que es posible que un usuario tenga un amigo que no sea amigo, usando este estilo. También hay otras formas, pero esta es la más simple de implementar. Tal vez un poco más acerca de su lógica de negocios amigo ayudaría? ¡@Juha Syrjälä me ganó! – jcolebrand

+0

Los amigos son unidireccionales y ya deben existir en la base de datos. Es solo una lista de recordatorios de personas que conoces. – asmo

Respuesta

9

Suponiendo que todos sus amigos estén también en la tabla de usuarios, necesitará una tabla de amigos que defina una relación sencilla de uno a varios, vinculando la tabla de usuarios a sí misma. Entonces

User Table 
UserID int identity not null 
[other attribute fields] 

Friends Table 
UserIDLink1 int 
UserIDLink2 int 
[other attribute field] 

Donde tanto UserIDLink1 como UserIDLink2 son claves foráneas en la tabla Usuarios.

Así por ejemplo, si tengo tres usuarios

1 Joe 
2 Bill 
3 Jane 

y Joe y Jane son amigos, entonces los Amigos mesa contendrían una sola fila

1 3 

El anterior supone implícitamente que si A es una Amigo de B, B es amigo de A: si no es así, probablemente querría cambiar el nombre de UserIDLink1 y UserIDLink2 a UserID y FriendID o similar, en cuyo caso también podría duplicar los registros.

También para la configuración bidireccional (A es amigo de B si B es amigo de A) debe configurar los índices en la tabla Friends para (UserIDLink1, UserIDLink2) y (UserIDLink2, UserIDLink1) para garantizar el acceso siempre es eficiente si buscábamos amigos de joe o amigos de jane (si no configuraste el segundo índice, la primera consulta sería una búsqueda de índice eficiente, pero la segunda requeriría un escaneo completo de la tabla).

Si sus enlaces no eran bidireccionales, esto no sería necesario para averiguar quiénes son los amigos de A, pero es probable que lo requiera ya que también necesitará averiguar de quién es amigo.

+1

Me pregunto, ¿cómo formular la consulta de combinación con dos claves externas (ID de usuario1 y ID de usuario2) apuntando a la misma clave principal? – koceeng

-1

crear una sola tabla para todos los amigos y dar a cada amigo un UserSID que es igual a sus respectivos usuarios clave

0

Crear una tabla que contiene todos los amigos Cada fila de la tabla contendrá el ID del usuario y el ID de su amigo

+0

Entonces, para cada amigo de cada usuario, agrego una fila en una tabla de 2 columnas (Usuario, Amigo). Por ejemplo, si tengo 200 usuarios con 10 amigos cada uno, la tabla "Amigos" debe tener 2000 filas (10 por usuario). ¿Entiendo correctamente? – asmo

+1

@asmo eso es correcto, pero con una tabla altamente optimizada como la que puede tener en este caso, no debe temer a las tablas con más de un millón de filas, eso no será un problema. – Cruachan

7

Asumiendo que su mesa de USER tiene una clave principal llamado id o algo similar, utilice la siguiente tabla:

DROP TABLE IF EXISTS `friends`; 
CREATE TABLE `friends` (
    `user_id` int(10) unsigned NOT NULL, 
    `friend_id` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`user_id`,`friend_id`), 
    KEY `FK_FRIENDS_2` (`friend_id`), 
    CONSTRAINT `FK_FRIENDS_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), 
    CONSTRAINT `FK_FRIENDS_2` FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Este setu P apoya que Peter es amigo de Mary, pero Mary no piensa en Peter así. Pero los datos existen para inferir que Peter es un conocido de Mary ...

La clave principal son ambas columnas y detiene los duplicados.

+0

¿Me falta la asignación de 'FK_FRIENDS_1' allí? – jcolebrand

+0

Más limpio con user_id y friend_id – rigobcastro

1

Está buscando tabla M-to-N o many-to-many join.

tabla de usuarios:

USER_ID integer primary key, 
NAME  varchar 

amistades Tabla

USER_ID integer not null, 
FRIEND_ID integer not null, 

Tanto USER_ID y FRIEND_ID son las claves externas que hacen referencia a la tabla Usuarios (Users.user_id).

Si el usuario 123 es amigo del usuario 921. Agregue la fila (123, 921) a la tabla de Amistades.

+0

¿Estás mostrando solo 2 tablas? ¿No es suficiente uno-a-muchos para esto? – Notflip

Cuestiones relacionadas