Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2Noțiuni introductive - vezi partea 1.

3. Variante de structuri la utilizarea globalelor

O structură precum un arbore ordonat are diverse cazuri speciale. Să luăm în considerare cele care au valoare practică atunci când lucrăm cu globaluri.

3.1 Caz special 1. Un nod fără ramuri


Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2Globalele pot fi folosite nu numai ca o matrice, ci și ca variabile obișnuite. De exemplu, ca contor:

Set ^counter = 0  ; установка счётчика
Set id=$Increment(^counter) ;  атомарное инкрементирование

În acest caz, globalul, pe lângă sensul său, poate avea și ramuri. Unul nu îl exclude pe celălalt.

3.2 Caz special 2. Un vârf și mai multe ramuri

În general, aceasta este o bază clasică cheie-valoare. Și dacă salvăm un tuplu de valori ca valoare, vom obține un tabel foarte obișnuit cu o cheie primară.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2

Pentru a implementa un tabel cu valori globale, va trebui să generăm noi înșine rânduri din valorile coloanei și apoi să le salvam în global folosind cheia primară. Pentru a face posibilă împărțirea șirului în coloane din nou atunci când citiți, puteți utiliza:

  1. caractere delimitare.
    Set ^t(id1) = "col11/col21/col31"
    Set ^t(id2) = "col12/col22/col32"
  2. o schemă rigidă în care fiecare câmp ocupă un număr predeterminat de octeți. Așa cum se face în bazele de date relaționale.
  3. o funcție specială $LB (disponibilă în Cache), care creează un șir de valori.
    Set ^t(id1) = $LB("col11", "col21", "col31")
    Set ^t(id2) = $LB("col12", "col22", "col32")

Interesant este că nu este dificil să folosiți globals pentru a face ceva similar cu indecșii secundari din bazele de date relaționale. Să numim astfel de structuri index global. Un index global este un arbore auxiliar pentru căutarea rapidă a câmpurilor care nu fac parte din cheia primară a globalului principal. Pentru a-l completa și utiliza, trebuie să scrieți cod suplimentar.

Să creăm un index global pe prima coloană.

Set ^i("col11", id1) = 1
Set ^i("col12", id2) = 1

Acum, pentru a căuta rapid informații în prima coloană, trebuie să ne uităm la global ^i și găsiți cheile primare (id) corespunzătoare valorii dorite a primei coloane.

Când inserăm o valoare, putem crea imediat atât valoarea globală, cât și indexul pentru câmpurile necesare. Iar pentru fiabilitate, să includem totul într-o tranzacție.

TSTART
Set ^t(id1) = $LB("col11", "col21", "col31")
Set ^i("col11", id1) = 1
TCOMMIT

Detalii despre cum se face pe M tabele cu valori globale, emularea indicilor secundari.

Astfel de tabele vor funcționa la fel de repede ca în bazele de date tradiționale (sau chiar mai rapid) dacă funcțiile de inserare/actualizare/ștergere de rânduri sunt scrise în COS/M și compilate.Am verificat această declarație cu teste în bloc INSERT și SELECT într-un tabel cu două coloane, inclusiv folosind comenzile TSTART și TCOMMIT (tranzacții).

Nu am testat scenarii mai complexe cu acces simultan și tranzacții paralele.

Fără a utiliza tranzacții, rata de inserare a fost de 778 inserări/secundă per milion de valori.
Cu 300 de milioane de valori - 422 inserții/secundă.

Când se utilizează tranzacții - 572 inserții/secundă pentru 082M inserții. Toate operațiunile au fost efectuate din codul M compilat.
Hard disk-urile sunt obișnuite, nu SSD. RAID5 cu rescriere. Procesor Phenom II 1100T.

Pentru a testa o bază de date SQL într-un mod similar, trebuie să scrieți o procedură stocată care va efectua inserții într-o buclă. Când am testat MySQL 5.5 (stocare InnoDB), folosind această metodă am primit numere care nu depășesc 11K inserții pe secundă.
Da, implementarea tabelelor pe globale pare mai complexă decât în ​​bazele de date relaționale. Prin urmare, bazele de date industriale pe globale au acces SQL pentru a simplifica lucrul cu date tabulare.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2În general, dacă schema de date nu se va schimba frecvent, viteza de inserare nu este critică și întreaga bază de date poate fi ușor reprezentată sub formă de tabele normalizate, atunci este mai ușor să lucrați cu SQL, deoarece oferă un nivel mai ridicat de abstractizare .

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2În acest caz, am vrut să arăt asta globals pot acționa ca un constructor pentru crearea altor baze de date. Ca un asamblator în care pot fi scrise alte limbi. Iată exemple despre cum puteți crea analogi pe globale cheie-valoare, liste, seturi, baze de date tabelare, orientate pe documente.

Dacă trebuie să creați un fel de bază de date non-standard cu un efort minim, atunci ar trebui să vă uitați la global.

3.3 Caz special 3. Arborele cu două niveluri, fiecare nod al celui de-al doilea nivel are un număr fix de ramuri

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2Probabil ați ghicit: aceasta este o implementare alternativă a tabelelor pe globale. Să comparăm această implementare cu cea anterioară.

Tabele pe un arbore cu două niveluri vs. pe un arbore cu un singur nivel.

Contra
Pro

  1. Mai lent pentru inserare, deoarece trebuie să setați numărul de noduri egal cu numărul de coloane.
  2. Mai mult consum de spațiu pe disc. Deoarece indecșii globali (înțeleși ca indici de matrice) cu nume de coloane ocupă spațiu pe disc și sunt duplicați pentru fiecare rând.

  1. Acces mai rapid la valorile coloanelor individuale, deoarece nu este nevoie să analizați șirul. Conform testelor mele, este cu 11,5% mai rapid pe 2 coloane și mai mult pe un număr mai mare de coloane.
  2. Mai ușor de schimbat schema de date
  3. Cod mai clar

Concluzie: nu pentru toata lumea. Deoarece viteza este unul dintre cele mai importante beneficii ale globale, nu are rost să folosiți această implementare, deoarece cel mai probabil nu va funcționa mai rapid decât tabelele din bazele de date relaționale.

3.4 Caz general. Copaci și copaci ordonați

Orice structură de date care poate fi reprezentată ca un arbore se potrivește perfect cu globalurile.

3.4.1 Obiecte cu subobiecte

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2

Aceasta este zona de utilizare tradițională a globale. În domeniul medical există un număr mare de boli, medicamente, simptome și metode de tratament. Este irațional să creezi un tabel cu un milion de câmpuri pentru fiecare pacient. Mai mult, 99% din câmpuri vor fi goale.

Imaginați-vă o bază de date SQL de tabele: „pacient” ~ 100 de câmpuri, „Medicina” - 000 de câmpuri, „Terapie” - 100 de câmpuri, „Complicații” - 000 de câmpuri etc. și așa mai departe. Sau puteți crea o bază de date cu multe mii de tabele, fiecare pentru un anumit tip de pacient (și se pot suprapune!), tratamente, medicamente și alte mii de tabele pentru conexiuni între aceste tabele.

Globalurile sunt ideale pentru medicină, deoarece vă permit să creați pentru fiecare pacient o descriere exactă a istoricului său medical, a diferitelor terapii și a acțiunilor medicamentelor, sub forma unui arbore, fără a pierde spațiu suplimentar pe disc pe coloanele goale, așa cum ar fi cazul. fi cazul într-un caz relațional.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2Folosind globale, este convenabil să creați o bază de date cu date despre oameni, atunci cand este important sa acumulam si sa sistematizam un maxim de informatii variate despre client. Acest lucru este solicitat în medicină, servicii bancare, marketing, arhivare și alte domenii

.
Desigur, în SQL puteți emula și un arbore cu doar câteva tabele (Extensie EAV, 1,2,3,4,5,6,7,8,9,10), cu toate acestea, acest lucru este semnificativ mai complicat și va fi mai lent. În esență, ar trebui să scrieți o globală care funcționează pe tabele și să ascundeți toată munca cu tabele sub un strat de abstractizare. Este greșit să emulați tehnologia de nivel inferior (global) folosind tehnologia de nivel superior (SQL). Nepotrivit.

Nu este un secret pentru nimeni că schimbarea schemei de date pe tabele gigantice (ALTER TABLE) poate dura destul de mult. MySQL, de exemplu, face ALTER TABLE ADD|DROP COLUMN prin copierea completă a informațiilor din tabelul vechi în tabelul nou (motoare MyISAM, InnoDB testate). Care poate bloca o bază de date funcțională cu miliarde de înregistrări zile, dacă nu săptămâni.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2Schimbarea structurii datelor dacă folosim globale nu ne costă nimic. În orice moment putem adăuga orice proprietăți noi de care avem nevoie oricărui obiect, la orice nivel al ierarhiei. Modificările asociate cu redenumirea ramurilor pot fi executate în fundal pe o bază de date care rulează.


Prin urmare, atunci când vine vorba de stocarea obiectelor cu un număr mare de proprietăți opționale, globalurile sunt o alegere excelentă.

Mai mult, permiteți-mi să vă reamintesc că accesul la oricare dintre proprietăți este instantaneu, deoarece în global toate căile sunt arbori B.

Bazele de date globale, în general, sunt un tip de bază de date orientată spre documente, cu capacitatea de a stoca informații ierarhice. Prin urmare, bazele de date orientate spre documente pot concura cu cele globale în domeniul stocării dosarelor medicale. Dar tot nu este chiar la felSă luăm MongoDB pentru comparație. În acest domeniu pierde în fața globală din următoarele motive:

  1. Dimensiunea documentului. Unitatea de stocare este text în format JSON (mai precis BSON) cu un volum maxim de aproximativ 16MB. Restricția a fost făcută special pentru ca baza de date JSON să nu încetinească în timpul analizei dacă un document JSON uriaș este stocat în ea și apoi accesat de câmpuri. Acest document trebuie să conțină toate informațiile despre pacient. Știm cu toții cât de groase pot fi dosarele pacienților. Dimensiunea maximă a cardului de 16 MB pune capăt imediat pacienților al căror card de boală include fișiere RMN, scanări cu raze X și alte studii. Într-o ramură a globalului puteți avea gigabytes și terabytes de informații. În principiu, putem pune capăt acestui lucru, dar voi continua.
  2. Timpul de conștiință/modificare/ștergere a noilor proprietăți în fișa pacientului. O astfel de bază de date trebuie să citească întreaga hartă în memorie (aceasta este o cantitate mare!), să analizeze BSON, să adauge/modifica/șterge un nou nod, să actualizeze indecși, să-l împacheteze în BSON și să-l salveze pe disc. Un global trebuie doar să acceseze o anumită proprietate și să o manipuleze.
  3. Acces rapid la proprietăți individuale. Cu multe proprietăți într-un document și structura sa pe mai multe niveluri, accesul la proprietățile individuale va fi mai rapid datorită faptului că fiecare cale din global este un arbore B. În BSON, trebuie să analizați liniar documentul pentru a găsi proprietatea dorită.

3.3.2 Matrice asociative

Matricele asociative (chiar și cu matrice imbricate) se potrivesc perfect pe globale. De exemplu, o astfel de matrice din PHP va fi afișată în prima imagine 3.3.1.

$a = array(
  "name" => "Vince Medvedev",
  "city" => "Moscow",
  "threatments" => array(
    "surgeries" => array("apedicectomy", "biopsy"),
    "radiation" => array("gamma", "x-rays"),
    "physiotherapy" => array("knee", "shoulder")
  )
);

3.3.3 Documente ierarhice: XML, JSON

De asemenea, ușor de stocat în global. Poate fi aranjat în diferite moduri pentru depozitare.

XML
Cel mai simplu mod de a descompune XML în global este de a stoca atributele etichetelor în noduri. Și dacă este nevoie de acces rapid la atributele etichetelor, atunci le putem muta în ramuri separate.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2

<note id=5>
<to>Вася</to>
<from>Света</from>
<heading>Напоминание</heading>
<body>Позвони мне завтра!</body>
</note>

Pe COS, aceasta ar corespunde codului:

Set ^xml("note")="id=5"
Set ^xml("note","to")="Саша"
Set ^xml("note","from")="Света"
Set ^xml("note","heading")="Напоминание"
Set ^xml("note","body")="Позвони мне завтра!"

observaţie: Pentru XML, JSON, tablouri asociative, puteți veni cu multe moduri diferite de afișare pe globale. În acest caz, nu am reflectat ordinea subetichetelor în eticheta notă. La nivel global ^xml subetichetele vor fi afișate în ordine alfabetică. Pentru a reflecta strict comanda, puteți utiliza, de exemplu, următorul afișaj:

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2
JSON.
Prima imagine din secțiunea 3.3.1 arată o reflectare a acestui document JSON:

var document = {
  "name": "Vince Medvedev",
  "city": "Moscow",
  "threatments": {
    "surgeries": ["apedicectomy", "biopsy"],
    "radiation": ["gamma", "x-rays"],
    "physiotherapy": ["knee", "shoulder"]
  },
};

3.3.4 Structuri identice legate prin relații ierarhice

Exemple: structura birourilor de vânzări, localizarea persoanelor într-o structură MLM, baza de date a deschiderilor la șah.

Baza de date de debut. Puteți utiliza estimarea forței de mișcare ca valoare a indexului global al nodului. Apoi, pentru a alege cea mai puternică mișcare, va fi suficient să alegeți ramura cu cea mai mare greutate. La nivel global, toate ramurile de la fiecare nivel vor fi sortate în funcție de puterea mișcării.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2

Structura birourilor de vânzări, structura oamenilor din MLM. Nodurile pot stoca anumite valori de stocare în cache care reflectă caracteristicile întregului subarbore. De exemplu, volumul vânzărilor unui subarbore dat. În orice moment putem obține o cifră care să reflecte realizările oricărei ramuri.

Globalurile sunt comori-sabii pentru stocarea datelor. Copaci. Partea 2

4. În ce cazuri este cel mai benefic să folosiți globale?

Prima coloană prezintă cazuri în care veți obține un câștig semnificativ de viteză prin utilizarea globalelor, iar a doua când designul sau modelul de date va fi simplificat.

Viteză
Ușurință în prelucrarea/prezentarea datelor

  1. Inserare [cu sortare automată la fiecare nivel], [indexare prin cheie principală]
  2. Înlăturarea subarborilor
  3. Obiecte cu o mulțime de proprietăți imbricate care necesită acces individual
  4. Structură ierarhică cu capacitatea de a ocoli ramurile copil din orice ramură, chiar și din cele inexistente
  5. Traversarea în adâncime a subarborilor
  1. Obiecte/entități cu un număr mare de proprietăți/entități opționale [și/sau imbricate].
  2. Date fără schemă. Când pot apărea adesea proprietăți noi și cele vechi dispar.
  3. Trebuie să creați o bază de date personalizată.
  4. Bazele căilor și arborii de decizie. Când este convenabil să reprezinte cărările ca un copac.
  5. Eliminarea structurilor ierarhice fără utilizarea recursiunii

Extensie „Globalurile sunt săbii de comori pentru stocarea datelor. Matrice rare. Partea 3".

Declinare a responsabilităţii: Acest articol și comentariile mele la acesta sunt părerea mea și nu au nicio legătură cu poziția oficială a InterSystems Corporation.

Sursa: www.habr.com

Adauga un comentariu