Relační databáze dominují ve správě dat po celá desetiletí, ale nedávno ztratily půdu pod nohama alternativami. I když úložiště dat NoSQL nejsou správná pro každý případ použití, jsou obecně lepší velká data, což je zkratka pro systémy, které zpracovávají obrovské objemy dat. Pro velká data se používají čtyři typy úložiště dat:
- Úložiště klíč / hodnota, například Memcached a Redis
- Dokumentově orientované databáze jako MongoDB, CouchDB a DynamoDB
- Sloupcově orientovaná datová úložiště, jako jsou Cassandra a HBase
- Grafické databáze jako Neo4j a OrientDB
Tento výukový program představuje Neo4j, což je databáze grafů používaná pro interakci s vysoce související data. Zatímco relační databáze jsou dobré při správě vztahů mezi data, databáze grafů jsou lepší při správě n-tý stupně vztahů. Jako příklad si vezměte sociální síť, kde chcete analyzovat vzorce zahrnující přátele, přátele přátel atd. Databáze grafů by usnadnila odpověď na otázku typu: „Vzhledem k pěti stupňům oddělení, jaké jsou pět filmů populárních v mé sociální síti, které jsem ještě neviděl?“ Takové otázky jsou běžné pro doporučovací software a databáze grafů jsou ideální pro jejich řešení. Databáze grafů navíc dobře reprezentují hierarchická data, například řízení přístupu, katalogy produktů, databáze filmů nebo dokonce topologie sítí a organizační schémata. Pokud máte objekty s více vztahy, rychle zjistíte, že databáze grafů nabízejí elegantní objektově orientované paradigma pro správu těchto objektů.
Případ databází grafů
Jak název napovídá, databáze grafů dobře reprezentují grafy dat. To je užitečné zejména pro sociální software, kde pokaždé, když se s někým spojíte, je mezi vámi definován vztah. Pravděpodobně při svém posledním hledání zaměstnání jste si vybrali několik společností, které vás zajímaly, a poté jste ve svých sociálních sítích hledali spojení. I když možná neznáte nikoho, kdo pracuje pro některou z těchto společností, pravděpodobně to někdo ve vaší sociální síti ví. Řešení takového problému je snadné při jednom nebo dvou stupních oddělení (váš přítel nebo přítel přítele), ale co se stane, když začnete rozšiřovat vyhledávání po celé síti?
Ve své knize Neo4j In Action zkoumají Aleksa Vukotic a Nicki Watt rozdíly mezi relačními databázemi a databázemi grafů pro řešení problémů sociálních sítí. Pro několik dalších příkladů čerpám z jejich práce, abych vám ukázal, proč se databáze grafů stávají stále oblíbenější alternativou relačních databází.
Modelování složitých vztahů: Neo4j vs MySQL
Z pohledu informatiky, když přemýšlíme o modelování vztahů mezi uživateli v sociální síti, můžeme nakreslit graf jako ten na obrázku 1.
Steven HainesUživatel má IS_FRIEND_OF
vztahy s ostatními uživateli a tito uživatelé mají IS_FRIEND_OF
vztahy s ostatními uživateli atd. Obrázek 2 ukazuje, jak bychom to reprezentovali v relační databázi.
The UŽIVATEL
tabulka má vztah jedna k mnoha s USER_FRIEND
tabulka, která modeluje vztah „přátel“ mezi dvěma uživateli. Nyní, když jsme modelovali vztahy, jak bychom dotazovali naše data? Vukotic a Watt měřili výkon dotazu pro počítání počtu odlišných přátel, kteří šli do hloubky pěti úrovní (přátelé přátel přátel přátel přátel přátel). V relační databázi by dotazy vypadaly takto:
# Hloubka 1 vyberte počet (odlišný uf. *) Od user_friend uf kde uf.user_1 =? # Hloubka 2 vyberte počet (odlišný uf2. *) Od user_friend uf1 vnitřní spojení user_friend uf2 na uf1.user_1 = uf2.user_2 kde uf1.user_1 =? # Hloubka 3 vyberte počet (odlišný uf3. *) Od t_user_friend uf1 vnitřní spojení t_user_friend uf2 na uf1.user_1 = uf2.user_2 vnitřní spojení t_user_friend uf3 na uf2.user_1 = uf3.user_2 kde uf1.user_1 =? # A tak dále...
Zajímavé na těchto dotazech je to, že pokaždé, když vyjdeme o jednu úroveň více, musíme se připojit USER_FRIEND
stůl sám se sebou. Tabulka 1 ukazuje, co výzkumníci Vukotic a Watt našli, když vložili 1 000 uživatelů s přibližně 50 vztahy každý (50 000 vztahů) a spustili dotazy.
Tabulka 1. Doba odezvy na dotaz MySQL pro různé hloubky vztahů
DepthExecution time (seconds) Count result
2 | 0.028 | ~900 |
3 | 0.213 | ~999 |
4 | 10.273 | ~999 |
5 | 92.613 | ~999 |
MySQL dělá skvělou práci při spojování dat až o tři úrovně dál, ale výkon se poté rychle sníží. Důvodem je, že pokaždé, když USER_FRIEND
tabulka je spojena sama se sebou, MySQL musí spočítat kartézský součin tabulky, přestože většina dat bude vyhozena. Například při provádění tohoto spojení pětkrát má kartézský součin 50 000 ^ 5 řádků nebo 102,4 * 10 ^ 21 řádků. To je plýtvání, když nás zajímá pouze 1 000 z nich!
Dále se Vukotic a Watt pokusili provést stejný typ dotazů proti Neo4j. Tyto zcela odlišné výsledky jsou uvedeny v tabulce 2.
Tabulka 2. Doba odezvy Neo4j pro různé hloubky vztahů
DepthExecution time (seconds) Count result
2 | 0.04 | ~900 |
3 | 0.06 | ~999 |
4 | 0.07 | ~999 |
5 | 0.07 | ~999 |
Stánek s jídlem z těchto srovnání provedení je ne že Neo4j je lepší než MySQL. Spíše při procházení těmito typy vztahů závisí výkon Neo4j na počtu načtených záznamů, zatímco výkon MySQL závisí na počtu záznamů v USER_FRIEND
stůl. Jak se tedy zvyšuje počet vztahů, doba odezvy pro dotazy MySQL se rovněž zvýší, zatímco doba odezvy pro dotazy Neo4j zůstane stejná. Důvodem je, že doba odezvy Neo4j závisí na počtu vztahů pro konkrétní dotaz, a nikoli na celkovém počtu vztahů.
Škálování Neo4j pro velká data
Vukotic a Watt rozšířili tento myšlenkový projekt o krok dále a vytvořili milion uživatelů s 50 miliony vztahů mezi nimi. Tabulka 3 ukazuje výsledky pro daný soubor dat.
Tabulka 3. Doba odezvy Neo4j pro 50 milionů vztahů
DepthExecution time (seconds) Count result
2 | 0.01 | ~2,500 |
3 | 0.168 | ~110,000 |
4 | 1.359 | ~600,000 |
5 | 2.132 | ~800,000 |
Netřeba dodávat, že vděčím Aleksi Vukotic a Nicki Watt a velmi doporučuji zkontrolovat jejich práci. Všechny testy v této části jsem vytáhl z první kapitoly jejich knihy, Neo4j v akci.
Začínáme s Neo4j
Viděli jste, že Neo4j je schopen velmi rychle spouštět obrovské množství vysoce souvisejících dat a není pochyb o tom, že je pro některé druhy problémů vhodnější než MySQL (nebo jakákoli relační databáze). Pokud chcete pochopit více o tom, jak Neo4j funguje, nejjednodušší je komunikovat s ním prostřednictvím webové konzoly.
Začněte stažením Neo4j. V tomto článku budete potřebovat edici Community, která je od tohoto psaní ve verzi 3.2.3.
- Na počítači Mac stáhněte soubor DMG a nainstalujte jej stejně jako jakoukoli jinou aplikaci.
- Ve Windows si buď stáhněte EXE a projděte si průvodce instalací, nebo si stáhněte soubor ZIP a dekomprimujte jej na pevný disk.
- V systému Linux si stáhněte soubor TAR a dekomprimujte jej na pevný disk.
- Případně použijte image Dockeru v jakémkoli operačním systému.
Po instalaci Neo4j jej spusťte a otevřete okno prohlížeče na následující adrese URL:
//127.0.0.1:7474/browser/
Přihlaste se pomocí výchozího uživatelského jména neo4j
a výchozí heslo pro neo4j
. Měla by se zobrazit obrazovka podobná obrázku 3.
Uzly a vztahy v Neo4j
Neo4j je navržen kolem konceptu uzlů a vztahů:
- A uzel představuje věc, jako je uživatel, film nebo kniha.
- Uzel obsahuje sadu páry klíč / hodnota, například jméno, titul nebo vydavatel.
- Uzel označení definuje, o jaký typ věci jde - opět uživatel, film nebo kniha.
- Vztahy definovat asociace mezi uzly a jsou konkrétních typů.
Jako příklad bychom mohli definovat uzly znaků, jako jsou Iron Man a Captain America; definovat uzel filmu s názvem „Avengers“; a poté definujte APPEARS_IN
vztah mezi Iron Manem a Avengers a Captain America a Avengers. To vše je znázorněno na obrázku 4.
Obrázek 4 ukazuje tři uzly (dva uzly znaků a jeden uzel filmu) a dva vztahy (oba typu APPEARS_IN
).
Modelování a dotazování uzlů a vztahů
Podobně jako relační databáze používá ke komunikaci s daty Structured Query Language (SQL), Neo4j používá Cypher Query Language k interakci s uzly a vztahy.
Pojďme pomocí Cypheru vytvořit jednoduchou reprezentaci rodiny. V horní části webového rozhraní vyhledejte znak dolaru. To označuje pole, které vám umožňuje provádět dotazy Cypher přímo proti Neo4j. Do tohoto pole zadejte následující dotaz Cypher (jako příklad používám svou rodinu, ale pokud chcete, můžete změnit podrobnosti a modelovat svou vlastní rodinu):
VYTVOŘIT (osoba: Osoba {jméno: "Steven", věk: 45}) RETURN osoba
Výsledek je znázorněn na obrázku 5.
Steven HainesNa obrázku 5 můžete vidět nový uzel se štítkem Osoba a jménem Steven. Pokud umístíte ukazatel myši na uzel ve webové konzole, uvidíte jeho vlastnosti v dolní části. V tomto případě jsou vlastnosti ID: 19, jméno: Steven a věk: 45. Nyní pojďme rozdělit dotaz Cypher:
- VYTVOŘIT: The
VYTVOŘIT
klíčové slovo se používá k vytvoření uzlů a vztahů. V tomto případě mu předáme jediný argument, kterým je aOsoba
uzavřeno v závorkách, takže to má za cíl vytvořit jeden uzel. - (osoba: Osoba {...}): Malá písmena “
osoba
„je název proměnné, jehož prostřednictvím můžeme přistupovat k vytvářené osobě, zatímco kapitál“Osoba
„je štítek. Upozorňujeme, že dvojtečka odděluje název proměnné od štítku. - {name: "Steven, věk: 45}: Toto jsou vlastnosti klíč / hodnota, které definujeme pro uzel, který vytváříme. Neo4j nevyžaduje, abyste před vytvořením uzlů definovali schéma a každý uzel může mít jedinečnou sadu prvků. (Většinu času definujete uzly se stejným štítkem, aby měly stejné vlastnosti, ale není to nutné.)
- NÁVRATNÁ osoba: Po vytvoření uzlu požádáme Neo4j, aby nám jej vrátil zpět. To je důvod, proč jsme viděli, že se uzel objeví v uživatelském rozhraní.
The VYTVOŘIT
příkaz (který nerozlišuje velká a malá písmena) se používá k vytváření uzlů a lze jej číst takto: vytvořit nový uzel se štítkem Osoba, který obsahuje vlastnosti jména a věku; přiřadit ji k proměnné osobě a vrátit ji zpět volajícímu.
Dotazování pomocí Cypher Query Language
Dále chceme zkusit nějaké dotazování s Cypherem. Nejprve budeme muset vytvořit několik dalších lidí, abychom mohli definovat vztahy mezi nimi.
CREATE (osoba: Osoba {jméno: "Michael", věk: 16}) RETURN osoba CREATE (osoba: Osoba {jméno: "Rebecca", věk: 7}) RETURN osoba CREATE (osoba: Osoba {jméno: "Linda"}) ) NÁVRATNÁ osoba
Jakmile vytvoříte své čtyři lidi, můžete buď kliknout na ikonu Osoba tlačítko pod Štítky uzlů (viditelné, pokud kliknete na ikonu databáze v levém horním rohu webové stránky) nebo provedete následující dotaz Cypher:
MATCH (person: Person) RETURN person
Cypher používá ZÁPAS
klíčové slovo pro vyhledání věcí v Neo4j. V tomto příkladu žádáme Cypher, aby odpovídal všem uzlům, které mají štítek Person, přiřaďte tyto uzly k osoba proměnná a vrátí hodnotu, která je přidružena k této proměnné. Ve výsledku byste měli vidět čtyři uzly, které jste vytvořili. Pokud umístíte ukazatel myši na každý uzel ve webové konzole, uvidíte vlastnosti každého člověka. (Možná si všimnete, že jsem vyloučil věk mé manželky z jejího uzlu, což dokazuje, že vlastnosti nemusí být shodné napříč uzly, dokonce ani se stejným štítkem. Také nejsem pošetilý, abych zveřejnil věk mé manželky.)
Můžeme to rozšířit ZÁPAS
příklad trochu dále přidáním podmínek k uzlům, které chceme vrátit. Například pokud bychom chtěli pouze uzel „Steven“, mohli bychom jej načíst pomocí shody na vlastnosti name:
ZÁPAS (osoba: Osoba {jméno: "Steven"}) NÁVRATNÁ osoba
Nebo kdybychom chtěli vrátit všechny děti, mohli bychom požádat všechny lidi ve věku do 18 let:
MATCH (person: Person) WHERE person.age <18 RETURN person
V tomto příkladu jsme přidali KDE
klauzule dotazu pro zúžení našich výsledků. KDE
funguje velmi podobně jako jeho ekvivalent SQL: MATCH (person: Person)
najde všechny uzly se štítkem Osoba a poté KDE
klauzule filtruje hodnoty z množiny výsledků.
Směr modelování ve vztazích
Máme čtyři uzly, takže vytvořme nějaké vztahy. Nejprve vytvořme IS_MARRIED_TO
vztah mezi Stevenem a Lindou:
ZÁPAS (steven: Osoba {jméno: "Steven"}), (linda: Osoba {jméno: "Linda"}) CREATE (steven) - [: IS_MARRIED_TO] -> (linda) vrátit steven, linda
V tomto příkladu spojíme dva Person uzly označené Steven a Linda a vytvoříme vztah typu IS_MARRIED_TO
od Stevena po Lindu. Formát pro vytvoření vztahu je následující:
(node1) - [relationshipVariable: RELATIONSHIP_TYPE -> (node2)