2010-05-26 10 views
10

¿Cuál es la mejor manera de almacenar relaciones de usuario, p. amistades, que deben ser bidireccionales (eres mi amigo, así soy tu amigo) en un rel. base de datos, p. MYSql?mejor forma de almacenar relaciones de usuario 1: 1 en la base de datos relacional

puedo pensar en dos formas:

  1. cada vez que un usuario a otro usuario amigos, me gustaría añadir dos filas a una base de datos, la fila A que consiste en el identificador de usuario del usuario innitiating seguido por el UID el usuario aceptante en la siguiente columna. La fila B sería al revés.
  2. Solo agregará una fila, UID (usuario iniciador) seguido de UID (usuario aceptante); y luego solo busque en ambas columnas cuando intente averiguar si el usuario 1 es amigo del usuario 2.

Seguramente hay algo mejor?

+0

suena como si tuvieras el diseño correcto. A lo que se refiere es a una asociación entre dos tablas para crear un 0..1 o muchos entre cada tabla y la tabla de asociación. Al final, lo que redes es un muchos a muchos. Pero debo decir que tiene derecho a manejarlo de esta manera. –

Respuesta

8

Tendría una tabla de enlaces para amigos, o lo que sea, con 2 columnas, ambas de PK, y ambas son FK de la tabla de Usuario.

Ambas columnas serían el UID, y usted tendría dos filas por relación de amigo (A, B y B, A). Siempre y cuando ambas columnas sean PK, debería estar en formato normal (aunque otras son libres de corregirme en este caso)

Es una consulta un poco más compleja, pero nada que no pueda ser eliminada por una procedimiento almacenado o alguna lógica de negocios, y está en formato normal, que generalmente es bueno tener.

+5

Recuerde que en MySQL, el motor predeterminado MyISAM no admite claves externas, cambie a InnoDB. –

+0

Cierto, pero si tuviera que usar MyISAM, podría salirse con la suya no siendo FK real, pero podría afectar su integridad de datos y normalización, siga con InnoDB –

+2

Me gustaría ir con este sistema y simplifica enormemente las consultas de selección para buscar amigos, especialmente cuando necesitas unirte a esta tabla. Sin embargo, debe usar las transacciones y los procedimientos almacenados para asegurarse de que ambas filas siempre se inserten y eliminen juntas (usted ** no ** desea borrar accidentalmente una de las dos filas). –

3

Usar filas dobles, a la vez que crea datos adicionales, simplificará en gran medida sus consultas y le permitirá indexar inteligentemente. También recuerdo haber visto información en la solución MySQL personalizada de Twitter, en la que utilizaron un campo adicional (amigo #, básicamente) para hacer la limitación automática y la paginación. Parece bastante sencillo: https://blog.twitter.com/2010/introducing-flockdb

-6

Utilice un almacén de valores clave, como Cassandra, por ejemplo.

+0

La solicitud se refería específicamente a una solución MySQL. – ethanpil

3

Puede verificar cuál de los dos ID_usuarios es el más bajo y almacenarlos en un orden específico. De esta manera, no necesita filas dobles para una amistad y aún así mantener sus consultas simples.

user_id_low | user_id_high

una consulta sencilla de comprobar si ya eres amigo de alguien serían:

<?php 
$my_id = 2999; 
$friend_id = 500; 

$lowest = min($my_id, $friend_id); 
$highest= max($my_id, $friend_id); 

query("SELECT * FROM friends WHERE user_id_low=$lowest AND user_id_high=$highest"); 
?> 

o usted podría encontrar el menor ID de usuario/higest usando MySQL

<?php 
query("SELECT * FROM friends WHERE user_id_low=LEAST($my_id, $friend_id) AND user_id_high=GREATEST($my_id, $friend_id)"); 
?> 

Y para conseguir todo Identificación de tus amigos

<?php 

query("SELECT IF(user_id_low=$my_id,user_id_high,user_id_low) AS friend_id FROM friends WHERE $my_id IN (user_id_low, user_id_high)"); 

?> 
+0

después de mirar esto durante medio minuto y solo presenté que se me ocurriría una buena razón por la cual no debería usarse. Pero no, no lo hice. Esta no es una mala solución, bastante elegante en realidad :) en realidad esto también es compatible con un sistema en el que se puede organizar un grupo de, por ejemplo, 100 grupos de amigos, simplemente ponerlos todos en un orden asc/desc –

Cuestiones relacionadas