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 pead jooksma vähemalt kaks korda kiiremini!
(c) Alice Imedemaal

Mõni aeg tagasi paluti mul loengut pidada analüütikud Meie ettevõtte fookuses on andmemudelite disain, kuna me töötame projektide kallal pikka aega (mõnikord mitu aastat) ja unustame IT-maailmas toimuva. Meie ettevõttes, nagu ikka, paljud projektid ei kasuta NoSQL-i andmebaase (vähemalt mitte veel), seega keskendusin oma loengus just neile, tuues näitena HBase'i, ja püüdsin esitlust kohandada neile, kes pole nendega kunagi töötanud. Täpsemalt illustreerisin andmemudelite disaini mõningaid eripärasid näite abil, mida lugesin mitu aastat tagasi. Amandeep Khurana artiklis „Sissejuhatus HB ase skeemi kujundamisse”Näidete analüüsimisel võrdlesin sama probleemi mitut lahendust, et põhiideed paremini publikule edastada.

Hiljuti "igavusest" mõtlesin (pikad maikuu pühad karantiini ajal olid sellele küsimusele eriti soodsad): kui hästi teoreetilised kontseptsioonid praktikasse ülekantavad? Nii sündiski selle artikli idee. Arendaja, kes on NoSQL-iga juba mõnda aega töötanud, ei pruugi sellest midagi uut saada (ja seetõttu võib pool artiklist vahele jätta). Aga analüütikudNeile, kes pole veel NoSQL-iga põhjalikult töötanud, arvan, et see on kasulik HBase'i andmemudelite kujundamise eripärade põhiteadmiste saamiseks.

Näite analüüs

Minu arvates tuleb enne NoSQL-i andmebaaside kasutamist hoolikalt mõelda ja plusse ja miinuseid kaaluda. Sageli saab ülesande lahendada traditsiooniliste relatsioon-andmebaasihaldussüsteemide abil. Seetõttu on kõige parem vältida NoSQL-i kasutamist ilma mõjuva põhjuseta. Kui otsustate NoSQL-i andmebaasi kasutada, pidage meeles, et disainimeetodid on mõnevõrra erinevad. Mõned neist võivad olla eriti harjumatud neile, kes on varem töötanud ainult relatsioon-andmebaasihaldussüsteemidega (minu kogemuse põhjal). Näiteks relatsioonmaailmas alustame tavaliselt valdkonna modelleerimisega ja seejärel vajadusel mudeli denormaliseerime. NoSQL-is aga me... peab viivitamatult arvestama andmetega töötamise eeldatavate stsenaariumidega ja esialgu denormaliseerige andmed. On ka mitmeid muid erinevusi, mida käsitletakse allpool.

Vaatleme järgmist „sünteetilist” probleemi, millega me jätkame tööd:

Peame kujundama teatud abstraktse sotsiaalvõrgustiku kasutajate sõbralisti salvestusstruktuuri. Lihtsuse mõttes eeldame, et kõik ühendused on suunatud (nagu Instagramis, mitte LinkedInis). Struktuur peaks võimaldama järgmise tõhusat rakendamist:

  • Vasta küsimusele, kas kasutaja A loeb kasutajat B (lugemismuster)
  • Luba ühenduste lisamine/eemaldamine, kui kasutaja A jälgib/lõpetab kasutaja B jälgimise (andmete muutmise mall)

Loomulikult on sellele probleemile palju võimalikke lahendusi. Traditsioonilises relatsioonandmebaasis looksime tõenäoliselt lihtsalt relatsioonitabeli (võib-olla tüübitud, kui näiteks peame salvestama kasutajarühmi – perekond, töö jne –, mis sisaldavad antud "sõpra") ja lisaksime indeksid/partitsioonid, et optimeerida juurdepääsu kiirust. Saadud tabel näeks tõenäoliselt välja umbes selline:

USER_ID
sõbra_id

Vasya
Petja

Vasya
Оля

Selguse ja parema arusaamise huvides kasutan edaspidi ID-de asemel nimesid.

HBase'i puhul teame, et:

  • Tõhus otsing ilma täieliku tabeli skaneerimiseta on võimalik ainult võtme abil
    • Seepärast on sellistele andmebaasidele tuttavate SQL-päringute kirjutamine halb mõte; tehniliselt saab muidugi Impalast HBase'i saata SQL-päringu koos liitumiste ja muu loogikaga, aga kui tõhus see on?

Seetõttu oleme sunnitud kasutajatunnust võtmena kasutama. Esimene mõte teemal "kuhu ja kuidas sõprade ID-sid salvestada?" võib olla idee salvestada need veergudesse. See kõige ilmsem ja "naiivsem" variant näeks välja umbes selline (nimetagem seda Valik 1 (vaikimisi), edaspidiseks kasutamiseks):

Reavõti
Esinejad

Vasya
1: Petja
2: Olja
3: Daša

Petja
1: Maša
2: Vasja

Siin vastab iga rida ühele võrgukasutajale. Veerud on nimetatud 1, 2, ... – sõprade arvu põhjal – ja salvestavad sõprade ID-sid. Oluline on märkida, et igal real on erinev arv veerge. Ülaltoodud näites on ühel real kolm veergu (1, 2 ja 3), teisel aga ainult kaks (1 ja 2). Siin oleme ära kasutanud kahte HBase'i omadust, mida relatsioonandmebaasidel pole:

  • võimalus veergude koostist dünaamiliselt muuta (lisa sõber -> lisa veerg, eemalda sõber -> eemalda veerg)
  • erinevatel ridadel võivad olla erinevad veergude koostised

Kontrollime oma struktuuri vastavust ülesande nõuetele:

  • Andmete lugemine: selleks, et mõista, kas Vasya on Olya tellija, peame lahutama kogu rida RowKey = "Vasya" abil ja itereerime veeruväärtusi, kuni me "kohtume" Olyaga. Või itereerime läbi kõik veeruväärtused, "ei kohtu" Olyaga ja tagastame väärtuse False;
  • Andmete muutmine: sõbra lisaminesarnase probleemi puhul peame ka lahutama kogu rida RowKey = "Vasya" abil loendada oma sõprade koguarvu. Me vajame seda sõprade koguarvu, et määrata veeru number, kuhu uue sõbra ID salvestada.
  • Andmete muutmine: sõbra kustutamine:
    • On vaja lahutada kogu rida võtme RowKey = “Vasya” abil ja leidke veerud, kuhu kustutatav sõber on salvestatud;
    • Järgmisena, pärast sõbra kustutamist, peame kõik andmed ühte veergu "nihutama", et nende numeratsioonis ei tekiks "lünki".

Hindame nüüd, kui produktiivsed need algoritmid, mida peame "tingimusliku rakenduse" poolel rakendama, on. O-sümboolikaTähistagem hüpoteetilise sotsiaalvõrgustiku suurust n-ga. Siis on ühe kasutaja maksimaalne sõprade arv (n-1). Me võime seda (-1) siinkohal ignoreerida, kuna see pole O-sümbolite kasutamise kontekstis oluline.

  • Andmete lugemine: on vaja lahutada kogu rida ja piirväärtuse korral itereerida läbi kõigi selle veergude. See tähendab, et ülemine kuluhinnang on ligikaudu O(n)
  • Andmete muutmine: sõbra lisamineSõprade arvu määramiseks tuleb läbi käia kõik rea veerud ja seejärel lisada uus veerg => O(n)
  • Andmete muutmine: sõbra kustutamine:
    • Sarnaselt liitmisega on vaja itereerida üle kõigi veergude piirväärtuses => O(n)
    • Pärast veergude kustutamist peame need "nihutama". Lihtne lähenemine nõuaks kuni (n-1) operatsiooni rohkem. Siin ja kogu praktilises osas kasutame aga teistsugust lähenemist, mis rakendab "pseudo-nihet" fikseeritud arvu operatsioonidega – see tähendab, et see võtab konstantse aja olenemata n-st. See konstantne aeg (täpsemalt O(2)) on tühine võrreldes O(n)-ga. Lähenemisviisi illustreerib allolev joonis: me lihtsalt kopeerime andmed "viimasest" veerust sellesse, kust andmed tuleb kustutada, ja seejärel kustutame viimase veeru:
      NoSQL-i andmemudeli kujundamise omadused

Kokku saime kõigis stsenaariumides asümptootilise arvutusliku keerukuse O(n).
Tõenäoliselt olete juba märganud, et peaaegu alati peame andmebaasist lugema terve rea ja kahel juhul kolmest ainult selleks, et kõik veerud läbi käia ja sõprade koguarvu arvutada. Seetõttu saame optimeerimise eesmärgil lisada veeru "count", et salvestada iga võrgukasutaja sõprade koguarv. Sellisel juhul ei pea me sõprade koguarvu arvutamiseks lugema tervet rida, vaid lugema ainult veergu "count". Peaasi on meeles pidada, et andmetega manipuleerides värskendataks veergu "count". Nii saame parema tulemuse. 2. variant (loendus):

Reavõti
Esinejad

Vasya
1: Petja
2: Olja
3: Daša
arv: 3

Petja
1: Maša
2: Vasja

arv: 2

Võrreldes esimese variandiga:

  • Andmete lugemine: küsimusele "Kas Vasja loeb Oljat?" vastuse saamiseks pole midagi muutunud => O(n)
  • Andmete muutmine: sõbra lisamineOleme uue sõbra lisamise lihtsustanud, kuna me ei pea enam kogu rida lugema ja selle veerge läbi käima. Nüüd saame hankida ainult veeru "count" väärtuse ja seega kohe määrata veeru numbri uue sõbra lisamiseks. See vähendab arvutuslikku keerukust O(1)-ni.
  • Andmete muutmine: sõbra kustutamineSõbra kustutamisel saame seda veergu kasutada ka I/O-operatsioonide arvu vähendamiseks andmete ühe lahtri võrra vasakule nihutamisel. Kustutatava leidmiseks peame aga ikkagi veerud läbi käima, seega => ​​O(n)
  • Teisest küljest peame andmete värskendamisel iga kord värskendama ka veergu „count“, kuid see võtab konstantse aja, mida saab O-sümbolite raamistikus eirata.

Üldiselt tundub variant 2 veidi optimaalsem, aga see meenutab pigem "evolutsiooni revolutsiooni asemel". "Revolutsiooni" saavutamiseks on meil vaja Variant 3 (veerg).
Pöörame kõik pea peale: määrame ametisse veeru nimi kasutaja ID! See, mis veerus kirjas on, pole meie jaoks ülioluline; kasutame lihtsalt numbrit 1 (üldiselt võiks sinna salvestada kasulikke asju, näiteks rühmana nagu "perekond/sõbrad/jne"). See lähenemine võib üllatada algajat "võhikut", kellel pole eelnevat kogemust NoSQL-i andmebaasidega, kuid see võimaldab meil HBase'i potentsiaali selle ülesande jaoks palju tõhusamalt ära kasutada:

Reavõti
Esinejad

Vasya
Petja: 1
Olja: 1
Daša: 1

Petja
Maša: 1
Vasja: 1

See pakub mitmeid eeliseid. Nende mõistmiseks analüüsime uut struktuuri ja hindame selle arvutuslikku keerukust:

  • Andmete lugemineKüsimusele, kas Vasja on Olja tellija, vastamiseks piisab ühest veerust „Olja“: kui on, siis on vastus tõene, kui ei ole – vale => O(1)
  • Andmete muutmine: sõbra lisamineSõbra lisamine: lisa lihtsalt uus veerg "Sõbra ID" => O(1)
  • Andmete muutmine: sõbra kustutamine: eemalda lihtsalt veerg "Sõbra ID" => O(1)

Nagu näeme, on selle salvestusmudeli oluline eelis see, et kõigis vajalikes stsenaariumides opereerime ainult ühe veeruga, vältides seega kogu rea lugemist andmebaasist, rääkimata selle rea kõigi veergude läbikäimisest. Me võiksime seal peatuda, aga...

Saame olla veidi loomingulisemad ja minna veidi kaugemale jõudluse optimeerimisel ja sisend-/väljundoperatsioonide vähendamisel andmebaasile juurdepääsul. Mis siis, kui salvestaksime kogu seoseteabe otse reavõtmesse endasse? See tähendab, et muudaksime võtme liitvõtmeks, näiteks kasutajaID.sõbraID? Sellisel juhul ei peaks me isegi reaveergusid lugema (Variant 4 (rida)):

Reavõti
Esinejad

Vasja. Petja
Petja: 1

Vasja.Olja
Olja: 1

Vasja.Daša
Daša: 1

Petja. Maša
Maša: 1

Petja. Vasja
Vasja: 1

Ilmselgelt on sellise struktuuri kõigi andmetöötlusstsenaariumide hindamine O(1), nagu ka eelmises valikus. Erinevus 3. valikuga seisneb ainult andmebaasi I/O-operatsioonide efektiivsuses.

Ja lõpuks viimane nipp. On lihtne näha, et 4. variandi puhul on meie reavõtmel muutuv pikkus, mis võib potentsiaalselt jõudlust mõjutada (pidage meeles, et HBase salvestab andmeid baitide komplektina ja tabeli read sorteeritakse võtme järgi). Lisaks on meil eraldaja, mida võib mõnel juhul vaja minna töödelda. Selle mõju vältimiseks saame kasutada kasutajaID ja sõbraID räsi. Kuna mõlemal räsil on konstantne pikkus, saame need lihtsalt eraldajata liita. Seejärel näevad tabeli andmed välja sellised:Variant 5 (räsi)):

Reavõti
Esinejad

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petja: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Olja: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Daša: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Maša: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasja: 1

Ilmselgelt on sellise struktuuriga töötamise algoritmiline keerukus meie vaadeldavate stsenaariumide kohaselt sama, mis 4. variandi puhul – st O(1).
Võtame siis kõik meie arvutusliku keerukuse hinnangud ühte tabelisse kokku:

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

Valik 1 (vaikimisi)
O (n)
O (n)
O (n)

2. variant (loendus)
O (1)
O (n)
O (n)

3. variant (veerg)
O (1)
O (1)
O (1)

Variant 4 (rida)
O (1)
O (1)
O (1)

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

Nagu näete, tunduvad valikud 3-5 eelistatumad ja tagavad teoreetiliselt kõigi vajalike andmetöötlusstsenaariumide täitmise konstantse aja jooksul. Meie probleemipüstitus ei nõua otseselt kõigi kasutaja sõprade nimekirja hankimist, kuid reaalsetes projektides oleks meil heade analüütikutena soovitatav sellist probleemi ette näha ja ettevaatusabinõusid võtta. Seetõttu pooldan ma 3. valikut. Siiski on täiesti võimalik, et reaalses projektis on see taotlus juba muul viisil lahendatud, seega ilma kogu probleemi üldise mõistmiseta on parem mitte teha lõplikke järeldusi.

Katse ettevalmistamine

Sooviksin ülaltoodud teoreetilist arutluskäiku praktikas testida – see oligi pika nädalavahetuse jooksul tekkinud idee eesmärk. Selleks peame hindama oma „hüpoteetilise rakenduse” toimivust kõigis kirjeldatud andmebaasi kasutusstsenaariumides ja seda, kuidas see aeg suureneb koos sotsiaalvõrgustiku suurusega (n). Sihtparameeter, mis meid huvitab ja mida me katse käigus mõõdame, on aeg, mis kulub „hüpoteetilisel rakendusel” ühe „ärioperatsiooni” sooritamiseks. „Ärioperatsiooni” all peame silmas ühte järgmistest:

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

Seega, võttes arvesse esialgses avalduses esitatud nõudeid, on verifitseerimisstsenaarium järgmine:

  • Andmete salvestamineGenereerige juhuslikult algne võrk suurusega n. "Pärismaailma" paremaks lähendamiseks on iga kasutaja sõprade arv samuti juhuslik. Mõõtke aeg, mis kulub meie "näidisrakendusel" kõigi genereeritud andmete HBase'i kirjutamiseks. Seejärel jagage see aeg lisatud sõprade koguarvuga – see annab meile ühe "äritoimingu" keskmise aja.
  • Andmete lugemineIga kasutaja jaoks loo loend "isiksustest", mille puhul pead kindlaks tegema, kas kasutaja jälgib neid või mitte. Loendi pikkus on ligikaudu võrdne kasutaja sõprade arvuga, kusjuures vastus on poolte kontrollitud sõprade puhul "Jah" ja teise poole puhul "Ei". Kontrollid tehakse nii, et vastused "Jah" ja "Ei" vahelduvad (see tähendab, et igal muul juhul peame valikute 1 ja 2 jaoks läbi käima kõik rea veerud). Seejärel jagatakse kontrolli koguaeg kontrollitud sõprade arvuga, et saada keskmine aeg kontrolli kohta.
  • Andmete kustutamineKustuta kõik kasutaja sõbrad. Kustutamise järjekord on juhuslik (st me segame andmete salvestamiseks kasutatud algset nimekirja). Seejärel jagatakse kinnituse koguaeg kustutatavate sõprade arvuga, et saada keskmine kinnituse aeg.

Stsenaariume tuleb käivitada iga viie andmemudeli variandi ja erineva suurusega sotsiaalvõrgustike puhul, et näha, kuidas aeg võrgustiku kasvades muutub. Ühe n-mudeli piires peavad võrguühendused ja testitavate kasutajate loend loomulikult olema kõigi viie variandi puhul samad.
Paremaks mõistmiseks on allpool näide genereeritud andmetest n = 5 jaoks. Minu kirjutatud "generaator" loob kolm ID-sõnastikku:

  • esimene on sisestamiseks
  • teine ​​on kontrollimiseks
  • kolmas on eemaldamiseks

{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 sõnastikus kontrollimiseks mõeldud ID-d, mille number on suurem kui 10 000, just need, mis kindlasti tagastavad väärtuse „väär“. Sõprade sisestamine, kontrollimine ja kustutamine toimub sõnastikus määratud järjekorras.

Katse viidi läbi sülearvutil, millel oli Windows 10, kus HBase töötas ühes Dockeri konteineris ja Python koos Jupyter Notebookiga töötas teises. Dockerile eraldati 2 protsessori tuuma ja 2 GB muutmälu. Kogu loogika, sealhulgas "mannekeenirakenduse" simulatsioon ja testandmete genereerimise ning aja mõõtmise raamistik, kirjutati Pythonis. Teek õnnelik baas, 5. valiku räsi (MD5) arvutamiseks - hashlib

Võttes arvesse konkreetse sülearvuti arvutusvõimsust, valiti eksperimentaalselt käivitusaeg ajavahemike n = 10, 30, ... 170 jaoks – kui kogu testimistsükli (kõik stsenaariumid kõigi valikute jaoks kõigi n jaoks) kogukestusaeg oli veel enam-vähem mõistlik ja mahtus ühe teepidu ajale (keskmiselt 15 minutit).

Oluline on siinkohal märkida, et selles katses ei hinda me peamiselt absoluutseid jõudlusnäitajaid. Isegi kahe erineva variandi suhteline võrdlus ei pruugi olla täiesti täpne. Praegu huvitab meid aja muutuse olemus n funktsioonina, kuna ülalmainitud testplatvormi konfiguratsiooni arvestades on juhuslike ja muude tegurite mõjust "puhastatud" ajahinnangute saamine väga keeruline (ja see polnudki eesmärk).

Katse tulemus

Esimeses testis uuriti, kuidas muutub sõbralisti täitmiseks kuluv aeg. Tulemused on näidatud alloleval graafikul.
NoSQL-i andmemudeli kujundamise omadused
Valikud 3–5 näitavad ootuspäraselt praktiliselt konstantset "äritegevuse" aega, mis ei sõltu võrgu suuruse kasvust, ning märgatavat jõudluse erinevust.
Variant 2 näitab samuti konstantset, kuid veidi halvemat jõudlust, peaaegu täpselt kaks korda rohkem kui variantidel 3-5. See on julgustav, kuna see on kooskõlas teooriaga – selles variandis on HBase'i ja HBase'i suunatavate I/O-operatsioonide arv täpselt kaks korda suurem. See võib olla kaudne tõend selle kohta, et meie testi seadistus tagab üldiselt korraliku täpsuse.
Nagu oodatud, osutub ka 1. variant kõige aeglasemaks ning näitab ühe sõbra lisamiseks kuluva aja lineaarset suurenemist, olenevalt võrgu suurusest.
Vaatame nüüd teise testi tulemusi.
NoSQL-i andmemudeli kujundamise omadused
Variandid 3-5 käituvad taas ootuspäraselt – konstantse aja jooksul, olenemata võrgu suurusest. Variandid 1 ja 2 näitavad lineaarset aja kasvu koos võrgu suurusega ja sarnast jõudlust. Variant 2 on aga veidi aeglasem – ilmselt vajaduse tõttu analüüsida ja töödelda täiendavat "loendus" veergu, mis muutub märgatavamaks n suurenedes. Siiski jätan hinnangu andmata, kuna selle võrdluse täpsus on suhteliselt madal. Lisaks varieerusid korrelatsioonid (milline variant, 1 või 2, on kiirem) tsükliti (säilitades samal ajal järjepideva mustri ja olles kak-kaelus).

Noh, viimane graafik on eemaldamistesti tulemus.

NoSQL-i andmemudeli kujundamise omadused

Jällegi pole siin mingeid üllatusi. Valikud 3-5 teostavad kustutamise konstantse aja jooksul.
Huvitaval kombel näitavad valikud 4 ja 5, erinevalt eelmistest stsenaariumidest, märgatavalt veidi halvemat jõudlust kui valik 3. Ilmselt on rea kustutamise toiming kallim kui veeru kustutamise toiming, mis on üldiselt loogiline.

Nagu oodatud, näitavad valikud 1 ja 2 lineaarset ajakasvu. Valik 2 on aga pidevalt aeglasem kui variant 1, kuna loendusveeru haldamiseks on vaja täiendavat sisend-/väljundoperatsiooni.

Katse üldised järeldused:

  • Valikud 3–5 näitavad suuremat efektiivsust, kuna need kasutavad ära HBase'i; aga nende jõudlus erineb üksteisest konstantse väärtuse võrra ega sõltu võrgu suurusest.
  • Variantide 4 ja 5 vahel ei täheldatud erinevust. See aga ei tähenda, et varianti 5 ei tohiks kasutada. Arvestades katsealuse jõudlusomadusi, takistas kasutatud eksperimentaalne stsenaarium selle tuvastamist.
  • Andmetega „äritoimingute” teostamiseks kuluva aja pikenemise iseloom kinnitas üldiselt kõigi valikute puhul varem saadud teoreetilisi arvutusi.

Epiloog

Neid ligikaudseid katseid ei tohiks absoluutse tõena võtta. On palju tegureid, mida ei võetud arvesse ja mis moonutasid tulemusi (need kõikumised on eriti nähtavad väikeste võrkude suuruste graafikutel). Näiteks säästlikkuse kiirus, mida happybase kasutab, Pythonis kirjutatud loogika maht ja rakendusmeetod (ma ei saa väita, et kood kirjutati optimaalselt või et kõiki komponente kasutati tõhusalt), võimalik, et HBase'i vahemällu salvestamise funktsioonid ja taustategevus. Windows 10 Minu sülearvutil jne. Üldiselt võib järeldada, et kõik teoreetilised eeldused on eksperimentaalselt osutunud kehtivaks. Või vähemalt ei olnud võimalik neid sellise otsekohese rünnakuga ümber lükata.

Kokkuvõtteks on siin mõned soovitused kõigile, kes alles alustavad HBase'is andmemudelite kujundamist: pange kõrvale oma varasem kogemus relatsioonandmebaasidega ja pidage meeles "käske":

  • Projekteerimisel lähtume ülesande ja andmetega manipuleerimise mustritest, mitte domeenimudelist.
  • Tõhus juurdepääs (ilma täieliku tabeli skaneerimiseta) – ainult võtmega
  • Denormaliseerimine
  • Erinevad read võivad sisaldada erinevaid veerge.
  • Veergude dünaamiline koostis

Allikas: www.habr.com

Ostke DDoS-kaitsega saitide jaoks usaldusväärne hostimine, VPS VDS-serverid 🔥 Osta usaldusväärne veebimajutus DDoS-kaitsega, VPS VDS serverid | ProHoster