2010-05-26 10 views
10

Qual è il modo migliore per memorizzare le relazioni utente, ad es. le amicizie, che devono essere bidirezionali (sei mio amico, quindi sono tuo amico) in un rel. database, ad es. MySQL?il modo migliore per memorizzare relazioni utente 1: 1 nel database relazionale

Mi vengono in mente due modi:

  1. Ogni volta che un utente amici un altro utente, mi piacerebbe aggiungere due file a un database, riga A composto da l'id utente dell'utente innitiating seguito dal UID l'utente che accetta nella prossima colonna. La riga B sarebbe il contrario.
  2. Aggiungi solo una riga, UID (utente iniziale) seguito da UID (accetta utente); e quindi basta cercare tra le due colonne quando si cerca di capire se l'utente 1 è un amico dell'utente 2.

Sicuramente c'è qualcosa di meglio?

+0

suona come se avessi il design giusto. A cosa ti riferisci è un'associazione tra due tabelle per creare uno 0..1 o più tra ogni tabella e la tabella di associazione. Alla fine ciò che reti è un numero da molti a molti. Ma devo dire che hai ragione su come gestirlo in questo modo. –

risposta

8

Avrei una tabella di collegamento per gli amici, o qualsiasi altra cosa, con 2 colonne che sono entrambe PK, ed entrambe sono FK per la tabella Utente.

Entrambe le colonne sarebbero l'UID e avresti due righe per ogni relazione di amicizia (A, B e B, A). Finché entrambe le colonne sono PK, dovrebbe comunque essere nel formato normale (anche se altri sono liberi di correggermi)

È un po 'più complesso di una query, ma nulla che non possa essere sottratto da un stored procedure o alcune logiche di business, e il suo in formato normale, che di solito è bello avere.

+5

Ricorda che in MySQL il motore predefinito MyISAM non supporta chiavi esterne, passa a InnoDB. –

+0

Abbastanza vero, ma se si dovesse assolutamente usare MyISAM, si potrebbe farcela con questi non FK effettivi, ma potrebbe influenzare l'integrità e la normalizzazione dei dati, attenersi a InnoDB –

+2

Vorrei andare con questo sistema così come semplifica notevolmente le query selezionate per cercare gli amici, soprattutto quando è necessario unirsi a questo tavolo. Tuttavia dovresti usare le transazioni e le stored procedure per assicurarti che entrambe le righe siano sempre inserite e cancellate insieme (tu ** non ** vuoi eliminare accidentalmente una delle due righe). –

3

L'utilizzo di doppie righe, mentre crea dati aggiuntivi, semplifica notevolmente le query e consente di indicizzare in modo intelligente. Ricordo anche di aver visto informazioni sulla soluzione MySQL personalizzata di Twitter, in cui utilizzavano un campo aggiuntivo (numero di amico, in pratica) per limitare e impaginare automaticamente. Sembra abbastanza agevole: https://blog.twitter.com/2010/introducing-flockdb

-6

Utilizzare un archivio di valori chiave, ad esempio Cassandra.

+0

La richiesta riguardava specificamente una soluzione MySQL. – ethanpil

3

È possibile verificare quale dei due user_id è il più basso e memorizzarli in un ordine specifico. In questo modo non hai bisogno di doppie file per un'amicizia e continui a mantenere le tue domande semplici.

user_id_low | user_id_high

una semplice query per verificare se sei già amici con qualcuno sarebbe:

<?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 si potrebbe trovare il più basso higest userid/mysql utilizzando

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

E per ottenere tutto ID dei tuoi amici

<?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

dopo aver guardato questo per mezzo minuto e sentendo mi sarebbe venuto fuori con una buona ragione per cui questo non dovrebbe essere usato. Ma no, non l'ho fatto. Questa non è una cattiva soluzione - abbastanza elegante in realtà :) in realtà questo supporta anche un sistema in cui è possibile organizzare un gruppo di 100 gruppi di amici, mettendoli tutti in un ordine asc/desc –

Problemi correlati