Jak implementovat symetrickou relaci mezi dvěma řádky jedné DB tabulky?
- mgagaj
- Člen | 2
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.
- mgagaj
- Člen | 2
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
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
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.