Programmēšana

Lielo datu analīze ar Neo4j un Java, 1. daļa

Relāciju datu bāzes ir dominējušas datu pārvaldībā gadu desmitiem ilgi, taču tās nesen ir zaudējušas vietu NoSQL alternatīvām. Lai gan NoSQL datu krājumi nav piemēroti katram lietošanas gadījumam, tie parasti ir labāki lielie dati, kas ir stenogrāfija sistēmām, kas apstrādā lielu datu apjomu. Lieliem datiem tiek izmantoti četri datu krātuves veidi:

  • Atslēgu / vērtību krājumi, piemēram, Memcached un Redis
  • Uz dokumentu orientētas datu bāzes, piemēram, MongoDB, CouchDB un DynamoDB
  • Uz kolonnām orientēti datu krājumi, piemēram, Kasandra un HBase
  • Grafika datu bāzes, piemēram, Neo4j un OrientDB

Šī apmācība iepazīstina ar Neo4j, kas ir diagrammu datu bāze, ko izmanto mijiedarbībai ļoti saistītie dati. Lai gan relāciju datu bāzes labi pārvalda attiecības starp dati, diagrammu datu bāzes ir labāk pārvaldāmas n-tā grādu attiecības. Kā piemēru ņemiet sociālo tīklu, kurā vēlaties analizēt modeļus, kuros iesaistīti draugi, draugu draugi utt. Grafiku datu bāze ļautu viegli atbildēt uz šādu jautājumu: "Ņemot vērā piecas nošķiršanas pakāpes, kādas ir piecas manā sociālajā tīklā populāras filmas, kuras es vēl neesmu redzējis?" Šādi jautājumi ir izplatīti ieteikumu programmatūrai, un diagrammu datu bāzes ir ideāli piemērotas to risināšanai. Turklāt diagrammu datubāzes labi attēlo hierarhiskos datus, piemēram, piekļuves kontroles, produktu katalogus, filmu datu bāzes vai pat tīkla topoloģijas un organizācijas diagrammas. Kad jums ir objekti ar vairākām attiecībām, jūs ātri atradīsit, ka diagrammu datu bāzes piedāvā elegantu, uz objektu orientētu paradigmu šo objektu pārvaldībai.

Gadījums grafu datu bāzēm

Tāpat kā norāda nosaukums, diagrammu datu bāzes labi attēlo datu grafikus. Tas ir īpaši noderīgi sociālajai programmatūrai, kur katru reizi, kad izveidojat savienojumu ar kādu, starp jums tiek noteiktas attiecības. Iespējams, pēdējos darba meklējumos jūs izvēlējāties dažus interesējošus uzņēmumus un pēc tam meklējāt savos sociālajos tīklos savienojumus ar tiem. Kaut arī jūs, iespējams, nepazīstat nevienu, kas strādā kādā no šiem uzņēmumiem, kāds, iespējams, zina jūsu sociālajā tīklā. Šādas problēmas ir viegli atrisināt vienā vai divās šķiršanās pakāpēs (jūsu draugs vai drauga draugs), bet kas notiek, kad sākat paplašināt meklēšanu visā tīklā?

Aleksa Vukotic un Nicki Watt savā grāmatā Neo4j In Action pēta atšķirības starp relāciju datu bāzēm un grafu datu bāzēm sociālo tīklu problēmu risināšanai. Es izmantošu viņu darbu dažos nākamajos piemēros, lai parādītu, kāpēc diagrammu datu bāzes kļūst arvien populārāka alternatīva relāciju datu bāzēm.

Sarežģītu attiecību modelēšana: Neo4j vs MySQL

No datorzinātnes viedokļa, domājot par attiecību modelēšanu starp lietotājiem sociālajā tīklā, mēs varētu uzzīmēt tādu grafiku kā 1. attēlā.

Stīvens Heinss

Lietotājam ir IS_FRIEND_OF attiecības ar citiem lietotājiem, un šiem lietotājiem ir IS_FRIEND_OF attiecības ar citiem lietotājiem utt. 2. attēlā parādīts, kā mēs to attēlojam relāciju datu bāzē.

Stīvens Heinss

The LIETOTĀJS tabulai ir savstarpējas attiecības ar USER_FRIEND tabula, kurā tiek modelētas "drauga" attiecības starp diviem lietotājiem. Tagad, kad esam modelējuši attiecības, kā mēs vaicāsim savus datus? Vukotičs un Vats mēra vaicājuma veiktspēju, lai saskaitītu atšķirīgu draugu skaitu, kas iziet piecu līmeņu dziļumā (draugu draugu draugi, draugu draugu draugi). Relāciju datu bāzē vaicājumi izskatīsies šādi:

 # 1. dziļums atlasiet skaitu (atšķirīgs uf. *) No user_friend uf, kur uf.user_1 =? # 2 dziļums atlasiet skaitu (atšķirīgs uf2. *) No user_friend uf1 iekšējā pievienojiet user_friend uf2 vietnē uf1.user_1 = uf2.user_2, kur uf1.user_1 =? # 3 dziļums atlasiet skaitu (atšķirīgs uf3. *) No t_user_friend uf1 iekšējā savienojuma t_user_friend uf2 vietnē uf1.user_1 = uf2.user_2 iekšējais savienojums t_user_friend uf3 vietnē uf2.user_1 = uf3.user_2, kur uf1.user_1 =? # Un tā tālāk... 

Interesanti par šiem vaicājumiem ir tas, ka katru reizi, kad izejam vēl vienu līmeni, mums jāpievienojas USER_FRIEND galds ar sevi. 1. tabulā parādīts, ko pētnieki Vukotičs un Vats atrada, ievietojot 1000 lietotājus ar aptuveni 50 attiecībām katrā (50 000 sakaru) un izpildot vaicājumus.

1. tabula. MySQL vaicājuma atbildes laiks dažādiem attiecību dziļumiem

Izpildes laiks (sekundes) Skaita rezultātu

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

MySQL lieliski strādā, apvienojot datus līdz trim līmeņiem, taču pēc tam veiktspēja strauji pasliktinās. Iemesls ir tāds, ka katru reizi USER_FRIEND tabula ir savienota ar sevi, MySQL ir jāaprēķina tabulas Dekarta produkts, kaut arī lielākā daļa datu tiks izmesta. Piemēram, veicot šo savienojumu piecas reizes, Dekarta produkts rada 50 000 ^ 5 rindas vai 102,4 * 10 ^ 21 rindas. Tas ir lieki, ja mūs interesē tikai 1000 no tiem!

Pēc tam Vukotičs un Vats mēģināja izpildīt tāda paša veida vaicājumus pret Neo4j. Šie pilnīgi atšķirīgie rezultāti ir parādīti 2. tabulā.

2. tabula. Neo4j reakcijas laiks dažādiem attiecību dziļumiem

Izpildes laiks (sekundes) Skaita rezultātu

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

Izņemšana no šiem izpildes salīdzinājumiem ir ka Neo4j ir labāks par MySQL. Drīzāk, šķērsojot šāda veida attiecības, Neo4j veiktspēja ir atkarīga no iegūto ierakstu skaita, savukārt MySQL veiktspēja ir atkarīga no ierakstu skaita USER_FRIEND tabula. Tādējādi, palielinoties attiecību skaitam, arī MySQL vaicājumu atbildes laiks palielināsies, savukārt Neo4j vaicājumu atbildes laiks paliks nemainīgs. Tas ir tāpēc, ka Neo4j atbildes laiks ir atkarīgs no konkrētā vaicājuma attiecību skaita, nevis no kopējā attiecību skaita.

Neo4j mērogošana lieliem datiem

Paplašinot šo domu projektu vēl vienu soli, Vukotičs un Vats izveidoja miljonu lietotāju ar 50 miljoniem savstarpēju attiecību. 3. tabulā parādīti šīs datu kopas rezultāti.

3. tabula. Neo4j reakcijas laiks 50 miljoniem attiecību

Izpildes laiks (sekundes) Skaita rezultātu

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

Lieki piebilst, ka esmu parādā Aleksai Vukotičai un Nikijai Vatai un ļoti iesaku pārbaudīt viņu darbu. Es izņēmu visus šīs sadaļas testus no viņu grāmatas pirmās nodaļas, Neo4j darbībā.

Darba sākšana ar Neo4j

Jūs esat redzējis, ka Neo4j spēj ļoti ātri izpildīt lielu daudzumu ļoti saistītu datu, un nav šaubu, ka tas ir piemērotāks noteikta veida problēmām nekā MySQL (vai jebkura relāciju datu bāze). Ja vēlaties uzzināt vairāk par Neo4j darbību, vienkāršākais veids ir mijiedarboties ar to, izmantojot tīmekļa konsoli.

Sāciet ar Neo4j lejupielādi. Šajā rakstā jūs vēlaties kopienas izdevumu, kas šajā rakstā ir 3.2.3. Versija.

  • Mac datorā lejupielādējiet DMG failu un instalējiet to tāpat kā jebkuru citu lietojumprogrammu.
  • Operētājsistēmā Windows vai nu lejupielādējiet EXE un staigājiet pa instalēšanas vedni, vai lejupielādējiet ZIP failu un atspiest to cietajā diskā.
  • Operētājsistēmā Linux lejupielādējiet TAR failu un saspiediet to cietajā diskā.
  • Varat arī izmantot Docker attēlu jebkurā operētājsistēmā.

Kad esat instalējis Neo4j, palaidiet to un atveriet pārlūkprogrammas logu uz šādu URL:

//127.0.0.1:7474/browser/

Piesakieties ar noklusējuma lietotājvārdu neo4j un noklusējuma parole neo4j. Jums vajadzētu redzēt ekrānu, kas līdzīgs 3. attēlam.

Stīvens Heinss

Mezgli un attiecības Neo4j

Neo4j ir veidots atbilstoši mezglu un attiecību jēdzienam:

  • A mezgls pārstāv lietu, piemēram, lietotāju, filmu vai grāmatu.
  • Mezglā ir atslēgu / vērtību pāri, piemēram, nosaukums, nosaukums vai izdevējs.
  • Mezgls etiķete nosaka, kāda veida lieta tā ir - atkal Lietotājs, Filma vai Grāmata.
  • Attiecības definē asociācijas starp mezgliem un ir noteikta veida.

Kā piemēru mēs varētu definēt Rakstzīmju mezglus, piemēram, Iron Man un Captain America; definē filmas mezglu ar nosaukumu "Atriebēji"; un pēc tam definējiet PARĀDĀS_IN attiecības starp Dzelzs Cilvēku un Atriebējiem un Kapteini Ameriku un Atriebējiem. Tas viss parādīts 4. attēlā.

Stīvens Heinss

4. attēlā parādīti trīs mezgli (divi rakstzīmju mezgli un viens filmas mezgls) un divas attiecības (abas veida PARĀDĀS_IN).

Mezglu un attiecību modelēšana un vaicāšana

Līdzīgi tam, kā relāciju datu bāze izmanto strukturētu vaicājumu valodu (SQL), lai mijiedarbotos ar datiem, Neo4j izmanto Cypher Query valodu, lai mijiedarbotos ar mezgliem un attiecībām.

Izmantosim Cypher, lai izveidotu vienkāršu ģimenes attēlojumu. Tīmekļa saskarnes augšdaļā meklējiet dolāra zīmi. Tas norāda lauku, kas ļauj izpildīt Cypher vaicājumus tieši pret Neo4j. Šajā laukā ievadiet šādu Cypher vaicājumu (es izmantoju savu ģimeni kā piemēru, taču varat mainīt informāciju, lai modelētu savu ģimeni, ja vēlaties):

IZVEIDOT (persona: Persona {vārds: "Stīvens", vecums: 45}) RETURN persona

Rezultāts parādīts 5. attēlā.

Stīvens Heinss

5. attēlā jūs varat redzēt jaunu mezglu ar etiķeti Persona un vārdu Stīvens. Ja virzīsit peles kursoru virs mezgla tīmekļa konsolē, apakšā redzēsit tā īpašības. Šajā gadījumā rekvizīti ir ID: 19, nosaukums: Stīvens un vecums: 45. Tagad sadalīsim vaicājumu Cypher:

  • IZVEIDOT: IZVEIDOT atslēgvārds tiek izmantots mezglu un attiecību veidošanai. Šajā gadījumā mēs tam nododam vienu argumentu, kas ir Persona iekavās, tāpēc tas ir paredzēts, lai izveidotu vienu mezglu.
  • (persona: persona {...}): Mazie burti "persona"ir mainīgais nosaukums, ar kura starpniecību mēs varam piekļūt radāmajai personai, bet kapitāls"Persona"ir etiķete. Ņemiet vērā, ka kols atdala mainīgā nosaukumu no etiķetes.
  • {name: "Stīvens, vecums: 45}: Šīs ir atslēgas / vērtības īpašības, kuras mēs definējam izveidotajam mezglam. Neo4j nav nepieciešams definēt shēmu pirms mezglu izveides, un katram mezglam var būt unikāls elementu kopums. (Visbiežāk mezglus ar vienu un to pašu etiķeti definē, lai tiem būtu vienādas īpašības, taču tas nav nepieciešams.)
  • RETURN persona: Pēc mezgla izveides mēs lūdzam Neo4j atgriezt to mums atpakaļ. Tāpēc mēs redzējām, ka mezgls parādās lietotāja saskarnē.

The IZVEIDOT komandu (kas nav reģistrjutīgs) izmanto mezglu izveidošanai, un to var nolasīt šādi: izveidojiet jaunu mezglu ar etiķeti Persona, kas satur vārda un vecuma īpašības; piešķirt to mainīgajam personai un atgriezt to zvanītājam.

Vaicājums ar Cypher Query Language

Tālāk mēs vēlamies izmēģināt vaicājumus ar Cypher. Pirmkārt, mums būs jāizveido vēl daži cilvēki, lai mēs varētu noteikt attiecības starp viņiem.

 CREATE (persona: Persona {vārds: "Maikls", vecums: 16}) RETURN persona CREATE (persona: Persona {vārds: "Rebecca", vecums: 7}) RETURN persona CREATE (persona: Persona {vārds: "Linda"} ) RETURN persona 

Kad esat izveidojis četrus cilvēkus, varat noklikšķināt uz Persona poga zem Mezglu etiķetes (redzams, noklikšķinot uz datu bāzes ikonas tīmekļa lapas augšējā kreisajā stūrī) vai izpildāt šādu Cypher vaicājumu:

MATCH (persona: persona) RETURN persona

Kipers izmanto SASKAŅA atslēgvārdu, lai atrastu lietas Neo4j. Šajā piemērā mēs lūdzam Cypher saskaņot visus mezglus, kuriem ir Personas etiķete, piešķirt šos mezglus persona mainīgo un atgriež vērtību, kas ir saistīta ar šo mainīgo. Rezultātā jums vajadzētu redzēt četrus izveidotos mezglus. Ja virzīsit kursoru virs katra tīmekļa konsoles mezgla, jūs redzēsiet katras personas īpašības. (Jūs varētu atzīmēt, ka es izslēdzu sievas vecumu no viņas mezgla, parādot, ka īpašībām nav jābūt konsekventām visos mezglos, pat ar tādu pašu etiķeti. Es arī neesmu pietiekami dumjš, lai publicētu savas sievas vecumu.)

Mēs to varam pagarināt SASKAŅA piemērs nedaudz tālāk, pievienojot nosacījumus mezgliem, kurus mēs vēlamies atgriezt. Piemēram, ja mēs vēlētos tikai "Steven" mezglu, mēs varētu to izgūt, atbilstot nosaukuma rekvizītam:

MATCH (persona: Persona {vārds: "Stīvens"}) RETURN persona

Vai arī, ja mēs vēlētos atgriezt visus bērnus, mēs varam pieprasīt visiem cilvēkiem, kuri ir jaunāki par 18 gadiem:

SASKAŅA (persona: Persona) KUR persona.vecums <18 RETURN persona

Šajā piemērā mēs pievienojām KUR vaicājuma klauzula, lai sašaurinātu mūsu rezultātus. KUR darbojas ļoti līdzīgi kā tā SQL ekvivalents: MATCH (persona: persona) atrod visus mezglus ar etiķeti Persona un pēc tam KUR klauzula filtrē vērtības no rezultātu kopas.

Virziena modelēšana attiecībās

Mums ir četri mezgli, tāpēc izveidosim dažas attiecības. Vispirms izveidosim IS_MARRIED_TO attiecības starp Stīvenu un Lindu:

MATCH (Stīvens: Persona {vārds: "Stīvens"}), (linda: Persona {vārds: "Linda"}) IZVEIDOT (Stīvens) - [: IS_MARRIED_TO] -> (linda) atgriešanās Stīvens, Linda

Šajā piemērā mēs sakrītam ar diviem Person mezgliem, kas apzīmēti ar Stīvenu un Lindu, un mēs izveidojam veida attiecības IS_MARRIED_TO no Stīvena līdz Lindai. Attiecību izveides formāts ir šāds:

(mezgls1) - [relatīvais mainīgais: RELATIONSHIP_TYPE -> (2. mezgls)