![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Mam za zadanie zrobić serwis w stylu Friendster.com.
Schemat ideowy połączeń wygląda tak: Pan X zaprasza 10 znajomych, w tym pana Y, który ma 34 znajomy, a wsród nich jest pan Z, który posiada 73 znajomych, wsród których jest pan A itd itd... Czyli w skrócie: znajomi mojego znajomego są jednocześnie moimi znajomymi - i tak w pętli aż do końca - kurcze, aż ciężko to opisać :| I w związku z tym mam pytanie: w jaki sposób najlepiej zaprojektować tabelę z ID użytkowników, żeby to było szybkie i wydajne? Chodzi o jedną tabelę , która by zawierała połączenia między użytkownikami. -------------------- |
|
|
![]() |
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 148 Pomógł: 0 Dołączył: 16.06.2003 Ostrzeżenie: (0%) ![]() ![]() |
imho tak :
ID|name|FriendsID|ParentFriends iD| ID - wiadomo name - tez wiadmomo Friends ID - IDki osob ktore pan NAME ma wpisane jako przyjaciol ParentFriendsID - IDki osob ktore maja wpisanego pana Name jako friendsa... troche to zagmatwane ale male i dziala ![]() ![]() ![]() |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Yacho - wlasnie o takim czymś myślałem, ale w troche zmienionej postaci
Kod +----+------+----------+
| ID | MyID | IDFriend | +----+------+----------+ 1 34 345 2 34 4365 3 34 574 4 34 1065 5 4365 76322 6 4365 2574 ...... gdzie MyID to moje ID a dalej ID moich przyjaciół, a IDFriend to ID przyjaciół ludzi o ID z pola MyID. Czy dobrze uważam? Jakby mogło wyglądać przykładowe zapytanie na wyciagnięcie ID wszystkich osób powiązanych ze mną ![]() -------------------- |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 152 Pomógł: 0 Dołączył: 15.05.2002 Skąd: Łódź Ostrzeżenie: (0%) ![]() ![]() |
wydaje mi sie, ze tak jest najwydajniej. eq. jeszcze wywalic kolumne ID, a MyID | IDFriend oznaczyc jako primary key.
choc nie wiem. ale gdzies czytalem, ze tak wlasnie sie robi w takim szkielecie bazy. |
|
|
![]()
Post
#5
|
|
![]() Grupa: Przyjaciele php.pl Postów: 1 467 Pomógł: 13 Dołączył: 22.02.2003 Ostrzeżenie: (0%) ![]() ![]() |
a IMHO to można zrobić tak
people id, name - tutaj wszystko jasne friendshpis person_id, like_id person_id - id osoby ( references people bleble... ) like_id - osoby ktore lubi ( dla kazdej osoby nowy wpis ) potem superpętelka ( rekurnecyjna oczywiści ) i już |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 152 Pomógł: 0 Dołączył: 15.05.2002 Skąd: Łódź Ostrzeżenie: (0%) ![]() ![]() |
to samo mialem na mysli
|
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Ja też myślałem o 2 tabelach, ale tutaj chodziło o tą jedną tabelę-łącznik
![]() A czy da sie napisać takie zapytanie co na raz pobierze wszystkie ID-ki czy trzeba to juz przez php robić? -------------------- |
|
|
![]()
Post
#8
|
|
![]() Grupa: Przyjaciele php.pl Postów: 1 467 Pomógł: 13 Dołączył: 22.02.2003 Ostrzeżenie: (0%) ![]() ![]() |
Cytat A czy da sie napisać takie zapytanie co na raz pobierze wszystkie ID-ki czy trzeba to juz przez php robić? raczej tak. chyba, że by się pobawić ( tzn. zrobić sobie hardcorowego zajoba ) z pozapytaniami ( ale to tylko dal określonej głębokości by umiało ).
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 691 Pomógł: 0 Dołączył: 6.08.2003 Ostrzeżenie: (0%) ![]() ![]() |
Dwie uwagi:
- Przy tego typu bazach musisz sobie określić jakie zapytania będziesz wykonywał w ogóle, jakie najczęściej i pod to optymalizować schemat bazy. Nigdy nie będzie tak, aby baza była optymalna w każdym przypadku. - Należy znaleźć złoty środek między wydajnością a wielkością bazy i redundancją. W praktyce można zapomnieć o ideałach typu trzecia postać normalna czy brak redundancji. Oczywiście da się bazę w ten sposób zaprojektować, ale jej wydajność będzie daleka od ideału. Schemat który zaproponował Jabol jest naturalnym, książkowym rozwiązaniem, ale to co opisujesz jest drzewem (a nawet grafem), a to już nie jest najszczęśliwsza struktura do trzymania w relacjach. Generalnie, ustal: - ile może być maksymalnie zagłębień powiązań znajomości (być może nieskonczoność) - jakie informacje będziesz chciał od bazy uzyskiwać Wtedy będzie można myśleć nad schematem. |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Cytat Generalnie, ustal:
- ile może być maksymalnie zagłębień powiązań znajomości (być może nieskonczoność) - jakie informacje będziesz chciał od bazy uzyskiwać Ad.1 zakłądam, że nieskończoność, ale być może będzie ograniczenie do x poziomów (na razie nie wiem) Ad.2 wystarczą mi same ID osób i/lub ich liczba - resztę sam dopracuję |
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Hmm tak myśalałem sobie nad zapytaniem i nic nie mogę wymyślić. Natomiast szukanie ID z php w takiej drzewiastej strukturze to masakra... 90 sekund nie starcza :/
-------------------- |
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Więc tak - po kilku dyskusjach i wielu próbach doszedłem do takiego schematu i kodu jak poniżej - ale gdzieś tu jest bład logiczny... :|
![]() Dobra... mam wiec taka oto tabele: Kod myID | friendID | lev
gdzie lev to poziom "zaglębienia". Stworzylem sobie także przykladowa tabele users, gdzie mam ID i username. Oto kod, jaki wykorzystuje do dodawania danych: [php:1:df3c513c2f]<?php if(empty($_GET["myID"])) { $_GET["myID"]=186; } function dodaj_osobe($myID,$friendID,$lev="0") { #$prev= ($lev<1 ? 0 : ($lev<2 ? 1 : $lev-1)); if($myID!=$friendID) { if($lev<1) { $sql="SELECT count(myID) FROM god_connections WHERE myID='".$myID."' AND friendID='".$friendID."'"; } else { $sql="SELECT count(myID) FROM god_connections WHERE myID='".$myID."' AND friendID='".$friendID."' AND lev='".$lev."'"; } $q=mysql_query($sql); $ile=mysql_result($q,0); if($ile<1) { if(!mysql_query("INSERT INTO god_connections (myID,friendID,lev) VALUES (".$myID.",".$friendID.",".$lev.")")) { return(mysql_error()); } } } return(true); } if(empty($_GET["add"]) && empty($_GET["list"])) { $q=mysql_query("SELECT * FROM god_users"); while($t=mysql_fetch_array($q)) { echo "<a href=?add=".$t["id"]."&myID=".$_GET["myID"].">".$t["username"]."</a><br>"; } } elseif($_GET["add"]>0) { $q=mysql_query("SELECT * FROM god_connections WHERE friendID=".$_GET["myID"]." AND lev < 3") or die(mysql_error()); $i=0; while($t=mysql_fetch_array($q)) { $ids[$i]["myID"]=$t["myID"]; $ids[$i]["friendID"]=$t["friendID"]; $ids[$i]["t"]="m"; $ids[$i]["lev"]=$t["lev"]; $i++; } $q=mysql_query("SELECT * FROM god_connections WHERE myID=".$_GET["myID"]." AND lev < 3") or die(mysql_error()); while($t=mysql_fetch_array($q)) { $ids[$i]["friendID"]=$t["friendID"]; $ids[$i]["myID"]=$t["myID"]; $ids[$i]["t"]="f"; $ids[$i]["lev"]=$t["lev"]; $i++; } echo "<pre>"; print_r($ids); echo "</pre><br><br>"; echo dodaj_osobe($_GET["myID"],$_GET["add"]); dodaj_osobe($_GET["add"],$_GET["myID"]); foreach($ids AS $key=>$v) { $v["lev"]++; if($v["t"]=="m") { dodaj_osobe($v["myID"],$v["friendID"],$v["lev"]); } else { dodaj_osobe($v["friendID"],$v["myID"],$v["lev"]); } } } ?>[/php:1:df3c513c2f] Wiem, że to można było prościej napisać - ale tutaj chodzi tylko o sprawdzenie działania i przejrzystość (czyli powtórzenia) jest ważna. Zamieszczam całość bo może znajdzie się ktoś kto by to sprawdził - bede dozgonnie wdzięczny ![]() -------------------- |
|
|
![]()
Post
#13
|
|
![]() Grupa: Zarejestrowani Postów: 2 064 Pomógł: 1 Dołączył: 22.01.2003 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Więc problem jest taki:
za pierwszym dodaniem przy pomocy powyżzego kodu w tabeli mam takie coś: Kod myID friendID lev
186 106 0 106 186 0 Czyli zgodnie z planem, ale przy drugim dodaniu (już innego usera): Kod myID friendID lev
186 106 0 106 186 0 186 153 0 153 186 0 106 186 1 a zamiast 106 | 186 powinno być chyba 153 | 186 oraz 106 |153, 153|106 itd - czyli każdy z każdym (+ odpowieni poziom)... -------------------- |
|
|
![]()
Post
#14
|
|
![]() Grupa: Przyjaciele php.pl Postów: 1 467 Pomógł: 13 Dołączył: 22.02.2003 Ostrzeżenie: (0%) ![]() ![]() |
zablokowane na życzenie autora
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 19.07.2025 - 20:55 |