Jak implementovat symetrickou relaci mezi dvěma řádky jedné DB tabulky?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
mgagaj
Člen | 2
+
0
-

Dobrý den,

příklad – mám tabulku „uzivatel“, a chci vytvořit tabulku „kamarad“, která bude reprezentovat vztah mezi 2 uživateli.

Napadá mě jen toto:

uzivatel

id name
1 Aneta
2 Petr
3 Roman

kamarad

uzivatel1 uzivatel2
1 2
2 3

Toto reprezentuje, že Aneta se kamarádí s Petrem a Petr s Romanem. Správa takové databáze ale není moc jednoduchá, např. na zjištění, jestli Petr kamarádí s Anetou, je nutné ověřit dva případy
uzivatel1=1 and uzivatel2=2
uzivatel1=2 and uzivatel2=1

Chtěl bych to udělat čistěji. Příště může jít o jinou, složitější relaci – např. mezi 3 uživateli nebo obecně mezi n řádky tabulky.

PetrHH
Člen | 49
+
0
-

Dobrý den,

udělal bych to asi takto:

kamarad

id|uzivatel_id|jehokamrad_id
1 1 2
2 1 3
3 2 3

na kombinaci uzivatel_id a jehokamarad_id bych dal unique index.

Petr

mgagaj
Člen | 2
+
0
-

Děkuji za reakci – tohle je prakticky stejné, jako moje navrhované řešení (akorát jsi přidal sloupec „id“). Při složitějších dotazech typu „má Alena nějaké kamarády, kteří mají bydliště v Ostravě“ se ale musí vždycky udělat spojení výsledků dvou tabulek – nejdřív vyfiltrovat tabulku na případy, kdy se Alena nachází ve sloupci „uživatel“ a potom kdy se nachází ve sloupci „jehokamarád“.

Nešlo by to udělat jinak, efektivněji, opravdu symetricky?

David Matějka
Moderator | 6445
+
0
-

Pokud se chces drzet mysql, napadaji me dve rozumny reseni, bud ten vztah zrcadlit, tedy

uzivatel1 uzivatel2
1 2
2 1
2 3
3 2

nebo pro drzeni tech informaci o pratelstvi pouzit dve tabulky misto jedny (+ teda jedna pro uzivatele samotne). Jedna by drzela ID a pripadne dalsi info o pratelstvi (bez informace o zucastnenych osobach) a dalsi by drzela seznam „ucastniku“ pratelstvi, tedy

friendship
-----
id - PK

friendship_user
------
friendship_id
user_id

Tyto vzajemne vztahy mezi entitami resi dobre grafove databaze, treba neo4j, ale v tomto pripade to bude spise kanon na vrabce :)

Editoval matej21 (17. 10. 2014 15:11)

PetrHH
Člen | 49
+
0
-

Stejné mi to nepřipadá. Ty bys musel mít v tabulce kamaradi tolik sloupcu, kolik je uzivatelu-1.

Zatim jsem nic takoveho jako Ty neresil, ale toto by mohlo dobre fungovat:

select distinct
  uziv.id,uziv.jmeno from uziv
left join
  kamarad on uzivatel.id = kamarad.uzivatel_id
where
  kamarad.uzivatel_id=1 or kamarad.jehokamrad_id=1
having
  uzivatel.id<>1

a na tabulku povesit triggery, ktere se pri vlozeni/zmenene postaraji o pridani/smazani protilehle vazby.