Venn av en venn i PHP / MySQL?

stemmer
2

Jeg har et sosialt nettverk som ligner på myspace / facebook. I min kode er du enten en persons venn eller ikke venn, så jeg viser alle handlinger fra folk du er venner med (i dette innlegget vil jeg referere til handlinger som oppslags innlegg alene for å gjøre det enklere å visualisere.

Så du hver gang en person legger ut et nyhetsbrev vil det dukke opp til enhver person som er der venn.

I mysql vil du få en persons venneliste ved å gjøre noe som dette,

SELECT user_id FROM friends WHERE friend_id = 1 (user ID)

Jeg vil vite hvordan et nettsted som facebook og noen andre ville vise alle oppslags innlegg fra vennene dine og fra venners venner?

Hvis noen har en idé du vise noen kode som hva slags mysql spørringen?

Publisert på 29/12/2009 klokken 23:07
kilden bruker
På andre språk...                            


5 svar

stemmer
3

du gjør en delspørring:

SELECT DISTINCT user_id FROM friends WHERE friend_id IN (SELECT user_id FROM friends WHERE friend_id = 1)

Svarte 29/12/2009 kl. 23:12
kilden bruker

stemmer
2

Test begge disse for ytelse:

SELECT DISTINCT user_id
FROM friends f1
JOIN friends f2 ON f1.friend_id = f2.user_id
WHERE f2.friend_id = 1

og

SELECT DISTINCT user_id
FROM friends
WHERE friend_id IN (SELECT user_id FROM friends WHERE friend_id = 1)

Ofte er de samme, men noen ganger er de ikke.

Sørg for friend_id og user_id er indeksert.

Svarte 29/12/2009 kl. 23:16
kilden bruker

stemmer
6

Svaret er at de ikke gjør velger på en venn bordet, de er mest sannsynlig å bruke en de-normalisert news-event bord. Vi gjennomførte en nyhetsmating lik Facebooks på DoInk.com, her er hvordan vi gjorde det:

Det er tanken om en "NewsEvent" den har en form, en initiator (en bruker-ID) og en målbruker (også en bruker-ID). (Du kan også ha ekstra kolonne (er) for andre egenskaper som er relevante for arrangementet, eller bli med dem i)

Når en bruker poster noe på en annen brukerne vegg genererer vi et arrangement som dette:

INSERT INTO events VALUES (wall_post_event, user1, user1)

Når du ser bruker1 profil, vil du velge for alle arrangementer hvor bruker1 er enten initiativtaker eller målet. Det er hvordan du viser profilen feed. (Du kan få fancy og filtrere ut hendelser avhengig av ditt privatliv modell. Du kan vurdere å gjøre dette i minne for bedre ytelse)

Eksempel:

SELECT * FROM events WHERE initiator = user1 or target = user1 //to see their profile feed

SELECT * FROM events WHERE initiator IN (your set of friend ids) //to see your newsfeed

Når du ønsker å se newsfeed for alle hendelser i forhold til vennene dine at du kan gjøre en spørring velge for alle arrangementer hvor initiativtaker er i sett med venner.

Unngå implementeringer med under velger, avhengig av kompleksiteten, de vil ikke skalere.

Svarte 29/12/2009 kl. 23:20
kilden bruker

stemmer
1

Den enkle tilnærming ville være å gjøre noen form for enkel nestet klausulen. Så sier du har en tabell med innlegg og plakater id, og en tabell venner, ville det første laget være

SELECT post FROM posts JOIN friends 
  on post.userid = friends.friend_id 
  WHERE friend.id = 1 (user ID)

deretter å få en venners venner

SELECT post FROM posts JOIN
   (SELECT DISTINCT friends_2.friend_id FROM friends AS friends_1 
        JOIN friends as friends_2 
        on friends_1.friend_id = friends_2.id where friends_1.id = 1) 
AS friends 
wHERE post.userid = friends.friend_id AND mainid = 1 (user ID)

Du kan gjenta denne hekkende hver gang du ønsker å legge et lag av venn abstraksjon. Problemet med denne tilnærmingen er at det vil ta svært lang tid å gjennomføre. For hver gang du legger et lag med venn abstraksjon du øker kompleksiteten ved en kraft n (der n er antall rader i tabellen).

Det er mer sannsynlig at de sparer det synlige venner i en tabell et sted, så kan lage en ny fremmet kalt friends_web

user_id, friend_id, level

når en bruker venner noen, legger det ut til at ny venn inn friends_web på et nivå fra 0 (siden den vennen er ingen mennesker unna) så legger til at venners venner på et nivå på 1 (siden en venn unna). For å holde tabellen integritet vil du også ønsker å legge den omvendte posten. For å avklare om en legger B som en venn og C er en venn av B, vil følgende to postene bli lagt til vår nye tabellen

A, C, 1
C, A, 1

siden nå En kan se C og C kan se A.

Nå når vi ønsker en spørring vi bare gjøre

 SELECT post FROM posts 
  JOIN friends_web ON post.user_id = friends_web.friend_id 
  WHERE friends_web.user_id = user_id AND friends_web.level < 2 (or however deep you want to look)

ved å gjøre det du minimert søket kompleksitet når du gjør legg oppslag og være i stand til å se mer enn ett lag dypt inn i en venn web.

Beklager for lang omstendelig svar.

Svarte 29/12/2009 kl. 23:52
kilden bruker

stemmer
0

Dette bør trekke ut alle brukerens venns innlegg.

SELECT * FROM posts WHERE uid IN (SELECT friend_uid FROM friends WHERE uid=1) ORDER BY post_id DESC

Dette bør trekke ut alle innlegg som er din venns venn.

SELECT * FROM posts WHERE uid IN (SELECT friend_uid FROM friends WHERE uid IN (SELECT friend_uid FROM friends WHERE uid=1)) ORDER BY post_id DESC

Svarte 30/12/2009 kl. 00:14
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more