NoSQL-i andmemudeli kujundamise omadused

Sissejuhatus

NoSQL-i andmemudeli kujundamise omadused "Sa pead jooksma nii kiiresti kui võimalik, et paigal püsida,
ja kuhugi jõudmiseks tuleb joosta vähemalt kaks korda kiiremini!”
c) Alice Imedemaal

Mõni aeg tagasi paluti mul loengut pidada analüütikud meie ettevõtet andmemudelite kujundamise teemal, sest pikalt (vahel mitu aastat) projektide kallal istudes kaotame silmist IT-tehnoloogiate maailmas meie ümber toimuva. Meie ettevõttes (nii juhtub) paljud projektid ei kasuta (vähemalt praegu) NoSQL andmebaase, mistõttu pöörasin oma loengus neile HBase näitel eraldi tähelepanu ja püüdsin orienteeruda materjali esitluse nendele. kes pole neid kunagi kasutanud, on töötanud. Eelkõige illustreerisin mõningaid andmemudeli disaini funktsioone, kasutades näidet, mida ma mitu aastat tagasi lugesin Amandeep Khurana artiklis "Sissejuhatus HB ase skeemi kujundamisse".. Näiteid analüüsides võrdlesin mitut võimalust sama probleemi lahendamiseks, et põhiideed paremini auditooriumini viia.

Hiljuti "mitte tegemisest" esitasin endale küsimuse (eriti soodustab seda maikuu pikk nädalavahetus karantiinis), kui palju vastavad teoreetilised arvutused praktikale? Tegelikult sündis selle artikli idee nii. Mitu päeva NoSQL-iga töötanud arendaja ei pruugi sellest midagi uut õppida (ja seetõttu võib kohe poole artikli vahele jätta). Aga selleks analüütikudNeile, kes pole veel NoSQL-iga tihedat koostööd teinud, on minu arvates kasulik HBase'i andmemudelite kujundamise funktsioonide põhiteadmiste saamiseks.

Näidisanalüüs

Minu arvates tuleb enne NoSQL-i andmebaaside kasutamist hoolikalt läbi mõelda ning plusse ja miinuseid kaaluda. Sageli saab probleemi suure tõenäosusega lahendada traditsiooniliste relatsiooniliste DBMS-ide abil. Seetõttu on parem mitte kasutada NoSQL-i ilma oluliste põhjusteta. Kui otsustasite siiski kasutada NoSQL-i andmebaasi, peaksite arvestama, et siinsed disainikäsitlused on mõnevõrra erinevad. Eriti mõned neist võivad olla ebatavalised neile, kes on varem tegelenud ainult relatsiooniliste DBMS-idega (minu tähelepanekute kohaselt). Seega alustame “relatsioonimaailmas” tavaliselt probleemvaldkonna modelleerimisest ja alles seejärel denormaliseerime mudeli vajadusel. NoSQL-is me peaks viivitamatult arvestama andmetega töötamise eeldatavate stsenaariumidega ja algselt denormaliseerige andmed. Lisaks on mitmeid muid erinevusi, mida arutatakse allpool.

Vaatleme järgmist "sünteetilist" probleemi, millega jätkame tööd:

Mõne abstraktse suhtlusvõrgustiku kasutajate sõprade loendi jaoks on vaja kujundada salvestusstruktuur. Lihtsustamiseks eeldame, et kõik meie ühendused on suunatud (nagu Instagramis, mitte Linkedinis). Struktuur peaks võimaldama teil tõhusalt:

  • Vastake küsimusele, kas kasutaja A loeb kasutajat B (lugemismuster)
  • Ühenduste lisamise/eemaldamise lubamine kasutaja A tellimisel/tellimusest loobumisel kasutajalt B (andmete muutmise mall)

Loomulikult on probleemi lahendamiseks palju võimalusi. Tavalises relatsiooniandmebaasis teeme suure tõenäosusega lihtsalt seoste tabeli (võib-olla tüpiseerida, kui näiteks peame salvestama kasutajarühma: perekond, töö jne, kuhu see "sõber" kuulub) ja optimeerida. juurdepääsu kiirus lisaks indeksid/partitsioonid. Tõenäoliselt näeb finaallaud välja umbes selline:

USER_ID
sõbra_id

Vasya
Petja

Vasya
Оля

edaspidi märgin selguse ja parema arusaamise huvides ID-de asemel nimed

HBase'i puhul teame, et:

  • võimalik on tõhus otsing, mis ei too kaasa täielikku tabeli skannimist eranditult võtmega
    • tegelikult on seetõttu paljudele tuttavate SQL-päringute kirjutamine sellistesse andmebaasidesse halb mõte; tehniliselt saab muidugi samast Impalast HBase'i saata SQL päringu Joinsi ja muu loogikaga, aga kui tõhus see siis on...

Seetõttu oleme sunnitud võtmena kasutama kasutajatunnust. Ja minu esimene mõte teemal "kus ja kuidas sõprade ID-sid säilitada?" võib-olla on mõte neid veergudesse salvestada. See kõige ilmsem ja "naiivsem" valik näeb välja umbes selline (nimetagem seda 1. valik (vaikimisi)edasiseks viitamiseks):

RowKey
Esinejad

Vasya
1: Petya
2: Olya
3: Daša

Petja
1: Maša
2: Vasja

Siin vastab iga rida ühele võrgukasutajale. Veergudel on nimed: 1, 2, ... - vastavalt sõprade arvule ja veergudesse salvestatakse sõprade ID-d. Oluline on märkida, et igal real on erinev arv veerge. Ülaltoodud näites on ühel real kolm veergu (1, 2 ja 3) ja teisel ainult kaks (1 ja 2) - siin kasutasime ise kahte HBase atribuuti, mida relatsiooniandmebaasidel pole:

  • võimalus dünaamiliselt muuta veergude koostist (lisage sõber -> lisage veerg, eemaldage sõber -> kustutage veerg)
  • erinevatel ridadel võib olla erinev veergude koostis

Kontrollime oma struktuuri vastavust ülesande nõuetele:

  • Andmete lugemine: selleks, et mõista, kas Vasya on Olya tellitud, peame lahutama terve rida klahviga RowKey = "Vasya" ja sorteerige veergude väärtusi, kuni me neis "kohtume" Olyaga. Või korrake kõigi veergude väärtusi, "ei vasta" Olyale ja tagastage vastus Väär;
  • Andmete redigeerimine: sõbra lisamine: sarnase ülesande jaoks peame ka lahutama terve rida kasutades klahvi RowKey = “Vasya”, et arvutada tema sõprade koguarv. Seda sõprade koguarvu vajame selleks, et määrata veeru number, kuhu peame uue sõbra ID üles kirjutama.
  • Andmete muutmine: sõbra kustutamine:
    • Vaja lahutada terve rida klahviga RowKey = “Vasya” ja sorteerige veerge, et leida see, kuhu kustutatav sõber on salvestatud;
    • Järgmisena peame pärast sõbra kustutamist kõik andmed ühte veergu "nihutama", et nende nummerdamisel ei tekiks "lünki".

Hindame nüüd, kui tootlikud on need algoritmid, mida peame rakendama "tingimusliku rakenduse" poolel, kasutades O-sümbolism. Tähistame oma hüpoteetilise suhtlusvõrgustiku suurust n-ga. Siis on maksimaalne sõprade arv ühel kasutajal (n-1). Võime selle (-1) oma eesmärkidel veelgi tähelepanuta jätta, kuna O-sümbolite kasutamise raames on see ebaoluline.

  • Andmete lugemine: on vaja lahutada kogu rida ja itereerida läbi kõik selle limiidi veerud. See tähendab, et kulude ülemine hinnang on ligikaudu O(n)
  • Andmete redigeerimine: sõbra lisamine: sõprade arvu määramiseks peate läbima kõik rea veerud ja seejärel sisestama uue veeru => O(n)
  • Andmete muutmine: sõbra kustutamine:
    • Sarnaselt lisamisega - peate läbima kõik limiidi veerud => O(n)
    • Pärast veergude eemaldamist peame need "teisaldama". Kui rakendate selle "peapeale", siis on limiidis vaja kuni (n-1) toimingut. Kuid siin ja edaspidi kasutame praktilises osas teistsugust lähenemist, mis rakendab kindla arvu toimingute jaoks "pseudonihet" - see tähendab, et sellele kulub pidevalt aega, olenemata n-st. Selle konstantse aja (täpsemalt O(2)) võib O(n)-ga võrreldes tähelepanuta jätta. Lähenemisviis on illustreeritud alloleval joonisel: kopeerime lihtsalt andmed „viimasest“ veerust sellesse, kust tahame andmeid kustutada, ja seejärel kustutame viimase veeru:
      NoSQL-i andmemudeli kujundamise omadused

Kokkuvõttes saime kõigis stsenaariumides O (n) asümptootilise arvutusliku keerukuse.
Tõenäoliselt olete juba märganud, et peaaegu alati peame lugema andmebaasist terve rea ja kahel juhul kolmest lihtsalt selleks, et kõik veerud läbi käia ja sõprade koguarv välja arvutada. Seetõttu saate optimeerimise katseks lisada veeru “count”, mis salvestab iga võrgukasutaja sõprade koguarvu. Sel juhul ei saa me sõprade koguarvu arvutamiseks lugeda tervet rida, vaid lugeda ainult ühte loendi veergu. Peaasi, et andmetega manipuleerimisel ei tohi unustada loendit värskendada. See. me paraneme 2. valik (loendus):

RowKey
Esinejad

Vasya
1: Petya
2: Olya
3: Daša
arv: 3

Petja
1: Maša
2: Vasja

arv: 2

Võrreldes esimese variandiga:

  • Andmete lugemine: et saada vastus küsimusele "Kas Vasya loeb Oljat?" midagi pole muutunud => O(n)
  • Andmete redigeerimine: sõbra lisamine: Oleme uue sõbra sisestamist lihtsustanud, kuna nüüd ei pea me tervet rida lugema ja selle veerge kordama, vaid saame ainult veeru “count” väärtuse jne. määrake kohe uue sõbra sisestamiseks veeru number. See viib arvutusliku keerukuse vähenemiseni väärtuseni O(1)
  • Andmete muutmine: sõbra kustutamine: Sõbra kustutamisel saame seda veergu kasutada ka I/O operatsioonide arvu vähendamiseks, kui andmeid “nihutada” ühe lahtri võrra vasakule. Kuid vajadus veergude kordamist läbi vaadata, et leida see, mis tuleb kustutada, jääb endiselt, nii et => ​​O(n)
  • Teisest küljest peame nüüd andmete uuendamisel iga kord uuendama veergu “count”, kuid see võtab pidevalt aega, mida võib O-sümbolite raames tähelepanuta jätta.

Üldiselt tundub variant 2 veidi optimaalsem, kuid see sarnaneb pigem "evolutsiooniga revolutsiooni asemel". "Revolutsiooni" tegemiseks on meil vaja Valik 3 (veerg).
Pöörame kõik "pahupidi": me määrame veeru nimi kasutaja ID! See, mis veergu endasse kirjutatakse, pole meie jaoks enam oluline, olgu selleks siis number 1 (üldiselt saab sinna talletada kasulikke asju, näiteks gruppi “pere/sõbrad/jne”). Selline lähenemine võib üllatada ettevalmistamatut "võhikut", kellel pole varasemat NoSQL-i andmebaasidega töötamise kogemust, kuid just see lähenemine võimaldab teil HBase'i potentsiaali selles ülesandes palju tõhusamalt kasutada:

RowKey
Esinejad

Vasya
Petya: 1
Olya: 1
Daša: 1

Petja
Maša: 1
Vasja: 1

Siin saame korraga mitu eelist. Nende mõistmiseks analüüsime uut struktuuri ja hindame arvutuslikku keerukust:

  • Andmete lugemine: et vastata küsimusele, kas Vasya on Olya tellitud, piisab, kui lugeda ühte veergu “Olya”: kui see on olemas, siis vastus on õige, kui mitte – Vale => O(1)
  • Andmete redigeerimine: sõbra lisamine: Sõbra lisamine: lisage lihtsalt uus veerg "Sõbra ID" => O(1)
  • Andmete muutmine: sõbra kustutamine: lihtsalt eemaldage veerg Sõbra ID => O(1)

Nagu näete, on selle salvestusmudeli oluliseks eeliseks see, et kõigis vajalikes stsenaariumides töötame ainult ühe veeruga, vältides kogu rea lugemist andmebaasist ja pealegi kõigi selle rea veergude loetlemist. Võiksime seal peatuda, aga...

Võite olla hämmingus ja minna andmebaasile juurdepääsul jõudluse optimeerimise ja I/O-toimingute vähendamise teel pisut kaugemale. Mis siis, kui salvestaksime täieliku seosteabe otse reavõtmesse? See tähendab, et muuta võti näiteks kasutajaID.sõbraID? Sel juhul ei pea me isegi rea veerge üldse lugema (4. valik (rida)):

RowKey
Esinejad

Vasja.Petja
Petya: 1

Vasja.Olja
Olya: 1

Vasja. Daša
Daša: 1

Petya.Masha
Maša: 1

Petja.Vasja
Vasja: 1

Ilmselgelt on kõigi andmetega manipuleerimise stsenaariumide hinnang sellises struktuuris, nagu ka eelmises versioonis, O(1). Erinevus 3. valikuga on ainult andmebaasi sisend-/väljundtoimingute tõhususes.

Noh, viimane "kummardus". On lihtne näha, et valikus 4 on reaklahvil muutuv pikkus, mis võib jõudlust mõjutada (siinkohal peame meeles, et HBase salvestab andmed baitide komplektina ja tabelite read on sorteeritud võtme järgi). Lisaks on meil eraldaja, mida võib mõne stsenaariumi korral olla vaja käsitleda. Selle mõju kõrvaldamiseks võite kasutada kasutajaID ja sõbra ID räsi ning kuna mõlemal räsil on konstantne pikkus, saate need lihtsalt ühendada ilma eraldajata. Siis näevad tabelis olevad andmed välja sellised (Valik 5 (räsi)):

RowKey
Esinejad

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petya: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Olya: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Daša: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Maša: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasja: 1

Ilmselgelt on sellise struktuuriga töötamise algoritmiline keerukus meie poolt vaadeldavates stsenaariumides sama, mis valiku 4 puhul – see tähendab O(1).
Kokkuvõttes võtame kõik meie arvutusliku keerukuse hinnangud ühte tabelisse kokku:

Sõbra lisamine
Sõbra kontrollimine
Sõbra eemaldamine

1. valik (vaikimisi)
O (n)
O (n)
O (n)

2. valik (loendamine)
O (1)
O (n)
O (n)

3. valik (veerg)
O (1)
O (1)
O (1)

4. valik (rida)
O (1)
O (1)
O (1)

Valik 5 (räsi)
O (1)
O (1)
O (1)

Nagu näete, tunduvad variandid 3-5 kõige eelistatumad ja tagavad teoreetiliselt kõigi vajalike andmetega manipuleerimise stsenaariumide täitmise konstantse aja jooksul. Meie ülesande tingimustes ei ole otsest nõuet hankida kõigi kasutaja sõprade nimekiri, kuid reaalsetes projektitegevustes oleks meil headel analüütikutel hea „ennata“, et selline ülesanne võib tekkida ja "Levita õlekõrs." Seetõttu on minu kaastunne 3. variandi poolel. Kuid on üsna tõenäoline, et reaalses projektis oleks selle taotluse saanud juba muul viisil lahendada, seega ilma üldise nägemuseta kogu probleemist on parem seda mitte teha. lõplikud järeldused.

Eksperimendi ettevalmistamine

Tahaksin eeltoodud teoreetilisi argumente praktikas testida - see oli pikal nädalavahetusel tekkinud idee eesmärk. Selleks on vaja hinnata meie "tingimusliku rakenduse" töökiirust kõigis kirjeldatud andmebaasi kasutamise stsenaariumides, samuti selle aja pikenemist sotsiaalse võrgustiku (n) suurenemisega. Sihtparameeter, mis meid huvitab ja mida eksperimendi käigus mõõdame, on aeg, mille „tingimuslik rakendus“ kulutab ühe „äritoimingu“ sooritamiseks. "Äritehingu" all peame silmas ühte järgmistest:

  • Ühe uue sõbra lisamine
  • Kontrollimine, kas kasutaja A on kasutaja B sõber
  • Ühe sõbra eemaldamine

Seega, võttes arvesse esialgses avalduses esitatud nõudeid, kujuneb kontrollimise stsenaarium järgmine:

  • Andmete salvestamine. Looge juhuslikult esialgne võrk suurusega n. "Päris maailmale" lähemale jõudmiseks on igal kasutajal olevate sõprade arv samuti juhuslik muutuja. Mõõtke aega, mille jooksul meie "tingimuslik rakendus" kõik loodud andmed HBase'i kirjutab. Seejärel jagage saadud aeg lisatud sõprade koguarvuga – nii saame ühe “äritoimingu” keskmise aja
  • Andmete lugemine. Koostage iga kasutaja jaoks loend "isiklustest", mille kohta peate saama vastuse, kas kasutaja on need tellinud või mitte. Nimekirja pikkus = ligikaudu kasutaja sõprade arv ja poolte kontrollitud sõprade puhul peaks vastus olema "jah" ja teisele poolele "ei". Kontrollimine toimub sellises järjekorras, et vastused “Jah” ja “Ei” vahelduvad (st igal teisel juhul peame valikute 1 ja 2 jaoks läbima kõik rea veerud). Seejärel jagatakse skriiningu koguaeg testitud sõprade arvuga, et saada keskmine sõelumisaeg subjekti kohta.
  • Andmete kustutamine. Eemalda kasutajast kõik sõbrad. Pealegi on kustutamise järjekord juhuslik (see tähendab, et me "segime" andmete salvestamiseks kasutatud algse loendi). Kontrollimise koguaeg jagatakse seejärel eemaldatud sõprade arvuga, et saada keskmine kontrollimise aeg.

Stsenaariumid tuleb käitada iga viie andmemudeli valiku ja erineva suurusega suhtlusvõrgustiku jaoks, et näha, kuidas aeg selle kasvades muutub. Ühe n piires peavad ühendused võrgus ja kontrollitavate kasutajate loend loomulikult olema kõigi 5 valiku puhul samad.
Parema mõistmise huvides on allpool näide genereeritud andmetest n= 5 jaoks. Kirjutatud "generaator" loob väljundina kolm ID-sõnastikku:

  • esimene on sisestamiseks
  • teine ​​on kontrollimiseks
  • kolmas – kustutamiseks

{0: [1], 1: [4, 5, 3, 2, 1], 2: [1, 2], 3: [2, 4, 1, 5, 3], 4: [2, 1]} # всего 15 друзей

{0: [1, 10800], 1: [5, 10800, 2, 10801, 4, 10802], 2: [1, 10800], 3: [3, 10800, 1, 10801, 5, 10802], 4: [2, 10800]} # всего 18 проверяемых субъектов

{0: [1], 1: [1, 3, 2, 5, 4], 2: [1, 2], 3: [4, 1, 2, 3, 5], 4: [1, 2]} # всего 15 друзей

Nagu näete, on kõik kontrollimiseks mõeldud sõnastikus olevad ID-d, mis on suuremad kui 10 000, just need, mis annavad kindlasti vastuse Vale. "Sõprade" sisestamine, kontrollimine ja kustutamine toimub täpselt sõnastikus määratud järjekorras.

Katse viidi läbi Windows 10 operatsioonisüsteemiga sülearvutiga, kus ühes Dockeri konteineris töötas HBase ja teises Python koos Jupyteri sülearvutiga. Dockerile eraldati 2 protsessorituuma ja 2 GB muutmälu. Kogu loogika, nagu "tingimusliku rakenduse" emuleerimine ja "torustiku" katseandmete genereerimiseks ja aja mõõtmiseks, on kirjutatud Pythonis. Teeki kasutati HBase'iga töötamiseks õnnelik alus, et arvutada räsi (MD5) valiku 5 jaoks – hashlib

Võttes arvesse konkreetse sülearvuti arvutusvõimsust, valiti katseliselt käivitus n = 10, 30, … jaoks. 170 – kui kogu testimistsükli kogu tööaeg (kõik stsenaariumid kõikidele variantidele kõigile n-le) oli isegi enam-vähem mõistlik ja sobis ühe teeõhtu jooksul (keskmiselt 15 minutit).

Siinkohal tuleb märkida, et selles katses ei hinda me eelkõige absoluutseid jõudlusnäitajaid. Isegi kahe erineva võimaluse suhteline võrdlus ei pruugi olla täiesti õige. Nüüd huvitab meid n-st sõltuva aja muutumise olemus, kuna ülaltoodud "katsestendi" konfiguratsiooni arvesse võttes on juhuslike ja muude tegurite mõjust "puhastatud" ajahinnanguid väga raske saada ( ja sellist ülesannet ei seatud).

Eksperimendi tulemus

Esimene test on see, kuidas muutub sõbralisti täitmisele kuluv aeg. Tulemus on alloleval graafikul.
NoSQL-i andmemudeli kujundamise omadused
Valikud 3-5 näitavad ootuspäraselt peaaegu konstantset “äritehingu” aega, mis ei sõltu võrgu suuruse kasvust ja jõudluse eristamatust erinevusest.
Valik 2 näitab ka püsivat, kuid veidi halvemat jõudlust, peaaegu täpselt 2 korda võrreldes valikutega 3-5. Ja see ei saa muud üle kui rõõmustada, kuna see on korrelatsioonis teooriaga - selles versioonis on HBase'i/HBase'i sisend-väljundoperatsioonide arv täpselt 2 korda suurem. See võib olla kaudne tõend selle kohta, et meie katsestendil on põhimõtteliselt hea täpsus.
Valik 1 osutub ootuspäraselt ka kõige aeglasemaks ja näitab lineaarset pikenemist, mis kulub võrgu suurusele üksteise lisamiseks.
Vaatame nüüd teise testi tulemusi.
NoSQL-i andmemudeli kujundamise omadused
Valikud 3-5 käituvad jälle ootuspäraselt – konstantne aeg, sõltumata võrgu suurusest. Valikud 1 ja 2 näitavad aja lineaarset pikenemist, kui võrgu suurus suureneb, ja sarnast jõudlust. Veelgi enam, valik 2 osutub veidi aeglasemaks – ilmselt seetõttu, et on vaja korrektuuri ja töödelda täiendavat veergu “count”, mis muutub n kasvades märgatavamaks. Kuid ma siiski hoidun igasuguste järelduste tegemisest, kuna selle võrdluse täpsus on suhteliselt madal. Lisaks muudeti neid suhteid (kumb valik, 1 või 2 on kiirem) jooksu pealt jooksmisele (säilitades samas sõltuvuse olemuse ja “kael ja kaela”).

Noh, viimane graafik on eemaldamise testimise tulemus.

NoSQL-i andmemudeli kujundamise omadused

Jällegi, siin pole üllatusi. Valikud 3-5 teostavad eemaldamist konstantse aja jooksul.
Veelgi enam, huvitaval kombel näitavad variandid 4 ja 5 erinevalt eelmistest stsenaariumitest märgatavalt veidi halvemat jõudlust kui valik 3. Ilmselt on ridade kustutamise operatsioon kallim kui veeru kustutamise toiming, mis on üldiselt loogiline.

Võimalused 1 ja 2 näitavad ootuspäraselt aja lineaarset pikenemist. Samal ajal on valik 2 pidevalt aeglasem kui valik 1 – tänu täiendavale sisend-/väljundoperatsioonile loendusveeru "säilitamiseks".

Katse üldised järeldused:

  • Valikud 3–5 näitavad suuremat tõhusust, kuna need kasutavad ära HBase'i; Pealegi erineb nende jõudlus üksteise suhtes konstandi võrra ega sõltu võrgu suurusest.
  • 4. ja 5. variantide erinevust ei registreeritud. Kuid see ei tähenda, et 5. võimalust ei tuleks kasutada. Tõenäoliselt ei võimaldanud kasutatud katsestsenaarium, võttes arvesse katsestendi tööomadusi, seda tuvastada.
  • Andmetega "äritoimingute" tegemiseks kuluva aja pikenemise iseloom kinnitas üldiselt kõigi võimaluste kohta eelnevalt saadud teoreetilisi arvutusi.

Epiloog

Läbiviidud jämedaid katseid ei tohiks võtta absoluutse tõena. On palju tegureid, mida ei arvestatud ja mis tulemusi moonutasid (eriti on need kõikumised näha väikese võrgumahuga graafikutel). Näiteks säästmise kiirus, mida happybase kasutab, Pythonis kirjutatud loogika maht ja rakendamise meetod (ma ei saa väita, et kood on kirjutatud optimaalselt ja kasutas tõhusalt kõigi komponentide võimalusi), võib-olla HBase'i vahemällu salvestamise funktsioonid, Windows 10 taustategevus minu sülearvutis jne. Üldiselt võime eeldada, et kõik teoreetilised arvutused on eksperimentaalselt tõestanud nende kehtivust. No või vähemalt ei õnnestunud neid sellise “pearünnakuga” ümber lükata.

Kokkuvõtteks soovitused kõigile, kes alles hakkavad HBase'is andmemudeleid kujundama: tehke kokkuvõte varasemast relatsiooniandmebaasidega töötamise kogemusest ja pidage meeles "käske":

  • Projekteerimisel lähtume andmete manipuleerimise ülesandest ja mustritest, mitte domeenimudelist
  • Tõhus juurdepääs (ilma täieliku tabeli skannimiseta) – ainult võtmega
  • Denormaliseerimine
  • Erinevad read võivad sisaldada erinevaid veerge
  • Kõlarite dünaamiline koosseis

Allikas: www.habr.com

Lisa kommentaar