Programavimas

Didelių duomenų analizė naudojant „Neo4j“ ir „Java“, 1 dalis

Reliacinės duomenų bazės dominuoja duomenų valdyme dešimtmečius, tačiau pastaruoju metu jos prarado vietą „NoSQL“ alternatyvoms. Nors „NoSQL“ duomenų saugyklos nėra tinkamos kiekvienu naudojimo atveju, jos paprastai yra geresnės dideli duomenys, kuris yra trumpų kalbų sistemoms, kurios apdoroja didžiulius duomenų kiekius. Didiesiems duomenims naudojami keturi duomenų saugyklos tipai:

  • Rakto / vertės saugyklos, tokios kaip „Memcached“ ir „Redis“
  • Į dokumentą orientuotos duomenų bazės, tokios kaip „MongoDB“, „CouchDB“ ir „DynamoDB“
  • Į stulpelius orientuotos duomenų saugyklos, tokios kaip „Cassandra“ ir „HBase“
  • Grafikuokite tokias duomenų bazes kaip „Neo4j“ ir „OrientDB“

Šioje pamokoje pristatoma „Neo4j“, kuri yra grafikų duomenų bazė, naudojama bendraujant labai susiję duomenys. Nors santykių duomenų bazės gerai valdo santykius tarp duomenys, grafikų duomenų bazės geriau tvarkosi n-tasis laipsnio santykiai. Kaip pavyzdį paimkite socialinį tinklą, kuriame norite analizuoti modelius, susijusius su draugais, draugų draugais ir pan. Grafikų duomenų bazėje būtų lengva atsakyti į tokį klausimą: „Kokie penki mano socialiniame tinkle populiarūs filmai, kurių dar nemačiau, atsižvelgiant į penkis atskyrimo laipsnius?“ Tokie klausimai yra bendri rekomendacinei programinei įrangai, o grafikų duomenų bazės puikiai tinka jiems išspręsti. Be to, grafikų duomenų bazės gerai atspindi hierarchinius duomenis, tokius kaip prieigos valdikliai, produktų katalogai, filmų duomenų bazės ar net tinklo topologijos ir organizacinės diagramos. Kai turite objektų su keliais ryšiais, greitai sužinosite, kad diagramų duomenų bazės siūlo elegantišką, į objektus orientuotą paradigmą, kaip valdyti tuos objektus.

Grafikų duomenų bazių atvejis

Kaip rodo pavadinimas, grafikų duomenų bazės gerai atspindi duomenų grafikus. Tai ypač naudinga socialinei programinei įrangai, kur kiekvieną kartą, kai susisiekiate su kuo nors, tarp jūsų yra apibrėžti santykiai. Tikriausiai per paskutinę darbo paiešką išsirinkote keletą jus dominančių įmonių ir paskui ieškojote ryšių su jomis savo socialiniuose tinkluose. Nors galbūt nepažįstate nė vieno, dirbančio vienoje iš šių bendrovių, kažkas jūsų socialiniame tinkle greičiausiai žino. Tokią problemą lengva išspręsti vienu ar dviem išsiskyrimo laipsniais (jūsų draugas ar draugo draugas), bet kas nutiks, kai pradėsite išplėsti paiešką visame savo tinkle?

Aleksa Vukotic ir Nicki Watt savo knygoje „Neo4j In Action“ nagrinėja santykių duomenų bazių ir grafikų duomenų bazių skirtumus socialinių tinklų problemoms spręsti. Kituose pavyzdžiuose remsiuosi jų darbu, norėdamas parodyti, kodėl diagramų duomenų bazės tampa vis populiaresne alternatyva reliacinėms duomenų bazėms.

Sudėtingų santykių modeliavimas: „Neo4j“ ir „MySQL“

Žvelgiant iš informatikos perspektyvos, galvodami apie socialinių tinklų vartotojų santykių modeliavimą, galime nupiešti grafiką, panašų į 1 paveiksle pateiktą.

Stevenas Hainesas

Vartotojas turi IS_FRIEND_OF santykius su kitais vartotojais ir tie vartotojai turi IS_FRIEND_OF santykiai su kitais vartotojais ir pan. 2 paveiksle parodyta, kaip tai pavaizduotume reliacinėje duomenų bazėje.

Stevenas Hainesas

VARTOTOJAS lentelė turi santykį „vienas su daugeliu“ USER_FRIEND lentelę, kurioje modeliuojami dviejų vartotojų „draugo“ santykiai. Dabar, kai mes modeliavome santykius, kaip galėtume pateikti užklausą savo duomenims? Vukotikas ir Wattas įvertino užklausos efektyvumą, skaičiuodami skirtingų draugų, išeinančių į penkių lygių, skaičių (draugų draugų draugai ir draugų draugų draugai). Reliacinėje duomenų bazėje užklausos atrodys taip:

 # 1 gylis pasirinkite skaičių (skiriasi uf. *) Nuo user_friend uf, kur uf.user_1 =? # 2 gylis pasirinkite skaičių (atskiras uf2. *) Iš vartotojo_draugo uf1 vidinio prisijungimo prie vartotojo_draugo uf2 uf1.user_1 = uf2.user_2, kur uf1.user_1 =? # 3 gylis pasirinkite skaičių (skiriasi uf3. *) Iš t_user_friend uf1 vidinio prisijungimo t_user_friend uf2 ant uf1.user_1 = uf2.user_2 vidinio prisijungimo t_user_friend uf3 ant uf2.user_1 = uf3.user_2, kur uf1.user_1 =? # Ir taip toliau... 

Įdomu šiose užklausose yra tai, kad kiekvieną kartą, kai išeiname dar vienu lygiu, turime prisijungti prie USER_FRIEND stalas su savimi. 1 lentelėje parodyta, ką rado tyrėjai Vukotic ir Watt, įterpdami 1000 vartotojų, kurių kiekvienas turėjo maždaug 50 ryšių (50 000 ryšių) ir vykdė užklausas.

1 lentelė. „MySQL“ užklausos atsakymo laikas įvairiems gylių santykiams

Gylis Vykdymo laikas (sekundės) Suskaičiuokite rezultatą

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

„MySQL“ puikiai sujungia duomenis iki trijų lygių, tačiau po to našumas sparčiai blogėja. Priežastis ta, kad kiekvieną kartą USER_FRIEND lentelė yra sujungta su savimi, „MySQL“ turi apskaičiuoti lentelės derinį, nors didžioji dalis duomenų bus išmesta. Pvz., Atliekant tą sujungimą penkis kartus, kartezinis produktas sudaro 50 000 ^ 5 eilučių arba 102,4 * 10 ^ 21 eilučių. Tai švaistymas, kai mus domina tik 1000 jų!

Tada Vukotikas ir Wattas bandė vykdyti tokio paties tipo užklausas prieš „Neo4j“. Šie visiškai skirtingi rezultatai parodyti 2 lentelėje.

2 lentelė. Neo4j atsako trukmė įvairiems santykių gyliams

Gylis Vykdymo laikas (sekundės) Suskaičiuokite rezultatą

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

Šių egzekucijų palyginimų paėmimas yra ne kad „Neo4j“ yra geresnis už „MySQL“. Atvirkščiai, važiuojant tokio tipo santykiais, „Neo4j“ našumas priklauso nuo gautų įrašų skaičiaus, o „MySQL“ našumas priklauso nuo įrašų skaičiaus USER_FRIEND stalo. Taigi, didėjant ryšių skaičiui, atsakymo laikas į „MySQL“ užklausas taip pat ilgės, o „Neo4j“ užklausų atsakymo laikas išliks toks pats. Taip yra todėl, kad „Neo4j“ atsakymo laikas priklauso nuo konkrečios užklausos ryšių skaičiaus, o ne nuo bendro ryšių skaičiaus.

„Neo4j“ mastelio keitimas dideliems duomenims

Išplėtę šį minties projektą dar vienu žingsniu, Vukotikas ir Wattas sukūrė milijoną vartotojų, tarp kurių buvo 50 milijonų santykių. 3 lentelėje pateikiami to duomenų rinkinio rezultatai.

3 lentelė. Neo4j atsako laikas, susijęs su 50 milijonų santykių

Gylis Vykdymo laikas (sekundės) Suskaičiuokite rezultatą

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

Nereikia nė sakyti, kad esu skolinga Aleksa Vukotic ir Nicki Watt ir labai rekomenduoju patikrinti jų darbus. Aš ištraukiau visus šio skyriaus testus iš pirmojo jų knygos skyriaus, „Neo4j“ veiksme.

Darbo su „Neo4j“ pradžia

Jūs matėte, kad „Neo4j“ gali labai greitai įvykdyti didžiulį kiekį labai susijusių duomenų ir, be abejonės, jis geriau tinka nei „MySQL“ (ar bet kokia reliacinė duomenų bazė) tam tikrų rūšių problemoms spręsti. Jei norite daugiau sužinoti apie „Neo4j“ veikimą, paprasčiausias būdas yra bendrauti su juo per interneto konsolę.

Pradėkite atsisiųsdami „Neo4j“. Šiam straipsniui reikalingas bendruomenės leidimas, kuris šio rašymo metu yra 3.2.3 versijoje.

  • „Mac“ sistemoje atsisiųskite DMG failą ir įdiekite jį kaip ir bet kurią kitą programą.
  • „Windows“ sistemoje atsisiųskite EXE ir eikite per diegimo vedlį, arba atsisiųskite ZIP failą ir išspauskite jį standžiajame diske.
  • „Linux“ sistemoje atsisiųskite TAR failą ir išspauskite jį standžiajame diske.
  • Arba naudokite „Docker“ vaizdą bet kurioje operacinėje sistemoje.

Įdiegę „Neo4j“, paleiskite jį ir atidarykite naršyklės langą šiuo URL:

//127.0.0.1:7474/browser/

Prisijunkite naudodami numatytąjį vartotojo vardą neo4j ir numatytąjį slaptažodį neo4j. Turėtumėte pamatyti ekraną, panašų į 3 paveikslą.

Stevenas Hainesas

„Neo4j“ mazgai ir santykiai

„Neo4j“ sukurtas pagal mazgų ir santykių sampratą:

  • A mazgas reiškia daiktą, pvz., vartotoją, filmą ar knygą.
  • Mazge yra rinkinys raktų / reikšmių poros, pvz., vardas, pavadinimas ar leidėjas.
  • Mazgo etiketė apibrėžia, koks tai daiktas - vėlgi Vartotojas, Filmas ar Knyga.
  • Santykiai apibrėžia asociacijas tarp mazgų ir yra specifinių tipų.

Kaip pavyzdį galime apibūdinti simbolių mazgus, tokius kaip „Geležinis žmogus“ ir „Kapitonas Amerika“; apibrėžti filmo mazgą pavadinimu „Keršytojai“; ir tada apibrėžkite PASIRENKA_IN santykiai tarp Geležinio žmogaus ir Keršytojų bei Kapitono Amerikos ir Keršytojų. Visa tai parodyta 4 paveiksle.

Stevenas Hainesas

4 paveiksle pavaizduoti trys mazgai (du simbolių mazgai ir vienas filmo mazgas) ir du ryšiai (abu tipo PASIRENKA_IN).

Mazgų ir ryšių modeliavimas ir užklausos

Panašiai kaip reliacinė duomenų bazė sąveikai su duomenimis naudoja struktūrinę užklausų kalbą (SQL), „Neo4j“ naudoja „Cypher Query Language“ sąveikai su mazgais ir ryšiais.

Naudokime „Cypher“, kad sukurtume paprastą šeimos vaizdą. Žiniatinklio sąsajos viršuje ieškokite dolerio ženklo. Tai rodo lauką, kuriame galite vykdyti „Cypher“ užklausas tiesiai prieš „Neo4j“. Įveskite šią „Cypher“ užklausą į tą lauką (aš naudoju savo šeimą kaip pavyzdį, bet nedvejodami pakeiskite išsamią informaciją, jei norite, modeliuoti savo šeimą):

SUKURTI (asmuo: Asmuo {vardas: "Stevenas", amžius: 45}) GRĄŽINTI asmenį

Rezultatas parodytas 5 paveiksle.

Stevenas Hainesas

5 paveiksle galite pamatyti naują mazgą su etikete Asmuo ir vardu Stevenas. Jei užveskite pelės žymeklį virš tinklo konsolės mazgo, pamatysite jo savybes apačioje. Šiuo atveju savybės yra ID: 19, vardas: Stevenas ir amžius: 45. Dabar suskirstykime „Cypher“ užklausą:

  • SUKURTI: SUKURTI raktinis žodis naudojamas mazgams ir santykiams kurti. Šiuo atveju mes pateikiame jam vieną argumentą, kuris yra Asmuo uždarytas skliausteliuose, todėl jis skirtas sukurti vieną mazgą.
  • (asmuo: asmuo {...}): Mažosios raidės "asmuo"yra kintamasis vardas, per kurį galime pasiekti kuriamą asmenį, o didžiosios"Asmuo"yra etiketė. Atkreipkite dėmesį, kad dvitaškis atskiria kintamojo pavadinimą nuo etiketės.
  • {vardas: "Stevenas, amžius: 45}: Tai yra pagrindinės / vertės ypatybės, kurias mes apibrėžiame savo kuriamam mazgui. „Neo4j“ nereikalauja, kad prieš kurdami mazgus apibrėžtumėte schemą, o kiekvienas mazgas gali turėti unikalų elementų rinkinį. (Dažniausiai mazgai su ta pačia etikete apibrėžiami tomis pačiomis savybėmis, tačiau to nereikia.)
  • GRĄŽINTI asmenį: Sukūrus mazgą, mes prašome „Neo4j“ grąžinti jį mums atgal. Štai kodėl mes matėme, kad mazgas atsirado vartotojo sąsajoje.

SUKURTI komanda (kuri neskiria didžiųjų ir mažųjų raidžių) naudojama mazgams kurti ir ją galima perskaityti taip: sukurkite naują mazgą su etikete „Person“, kuriame yra vardo ir amžiaus ypatybės; priskirkite kintamajam asmeniui ir grąžinkite jį skambinančiajam.

Užklausa naudojant „Cypher Query Language“

Toliau norime išbandyti užklausas su „Cypher“. Pirmiausia turime sukurti dar keletą žmonių, kad galėtume apibrėžti jų tarpusavio santykius.

 CREATE (asmuo: asmuo {vardas: "Michael", amžius: 16}) RETURN asmuo CREATE (asmuo: asmuo {vardas: "Rebecca", amžius: 7}) RETURN asmuo CREATE (asmuo: asmuo {vardas: "Linda"} ) GRĮŽTI asmenį 

Sukūrę keturis žmones, galite spustelėti Asmuo mygtukas po Mazgo etiketės (matoma spustelėjus duomenų bazės piktogramą viršutiniame kairiajame tinklalapio kampe) arba vykdote šią „Cypher“ užklausą:

MATCH (asmuo: asmuo) RETURN asmuo

Kipras naudoja Rungtynės raktinį žodį, kad rastumėte dalykų „Neo4j“. Šiame pavyzdyje mes prašome Cypher suderinti visus mazgus, turinčius asmens etiketę, priskirti tuos mazgus prie asmuo kintamąjį ir grąžinkite su tuo kintamuoju susijusią vertę. Todėl turėtumėte pamatyti keturis sukurtus mazgus. Jei užvesite pelės žymeklį virš kiekvieno tinklo konsolės mazgo, pamatysite kiekvieno asmens ypatybes. (Galbūt pastebėsite, kad iš savo mazgo neįtraukiau savo žmonos amžiaus, iliustruodamas, kad savybės nebūtinai turi būti vienodos įvairiuose mazguose, net ir tos pačios etiketės. Aš taip pat nesu kvailas, kad galėčiau paskelbti savo žmonos amžių.)

Mes galime tai pratęsti Rungtynės pavyzdys šiek tiek toliau, pridedant sąlygas mazgams, kuriuos norime grąžinti. Pvz., Jei norėtume tik „Steven“ mazgo, galėtume jį gauti suderinę vardo ypatybę:

RENGIMAS (asmuo: asmuo {vardas: "Stevenas}}) GRĄŽINTI asmenį

Arba, jei norėtume grąžinti visus vaikus, galėtume paprašyti visų žmonių iki 18 metų amžiaus:

MATCH (asmuo: asmuo) WHERE asmuo. Amžius <18 RETURN asmuo

Šiame pavyzdyje mes pridėjome KUR užklausos sąlyga, kad susiaurintume mūsų rezultatus. KUR veikia labai panašiai kaip jo SQL atitikmuo: MATCH (asmuo: asmuo) suranda visus mazgus su etikete Asmuo ir tada KUR sakinys filtruoja reikšmes iš rezultatų rinkinio.

Santykių krypties modeliavimas

Mes turime keturis mazgus, todėl sukurkime keletą santykių. Pirmiausia sukurkime IS_MARRIED_TO Steveno ir Lindos santykiai:

MATCH (steven: asmuo {vardas: "Steven"}), (linda: asmuo {vardas: "Linda"}) CREATE (stevenas) - [: IS_MARRIED_TO] -> (linda) grįžta stevenas, linda

Šiame pavyzdyje mes suderiname du Asmens mazgus, pažymėtus Stevenu ir Linda, ir sukuriame tipo santykį IS_MARRIED_TO nuo Steveno iki Lindos. Santykio kūrimo formatas yra toks:

(mazgas1) - [santykis Kintamasis: RELATIONSHIP_TYPE -> (mazgas2)