Programiranje

Analitika velikih podatkov z Neo4j in Javo, 1. del

Relacijske baze podatkov že desetletja prevladujejo nad upravljanjem podatkov, vendar so v zadnjem času izgubile prednost pred alternativami NoSQL. Čeprav shrambe podatkov NoSQL niso primerne za vsak primer uporabe, so na splošno boljše za veliki podatki, kar je okrajšava za sisteme, ki obdelujejo velike količine podatkov. Za velike podatke se uporabljajo štiri vrste shrambe podatkov:

  • Shrambe ključev / vrednosti, kot sta Memcached in Redis
  • Dokumentacijske baze podatkov, kot so MongoDB, CouchDB in DynamoDB
  • Stolpno usmerjene shrambe podatkov, kot sta Cassandra in HBase
  • Grafični zbirki podatkov, kot sta Neo4j in OrientDB

Ta vadnica predstavlja Neo4j, ki je podatkovna baza grafov, ki se uporablja za interakcijo z zelo povezani podatki. Medtem ko relacijske podatkovne baze dobro obvladujejo odnose med podatkov, grafične baze podatkov so boljše pri upravljanju n-ta razmerja med stopnjami. Za primer vzemite socialno omrežje, kjer želite analizirati vzorce, ki vključujejo prijatelje, prijatelje prijatelje itd. Z bazo podatkov grafov bi bilo enostavno odgovoriti na vprašanje, na primer: "Glede na pet stopinj ločenosti, kakšnih pet filmov je priljubljenih v moji socialni mreži, ki jih še nisem videl?" Takšna vprašanja so pogosta za programsko opremo za priporočila in zbirke podatkov grafov so kot nalašč za njihovo rešitev. Poleg tega grafične zbirke podatkov dobro predstavljajo hierarhične podatke, kot so nadzor dostopa, katalogi izdelkov, zbirke filmov ali celo omrežne topologije in organizacijske karte. Ko imate predmete z več odnosi, boste hitro ugotovili, da grafične zbirke podatkov ponujajo elegantno, objektno usmerjeno paradigmo za upravljanje teh predmetov.

Primer za grafične zbirke podatkov

Kot že ime pove, podatkovne baze grafov dobro predstavljajo grafe podatkov. To je še posebej koristno za družabno programsko opremo, kjer je vsakič, ko se z nekom povežete, med vami definiran odnos. Verjetno ste pri zadnjem iskanju zaposlitve izbrali nekaj podjetij, ki so vas zanimala, in nato v svojih družabnih omrežjih iskali povezave z njimi. Čeprav morda ne poznate nikogar, ki dela v enem od teh podjetij, verjetno nekdo v vašem socialnem omrežju ve. Reševanje takšne težave je enostavno pri eni ali dveh stopnjah ločitve (vaš prijatelj ali prijatelj prijatelja), kaj pa se zgodi, ko začnete iskati po svojem omrežju?

Aleksa Vukotic in Nicki Watt v svoji knjigi Neo4j v akciji raziskujeta razlike med relacijskimi bazami podatkov in grafičnimi bazami za reševanje problemov socialnih omrežij. Naslednjih nekaj primerov se bom oprl na njihovo delo, da vam pokažem, zakaj grafične baze postajajo vse bolj priljubljena alternativa relacijskim bazam podatkov.

Modeliranje kompleksnih odnosov: Neo4j vs MySQL

Z vidika računalništva lahko, ko razmišljamo o modeliranju odnosov med uporabniki v družbenem omrežju, narišemo graf, kot je prikazan na sliki 1.

Steven Haines

Uporabnik je IS_FRIEND_OF odnose z drugimi uporabniki, ki jih imajo ti uporabniki IS_FRIEND_OF odnosi z drugimi uporabniki itd. Slika 2 prikazuje, kako bi to predstavili v relacijski bazi podatkov.

Steven Haines

The UPORABNIK tabela ima odnos z enim do številk USER_FRIEND tabela, ki modelira odnos "prijatelj" med dvema uporabnikoma. Zdaj, ko smo modelirali odnose, kako bi poizvedovali po svojih podatkih? Vukotic in Watt sta izmerila uspešnost poizvedbe za štetje različnih prijateljev, ki so šli ven do globine petih stopenj (prijatelji prijateljev prijatelji prijateljev prijateljev). V relacijski bazi podatkov bi bile poizvedbe videti takole:

 # Globina 1 izberite število (ločeno uf. *) Od user_friend uf, kjer je uf.user_1 =? # Število izbranih globin 2 (ločeno uf2. *) Od user_friend uf1 notranje pridruži user_friend uf2 na uf1.user_1 = uf2.user_2 kjer je uf1.user_1 =? # Globina 3 izberite število (ločeno uf3. *) Od t_user_friend uf1 notranje pridružite t_user_friend uf2 na uf1.user_1 = uf2.user_2 notranje pridružite t_user_friend uf3 na uf2.user_1 = uf3.user_2 kje uf1.user_1 =? # In tako naprej... 

Zanimivo pri teh poizvedbah je, da se moramo vsakič, ko gremo še za eno stopnjo, pridružiti USER_FRIEND miza s seboj. Tabela 1 prikazuje, kaj sta ugotovila raziskovalca Vukotic in Watt, ko sta vstavila 1.000 uporabnikov s približno 50 odnosi vsak (50.000 odnosov) in izvedla poizvedbe.

Tabela 1. Odzivni čas poizvedbe MySQL za različne globine odnosov

DepthExecution time (sekunde) Rezultat štetja

20.028~900
30.213~999
410.273~999
592.613~999

MySQL se odlično spoji s podatki do treh stopenj, vendar se zmogljivost po tem hitro poslabša. Razlog je v tem, da vsakič USER_FRIEND Tabela je združena sama s seboj, MySQL mora izračunati kartezični zmnožek tabele, čeprav bo večina podatkov zavržena. Na primer, pri izvedbi petkratnega združevanja dobi kartezični izdelek 50.000 ^ 5 vrstic ali 102,4 * 10 ^ 21 vrstic. Škoda, ko nas zanima le 1.000!

Nato sta Vukotic in Watt poskušala opraviti isto vrsto poizvedb proti Neo4j. Ti povsem različni rezultati so prikazani v tabeli 2.

Tabela 2. Odzivni čas Neo4j za različne globine odnosov

DepthExecution time (sekunde) Rezultat štetja

20.04~900
30.06~999
40.07~999
50.07~999

Iz teh primerjav usmrtitev je mogoče ne da je Neo4j boljši od MySQL. Pri prečkanju teh vrst odnosov je zmogljivost Neo4j odvisna od števila pridobljenih zapisov, medtem ko je uspešnost MySQL odvisna od števila zapisov v USER_FRIEND tabela. Tako se bo s povečevanjem števila zvez povečeval tudi odzivni čas za poizvedbe MySQL, medtem ko bodo odzivni časi za poizvedbe Neo4j ostali enaki. To je zato, ker je odzivni čas Neo4j odvisen od števila razmerij za določeno poizvedbo in ne od skupnega števila razmerij.

Skaliranje Neo4j za velike podatke

Ko sta ta miselni projekt razširila še korak naprej, sta Vukotić in Watt nato ustvarila milijon uporabnikov s 50 milijoni odnosov med njima. Tabela 3 prikazuje rezultate za ta nabor podatkov.

Tabela 3. Odzivni čas Neo4j za 50 milijonov odnosov

DepthExecution time (sekunde) Rezultat štetja

20.01~2,500
30.168~110,000
41.359~600,000
52.132~800,000

Ni treba posebej poudarjati, da sem dolžan Aleksa Vukotić in Nicki Watt in toplo priporočam, da preverite njihovo delo. Vse teste v tem poglavju sem izluščil iz prvega poglavja njihove knjige, Neo4j v akciji.

Uvod v Neo4j

Videli ste, da je Neo4j sposoben zelo hitro izvesti ogromne količine zelo povezanih podatkov in nedvomno je za nekatere vrste težav bolj primeren kot MySQL (ali katera koli relacijska baza podatkov). Če želite več razumeti, kako deluje Neo4j, je najlažji način interakcije z njim prek spletne konzole.

Začnite s prenosom Neo4j. Za ta članek boste želeli izdajo za skupnost, ki je od tega pisanja na različici 3.2.3.

  • V računalnik Mac prenesite datoteko DMG in jo namestite tako kot katero koli drugo aplikacijo.
  • V sistemu Windows prenesite EXE in se sprehodite po čarovniku za namestitev ali prenesite datoteko ZIP in jo stisnite na trdi disk.
  • V Linux prenesite datoteko TAR in jo stisnite na trdi disk.
  • Lahko pa uporabite Dockerjevo sliko v katerem koli operacijskem sistemu.

Ko namestite Neo4j, ga zaženite in odprite okno brskalnika na naslednji URL:

//127.0.0.1:7474/browser/

Prijavite se s privzetim uporabniškim imenom neo4j in privzeto geslo za neo4j. Moral bi videti zaslon, podoben sliki 3.

Steven Haines

Vozlišča in odnosi v Neo4j

Neo4j je zasnovan na konceptu vozlišč in odnosov:

  • A vozlišče predstavlja stvar, na primer uporabnika, film ali knjigo.
  • Vozlišče vsebuje nabor pari ključ / vrednost, kot so ime, naslov ali založnik.
  • Vozlišče nalepko določa, za katero vrsto stvari gre - spet uporabnik, film ali knjiga.
  • Odnosi definirajo povezave med vozlišči in so določenih tipov.

Kot primer lahko določimo vozlišča znakov, kot sta Iron Man in Captain America; definirajte filmsko vozlišče z imenom "Avengers"; in nato določite NAZAJ_IN razmerje med Iron Manom ​​in Avengersi in Captain America in Avengers. Vse to je prikazano na sliki 4.

Steven Haines

Slika 4 prikazuje tri vozlišča (dve znakovni vozlišči in eno filmsko vozlišče) in dve relaciji (obe vrsti NAZAJ_IN).

Modeliranje in poizvedovanje vozlišč in odnosov

Podobno kot relacijska baza podatkov uporablja strukturirani poizvedbeni jezik (SQL) za interakcijo s podatki, Neo4j uporablja poizvedbeni jezik Cypher za interakcijo z vozlišči in odnosi.

Uporabimo Cypher, da ustvarimo preprosto predstavitev družine. Na vrhu spletnega vmesnika poiščite znak za dolar. To označuje polje, ki omogoča izvajanje poizvedb Cypher neposredno proti Neo4j. V to polje vnesite naslednjo poizvedbo Cypher (za primer uporabljam svojo družino, vendar lahko spremenite podrobnosti, če želite, da oblikujete svojo družino):

USTVARI (oseba: Oseba {ime: "Steven", starost: 45}) VRNI osebo

Rezultat je prikazan na sliki 5.

Steven Haines

Na sliki 5 lahko vidite novo vozlišče z oznako Oseba in imenom Steven. Če miškin kazalec premaknete nad vozlišče v spletni konzoli, boste na dnu videli njegove lastnosti. V tem primeru so lastnosti ID: 19, ime: Steven in starost: 45. Zdaj razčlenimo poizvedbo Cypher:

  • USTVARI: The USTVARI ključna beseda se uporablja za ustvarjanje vozlišč in odnosov. V tem primeru mu posredujemo en argument, ki je Oseba zaprta v oklepajih, zato naj bi ustvarila eno vozlišče.
  • (oseba: oseba {...}): Mala črka "oseba"je ime spremenljivke, prek katerega lahko dostopamo do osebe, ki jo ustvarjamo, medtem ko je kapital"Oseba"je oznaka. Upoštevajte, da dvopičje ločuje ime spremenljivke od oznake.
  • {ime: "Steven, starost: 45}: To so lastnosti ključ / vrednost, ki jih definiramo za vozlišče, ki ga ustvarjamo. Neo4j ne zahteva, da pred ustvarjanjem vozlišč definirate shemo, vsako vozlišče pa ima lahko edinstven nabor elementov. (Največkrat definirate vozlišča z isto oznako, da imajo enake lastnosti, vendar to ni potrebno.)
  • VRNITEV osebe: Ko je vozlišče ustvarjeno, prosimo Neo4j, da nam ga vrne nazaj. Zato smo videli, da se vozlišče prikaže v uporabniškem vmesniku.

The USTVARI ukaz (ki ne razlikuje med velikimi in malimi črkami) se uporablja za ustvarjanje vozlišč in ga lahko beremo na naslednji način: ustvarite novo vozlišče z oznako Person, ki vsebuje lastnosti imena in starosti; dodelite spremenljivki osebe in jo vrnite klicatelju.

Poizvedovanje s poizvedbenim jezikom Cypher

Nato želimo poskusiti nekaj poizvedb z Cypherjem. Najprej bomo morali ustvariti še nekaj ljudi, da bomo lahko opredelili odnose med njimi.

 USTVARI (oseba: Oseba {ime: "Michael", starost: 16}) VRNI osebo USTVARI (oseba: Oseba {ime: "Rebecca", starost: 7}) VRNI OSOBO USTVARI (oseba: oseba {ime: "Linda"} ) VRNITEV osebe 

Ko ustvarite svoje štiri osebe, lahko kliknete na Oseba pod gumbom Oznake vozlišč (vidno, če kliknete ikono baze podatkov v zgornjem levem kotu spletne strani) ali izvedite naslednjo poizvedbo Cypher:

TEKMA (oseba: Oseba) VRNITEV oseba

Cypher uporablja UTEK ključna beseda za iskanje stvari v Neo4j. V tem primeru prosimo Cypher, da se ujema z vsemi vozlišči, ki imajo oznako Person, ta vozlišča dodeli oseba in vrne vrednost, ki je povezana s to spremenljivko. Kot rezultat bi morali videti štiri vozlišča, ki ste jih ustvarili. Če se v spletni konzoli pomaknete nad vsako vozlišče, boste videli lastnosti vsake osebe. (Morda boste opazili, da sem iz vozlišča izključil starost svoje žene, kar ponazarja, da lastnosti niso nujno enakovredne na vseh vozliščih, tudi iste oznake. Prav tako nisem dovolj neumen, da bi objavil starost svoje žene.)

To lahko podaljšamo UTEK primer malo naprej z dodajanjem pogojev vozliščem, ki jih želimo vrniti. Če bi na primer želeli samo vozlišče "Steven", bi ga lahko pridobili tako, da bi se ujemali z lastnostjo imena:

TEKMA (oseba: Oseba {ime: "Steven"}) VRNITEV osebe

Če pa bi radi vrnili vse otroke, bi lahko zahtevali vse ljudi, mlajše od 18 let:

TEKMA (oseba: Oseba) KJE oseba.starost <18 VRNITEV oseba

V tem primeru smo dodali KJE klavzulo o poizvedbi, da zožimo naše rezultate. KJE deluje zelo podobno kot njegov SQL ekvivalent: TEKMA (oseba: oseba) poišče vsa vozlišča z oznako Person, nato pa KJE klavzula filtrira vrednosti iz nabora rezultatov.

Modeliranje smeri v odnosih

Imamo štiri vozlišča, zato ustvarimo nekaj odnosov. Najprej ustvarimo IS_MARRIED_TO razmerje med Stevenom in Lindo:

UTEK (steven: Oseba {ime: "Steven"}), (linda: Oseba {ime: "Linda"}) USTVARI (steven) - [: IS_MARRIED_TO] -> (linda) vrni steven, linda

V tem primeru povežemo dve vozlišči Person z imenom Steven in Linda in ustvarimo razmerje tipa IS_MARRIED_TO od Stevena do Linde. Oblika za ustvarjanje odnosa je naslednja:

(vozlišče1) - [razmerjeVariable: RELATIONSHIP_TYPE -> (vozlišče2)
$config[zx-auto] not found$config[zx-overlay] not found