|
[ fatality1 @ 18.05.2009. 14:35 ] @
| eh ovako
imam zadatak da uradim social network , sto i nije neki problem , znaci malo dizajna , malo sql-a i to bi se dalo rijesiti , ali ima jedna dodatna stvar , koja je i sustina tog zadatka a to su "veze" medju korisnicima.naime , npr. imam 4 korisnika , korisnik 1 , korisnik 2 , korisnik 3 i korisnik 4 , i sada korisnik 1 je prijatelj sa korisnikom 2 , korisnik 2 je prijatelj sa korisnikom 3 a korisnik 3 je prijatelj sa korisnikom 4 , sto bi u sql nekako ovako izgledalo :
ID friend-ID
1 2
2 3
3 4
eh tu je sada problem , jer bih trebao prikazati kako od korisnika 1 doci do korisnika 4 , odnosno preko koje relacije se korisnik 1 i korisnik 4 znaju (moze biti i vise puteva , npr. korisnik 1 zna korisnika 2 i korisnika 3 , a korisnik 2 i korisnik 3 znaju korisnika 4)
uglavnom ja sam nasao nesto na netu , ali je uradjeno na temelju novog oracle dok tih opcija nema u sql-u
(npr. ovakva relacija)
1->2->3->4
poslije bih ovo jos trebao nekako graficki predstaviti , ali mi je prvo bitno da shvatim kako ove relacije dobiti
i eto zamolio bih ako neko zna neki sajt ili tutorial ili ako ima neke upute da podijeli na forumu:)
a evo sta sam ja nasao :
http://www.tutorials.de/forum/1380293-post8.html
|
[ Goran Rakić @ 18.05.2009. 15:07 ] @
[ bogdan.kecman @ 18.05.2009. 15:14 ] @
koji deo ovoga sto je Thomas napisao ti nije jasan ? realno, moze da se izbaci t_friend.id iz t_friend tabele i da t_friend.userid i t_friend.friendid budu kompozitni primarni kljuc (sto bi bilo bolje nego kako je sada i malo bi ubrzalo sve operacije nad bazom), ali generalno, to je to ... onaj upit bi morao malo da se prebudzi za mysql ...
Code:
mysql> drop table t_user;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE t_user (id int auto_increment primary key, name varchar(255) NOT NULL);
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> CREATE TABLE t_friend (userid int NOT NULL, friendid int NOT NULL, PRIMARY KEY (userid, friendid));
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> INSERT INTO `t_user` (name) VALUES ('pera'), ('mika'), ('zika'), ('laza'),('selma'),('zozefina'),('enena');
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> INSERT INTO `t_friend` VALUES (1,2),(1,3),(1,5),(2,3),(2,5),(2,6),(3,7),(3,4);
Query OK, 8 rows affected (0.00 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> -- koga zna pera
mysql> SELECT k1.friendid FROM t_friend k1 WHERE k1.userid=1;
+----------+
| friendid |
+----------+
| 2 |
| 3 |
| 5 |
+----------+
3 rows in set (0.00 sec)
mysql> -- do koga sve pera moze da dodje preko prvog kolena
mysql> SELECT k1.friendid, k2.friendid FROM (SELECT t_friend.friendid FROM t_friend WHERE t_friend.userid=1) k1 JOIN t_friend k2 ON (k2.userid = k1.friendid);
+----------+----------+
| friendid | friendid |
+----------+----------+
| 2 | 3 |
| 2 | 5 |
| 2 | 6 |
| 3 | 4 |
| 3 | 7 |
+----------+----------+
5 rows in set (0.00 sec)
mysql> -- ili ovako, mada je ovo prethodno bolje
mysql> SELECT k1.friendid, k2.friendid FROM (SELECT t_friend.friendid FROM t_friend WHERE t_friend.userid=1) k1 LEFT JOIN t_friend k2 ON (k2.userid = k1.friendid);
+----------+----------+
| friendid | friendid |
+----------+----------+
| 2 | 3 |
| 2 | 5 |
| 2 | 6 |
| 3 | 4 |
| 3 | 7 |
| 5 | NULL |
+----------+----------+
6 rows in set (0.00 sec)
mysql> -- ocemo trece koleno ?
mysql> SELECT k1.friendid, k2.friendid, k3.friendid FROM (SELECT t_friend.friendid FROM t_friend WHERE t_friend.userid=1) k1 JOIN t_friend k2 ON (k2.userid = k1.friendid) JOIN t_friend k3 ON (k3.userid = k2.friendid);
+----------+----------+----------+
| friendid | friendid | friendid |
+----------+----------+----------+
| 2 | 3 | 4 |
| 2 | 3 | 7 |
+----------+----------+----------+
2 rows in set (0.00 sec)
mysql> -- ili ovako?
mysql> SELECT k1.friendid, k2.friendid, k3.friendid FROM (SELECT t_friend.friendid FROM t_friend WHERE t_friend.userid=1) k1 LEFT JOIN t_friend k2 ON (k2.userid = k1.friendid) LEFT JOIN t_friend k3 ON (k3.userid = k2.friendid);
+----------+----------+----------+
| friendid | friendid | friendid |
+----------+----------+----------+
| 2 | 3 | 4 |
| 2 | 3 | 7 |
| 2 | 5 | NULL |
| 2 | 6 | NULL |
| 3 | 4 | NULL |
| 3 | 7 | NULL |
| 5 | NULL | NULL |
+----------+----------+----------+
7 rows in set (0.00 sec)
mislim da dalje umes sam ...
[ bogdan.kecman @ 18.05.2009. 15:18 ] @
da, ako neces za samo jednog usera ..
Code:
mysql> SELECT k1.userid, k1.friendid, k2.friendid, k3.friendid FROM t_friend k1 LEFT JOIN t_friend k2 ON (k2.userid = k1.friendid) LEFT JOIN t_friend k3 ON (k3.userid = k2.friendid);
+--------+----------+----------+----------+
| userid | friendid | friendid | friendid |
+--------+----------+----------+----------+
| 1 | 2 | 3 | 4 |
| 1 | 2 | 3 | 7 |
| 1 | 2 | 5 | NULL |
| 1 | 2 | 6 | NULL |
| 1 | 3 | 4 | NULL |
| 1 | 3 | 7 | NULL |
| 1 | 5 | NULL | NULL |
| 2 | 3 | 4 | NULL |
| 2 | 3 | 7 | NULL |
| 2 | 5 | NULL | NULL |
| 2 | 6 | NULL | NULL |
| 3 | 4 | NULL | NULL |
| 3 | 7 | NULL | NULL |
+--------+----------+----------+----------+
13 rows in set (0.00 sec)
to sad sve moze verovatno jos malo da se optimizuje .. ovako sam cukao realtime po klijentu :)
[ fatality1 @ 18.05.2009. 16:04 ] @
prvo , hvala velika na odgovoru , ovako nesta mi i treba :)
a jos jedno pitanje , vidim da ti veze nisi snimao dva puta , npr. kod mene ako su user 1 i user 2 prijatelji imam dva unosa u t_friend tabeli (jedan gdje je user 1 friend , a drugi kada je user 2 friend) , i onda kod ovih upita gore dobijem malo izmiksane rezultate , tj. evo vidim desi se da ako krenem od user 1 , i trazim njegove prijatelje nekad nadje i sebe (jer dodje do user 2 a posto je i on prijatelj sa user 1 izbaci mi i to kao rjesenje) , i tu bih te htio pitat ima li nekakav drugi nacin da rijesim ove veze ili ih pak moram sve duplo unositi
[ bogdan.kecman @ 18.05.2009. 16:44 ] @
pogledaj malo po netu, sigurno ima resenje sa malo vise "razmisljanja" .. ovo sada je vec "budzenje" :)
Code:
mysql> SELECT k1.userid, k1.friendid, k2.friendid, k3.friendid FROM t_friend k1
-> LEFT JOIN t_friend k2 ON (k2.userid = k1.friendid or k2.friendid = k1.userid)
-> LEFT JOIN t_friend k3 ON (k3.userid = k2.friendid or k3.friendid = k2.userid);
+--------+----------+----------+----------+
| userid | friendid | friendid | friendid |
+--------+----------+----------+----------+
| 1 | 2 | 3 | 2 |
| 1 | 2 | 3 | 4 |
| 1 | 2 | 3 | 7 |
| 1 | 2 | 5 | 2 |
| 1 | 2 | 6 | 2 |
| 1 | 3 | 4 | 3 |
| 1 | 3 | 4 | 3 |
| 1 | 3 | 7 | 3 |
| 1 | 3 | 7 | 3 |
| 1 | 5 | NULL | NULL |
| 2 | 3 | 2 | 3 |
| 2 | 3 | 2 | 5 |
| 2 | 3 | 2 | 6 |
| 2 | 3 | 4 | 3 |
| 2 | 3 | 4 | 3 |
| 2 | 3 | 7 | 3 |
| 2 | 3 | 7 | 3 |
| 2 | 5 | 2 | 3 |
| 2 | 5 | 2 | 5 |
| 2 | 5 | 2 | 6 |
| 2 | 6 | 2 | 3 |
| 2 | 6 | 2 | 5 |
| 2 | 6 | 2 | 6 |
| 3 | 4 | 3 | 4 |
| 3 | 4 | 3 | 7 |
| 3 | 4 | 3 | 2 |
| 3 | 4 | 3 | 4 |
| 3 | 4 | 3 | 7 |
| 3 | 7 | 3 | 4 |
| 3 | 7 | 3 | 7 |
| 3 | 7 | 3 | 2 |
| 3 | 7 | 3 | 4 |
| 3 | 7 | 3 | 7 |
+--------+----------+----------+----------+
33 rows in set (0.00 sec)
ali generalno, sada su (1,2) i (2,1) isti .. tj ako pera zna miku to znaci da i mika zna peru (ne bas uvek tacno u realnom zivotu...)
[ fatality1 @ 18.05.2009. 16:53 ] @
e bas to kod tebe u prvom redu sto stoji , znaci 1-2-3-2 , to cu jos malo pokusat optimirat , da mi ne izbacuje dva puta isti ID , vjerovatno cu pogled toga moci nesta i u javi odraditi , tj. nakon sto ucitam ovaj query
[ bogdan.kecman @ 18.05.2009. 23:09 ] @
iskreno ne znam kako bih ga ja radio ... dal bi samo citao iz baze raw data pa slagao graf u hl jeziku ili vadio neki stat iz mysql-a direktno ... koristio neke stored procedures ili udf-ove ... ovako na jedan, iz konzole sam nacukao sta je bilo "najjednostavnije" .. neko "najoptimalnije" resenje bi zahtevalo malo vise truda, ali verujem da imas dovoljno za pocetak :) ipak je to tvoj zadatak :D
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|