Grafová databáze
Grafové databáze jsou databáze, kde se data ukládají ve formě grafu, což lépe odpovídá reálným vztahům mezi objekty. Jako objekty si představme jakékoliv objekty reálného světa, které lze seskupit do tzv. typů (v objektově orientovaném programování používáme pojem třídy).
Grafová databáze se skládá ze dvou základních částí:
Uzly (nodes)
- též vrcholy
- představují konkrétní objekty z reálného světa
- jsou jednoho typu
- mají vlastnosti
Hrany (edges)
- reprezentují vztahy mezi uzly
- mají směr
- jsou jednoho typu
- spojnice, které dávají datům kontext
Anatomie uzlu
Uzel je základní objekt (entita), která nese data:
- typ uzlu (například Person, Goods, Subject)
- vlastnosti (například firstName, lastName, title, birthDate)
- vlastnosti mají konkrétní hodnoty (firstName: „Jan“, lastName: „Syrový“)
- vlastnosti s hodnotami tvoří key-value páry
- každému uzlu se automaticky přiřadí ID
Příklad:
p:Person {
firstName: "Jan",
lastName: "Syrový",
birthDate: "2008-07-01",
eyeColour: "blue"
}

Vlastnosti jednotlivých uzlů ani typů uzlů nejsou nikde napevno nadefinované. Proto každý uzel může mít různé vlastnosti podle toho, co potřebujeme evidovat. Na druhou stranu z důvodu snadného výběru uzlů silně doporučuji mít stejná data uložená ve stejných vlastnostech.
p:Person{
firstName: "Lukáš",
lastName: "Novák",
birthDate: "2008-04-15",
maxBench: 115,
maxBenchDate: "2026-04-12"
}
p2:Person{
krestni: "Dan",
prijmeni: "Schlagsahne",
birthDate: "2008-12-01",
longestTrip: 2050,
longestTripYear: 2025
}
Na příkladu výše vidíte dva uzly typu Person, u kterých si můžete všimnout odlišnosti názvů jednotlivých vlastností. To, že Lukáš má vlastnosti maxBench a Dan longestTrip je naprosto v pořádku – u každého uzlu mohu sledovat různé vlastnosti. To, že křestní jméno u Lukáše je ale uloženo ve vlastnosti firstName a u Dana ve vlastnosti krestni, nám v budoucnu může způsobovat problémy při práci s uzly.
Anatomie hrany
Hrana spojuje jednotlivé uzly. Každá hrana má:
- směr – hrany jsou vždy orientované, mají směr od jednoho uzlu ke druhému. Pokud je vztah obousměrný, budou mezi uzly dvě hrany (každá jedním směrem).
- typ hrany (label) – definuje povahu vztahu (například friendOf, married, worksAt, bought)
- vlastnosti – také hrany mohou mít vlastnosti (jsou opět tvořeny key-value páry) – například u hrany typu married bude marriageDate nebo marriagePlace, u hrany typu worksAt může být since a until (data zaměstnání od–do)
(p:Person {firstName:"Jan"}-[f:friendOf {since:"2023-09-01"}]->(p2:Person {firstName:"Lukáš"})

Průchod grafem
Na rozdíl od tradičních relačních databází, kde se vztahy odvozují prostřednictvím spojení primárních a cizích klíčů a pomocí JOINů, ukládají grafové databáze vztahy nativně. To znamená, že vazby jsou přímou součástí samotné datové struktury, což umožňuje mnohem rychlejší dotazování a přirozenější navigaci mezi uzly. Fyzicky jsou totiž hrany reprezentovány jako ukazele (pointery) v paměti – tím odpadá nutnost prohledávat tabulky a indexy – databázový systém při dotazu doslova „přeskočí“ z jednoho uzlu na druhý v konstantním čase (tzv. index-free adjacency).
Tento proces přechodu z jednoho uzlu do druhého pomocí hran se nazývá průchod grafem (graph traversal). Tyto průchody dokážou s vysokou účinností odhalovat skryté vzory, hledat nejkratší cesty nebo identifikovat shluky (clustery) v datech.
Tento posun v myšlení – od pevných tabulkových dat k síti propojených dat – umožňuje zkoumat zcela nové vrstvy otázek. Namísto filtrování statických záznamů tedy grafová databáze umožňuje sledovat návaznosti a vidět, jak se jednotlivé uzly navzájem ovlivňují v reálném čase.
Použití grafové databáze
Grafovou databázi používáme v případě, že vztahy mezi jednotlivými objekty jsou stejně důležité nebo důležitější než objekty samy. Příklady použití:
- sociální sítě (propojení přátel a přátel mých přátel)
- doprava a logistika (hledání nejkratší cesty, optimalizace tras v reálném čase)
- indexace webu (propojení stránek pomocí odkazů)
- sítě a IT (správa síťové infrastruktury, analýza dopadů výpadků)
- zpracování jazyka (znalostní grafy pro sémantické vyhledávání a chatboty)
- genetika a medicína (mapování interakcí mezi proteiny a geny)
Výhoda ukládání hran pomocí ukazatelů v paměti se naplno projeví ve chvíli, kdy data tvoří složitou síť a potřebujeme se ptát na hlubší souvislosti. Typické příklady:
- sociální sítě – představte si dotaz „Najdi všechny přátele mých přátel, kteří pracují ve stejné firmě jako já, ale já je ještě neznám“. V relační databázi by to znamenalo několik složitých JOINů nad relacemi s miliony záznamů. V grafové databázi jednoduše začneme od Vás jako počátečního uzlu na uzly přátel a jejich přátel a vybereme dle spojení se stejným uzlem zaměstnavatele.
- odhalování podvodů – banka hledá podezřelý vzor (pattern) „Uživatel A posílá peníze na účet uživatele B, který ale sdílí stejnou IP adresu s uživatelem C, který je na black listu.“ Cílem banky je tuto operaci zastavit v momentě, kdy ji uživatel A chce provést. Rychlé propojení těchto zdánlivě nesouvisejících bodů pomocí průchodu grafem umožňuje zablokovat tuto podvodnou transakci ještě před jejím dokončením.
Srovnání relační a grafové databáze
Zkusme si nejprve srovnat jednotlivá složení relační databáze a grafové databáze. Víme, že relační databáze se skládá z relací (entit), které jsou popisované atributy a které obsahují jednotlivé záznamy. Grafová databáze se skládá z uzlů (vždy konkrétního typu) a hran, které uzly propojují.
| vlastnost | relační databáze | grafová databáze |
|---|---|---|
| seskupení objektů | relace s pevnou strukturou dat | typy uzlů, volná struktura dat |
| objekty reálného světa | záznamy relací | uzly |
| popisy objektů | atributy relací | vlastnosti uzlů |
| propojení objektů | vztahy pomocí primárních a cizích klíčů, realizace podle typu kardinalit | hrany |
| popis propojení objektů | vlastnosti vztahů pomocí atributů v rozkladové relaci | vlastnosti hran |
Pojďme si porovnat obecné chování jednotlivých typů databází, samozřejmě s jistou dávkou zobecnění:
| vlastnost | relační databáze | grafová databáze |
|---|---|---|
| struktura | pevná struktura relací tvořená konkrétními atributy určených datových typů | uzly a hrany bez schématu |
| propojení | JOINy (výpočetně náročné) | nativní ukazatele (rychlé) |
| složité dotazy | rychlost klesá společně s počtem JOINů | konstantní rychlost průchodu |
| rychlost dotazu s hloubkou dotazu 3+ | ~2000 ms (musí procházet indexy databázových tabulek) | ~50 ms (sleduje ukazatele v paměti) |
neo4j
Neo4j je nejpoužívanější grafová databáze na světě. Místo tabulek pracuje přímo s objekty a jejich vazbami.
- nativní ukládání grafů: Efektivní indexace.
- Cypher: Deklarativní dotazovací jazyk (obdoba SQL pro grafy).
- vizualizace: Grafické rozhraní pro prohlížení vztahů.
Neo4j pro lokální instalaci si můžete stáhnout z oficiálního webu zde: https://neo4j.com/download/
Vytvoření uzlu
CREATE (p:Person {firstName: "Jaroslav", lastName: "Kolenatý", birthDate: "2008-12-14", maxBench: 125}) RETURN p;
Za příkazem CREATE si definujeme novou proměnnou p, která je platná pouze po dobu vykonávání příkazu. Používáme ji v druhé části příkazu (RETURN p), který grafové databázi říká, aby poté, co uzel vytvoří, nám jej ještě ukázala.
Ve složených závorkách vidíme jednotlivé key-value páry, kdy nastavujeme vlastnosti a hodnoty konkrétnímu vytvářenému uzlu.
Výběr uzlu
MATCH (p:Person {lastName: "Kolenatý"}) RETURN p;
MATCH (p:Person) WHERE elementId(p) = "4:8d77cc4c-2eeb-44e2-815e-a1f5c9cfed15:1" RETURN p;
V prvním případě vidíme výběr všech uzlů typu Person, jejichž atribut lastName má hodnotu Kolenatý.
Ve druhém případě vidíme výběr konkrétního uzlu typu Person na základě automaticky stanoveného ID.
Vytvoření hrany mezi uzly
Pro vytvoření hrany si nejprve musíme vybrat dva konkrétní uzly. Doporučuji zpočátku si napřed zobrazit pomocí příkazu MATCH uzly, které chceme propojit, abychom propojovali skutečně pouze tyto dva uzly. Například:
MATCH (p:Person {firstName:"Lukáš"}), (e:Employer {name:"Google"}) RETURN p, e;

Nyní máme jistotu, že se nevybraly jiné uzly než přesně ty, které chceme propojit. Můžeme tedy do příkazu doplnit vytvoření hrany:
MATCH (p:Person {firstName:"Lukáš"}), (e:Employer {name:"Google"})
CREATE (p)-[w:worksAt]->(e)
RETURN p, w, e;

Nastavení dalších vlastností
Potřebujeme-li nastavit další vlastnosti uzlu či hrany, postupujeme tak, že jej nejprve vybereme a následně použijeme příkaz SET:
MATCH (n:Person {lastName:"Syrový"}) SET n.maxBench = 95 RETURN n;
MATCH (p:Person {firstName:"Lukáš"})-[w:worksAt]->(e:Employer {name:"Google"}) SET w.since = "2026-01-02" RETURN p, w, e;
Smazání uzlu
Také v případě, že chceme uzel smazat, jej nejprve vybereme pomocí příkazu MATCH a následně zadáme příkaz DELETE:
MATCH (n:Person {firstName: "Smažák"}) DELETE n;
MATCH (p:Person) WHERE elementId(p)="4:8d77cc4c-2eeb-44e2-815e-a1f5c9cfed15:3" DELETE p;
Další výběry
MATCH (n:Person) RETURN n;
MATCH (p)-[f:friendOf]->(p2) RETURN p,f,p2;
První výběr vybere všechny uzly typu Person. V praxi bychom jej asi takto příliš nepoužili – velké množství uzlů by nám zahltilo paměť. Druhý výběr vybere všechny uzly, které mezi sebou mají hranu typu friendOf.
Pokud chceme například vybrat pouze uzly, které mají mezi sebou vzájemné vazby (jeden je kamarád druhého a druhý prvního), můžeme využít například:
MATCH (p)-[f:friendOf]->(p2),
(p2)-[f2:friendOf]->(p)
RETURN p, f, f2, p2;
Pokud chceme vybrat přátele mých přátel, které já nemám za přátele, zeptáme se:
MATCH (ja:Person {fName:"Otokar", lName:"Březina"})-[:friendOf]->(p2)-[:friendOf]->(p3)
WHERE NOT (ja)-[:friendOf]->(p3)
RETURN DISTINCT p3;
Podcast
Podcast byl vygenerován službou NotebookLM na podkladě této výukové stránky.
instancí třídy (!pozor! nikoliv samotnou třídou)
Ne, vlastnosti nejsou nikde napevno nadefinované. Každý uzel může mít různé vlastnosti.
MATCH
Typ uzlu (label).
Vztahy mezi konkrétními uzly (například uzel „Jan“ se kamarádí s uzlem „Anežka“).
Cypher
Záznam v relaci (pozor – nikoliv celá relace).
SET
CREATE
Sledují přímé ukazatele v paměti (pointery) namísto procházení klíčů a spojování tabulek pomocí JOINů.
Pár key–value (klíč–hodnota) ukládající metadata jak o uzlech, tak o hranách.
Konkrétní objekt, jako například konkrétní osobu, produkt, nábytek nebo účet.