3. Varianty štruktúr pri použití globálov
Štruktúra, akou je napríklad usporiadaný strom, má rôzne špeciálne prípady. Zoberme si tie, ktoré majú praktickú hodnotu pri práci s globálnymi.
3.1 Špeciálny prípad 1. Jeden uzol bez vetiev
Globálne hodnoty možno použiť nielen ako pole, ale aj ako bežné premenné. Napríklad ako počítadlo:
Set ^counter = 0 ; установка счётчика
Set id=$Increment(^counter) ; атомарное инкрементирование
V tomto prípade môže mať globálne okrem svojho významu aj pobočky. Jedno nevylučuje druhé.
3.2 Špeciálny prípad 2. Jeden vrchol a veľa vetiev
Vo všeobecnosti ide o klasický kľúč – hodnota. A ak uložíme n-ticu hodnôt ako hodnotu, dostaneme veľmi obyčajnú tabuľku s primárnym kľúčom.
Aby sme implementovali tabuľku na globals, budeme musieť sami vygenerovať riadky z hodnôt stĺpcov a potom ich uložiť do globálneho pomocou primárneho kľúča. Aby bolo možné reťazec pri čítaní opäť rozdeliť na stĺpce, môžete použiť:
- oddeľovacie znaky.
Set ^t(id1) = "col11/col21/col31" Set ^t(id2) = "col12/col22/col32"
- pevná schéma, v ktorej každé pole zaberá vopred určený počet bajtov. Ako sa to robí v relačných databázach.
- špeciálna funkcia $LB (dostupná v Cache), ktorá vytvára reťazec hodnôt.
Set ^t(id1) = $LB("col11", "col21", "col31") Set ^t(id2) = $LB("col12", "col22", "col32")
Zaujímavé je, že nie je ťažké použiť globals na niečo podobné ako sekundárne indexy v relačných databázach. Nazvime takéto štruktúry indexové globálne. Globálny index je pomocný strom na rýchle vyhľadávanie polí, ktoré nie sú súčasťou primárneho kľúča hlavného globálneho. Ak ho chcete vyplniť a použiť, musíte napísať dodatočný kód.
V prvom stĺpci vytvoríme globálny index.
Set ^i("col11", id1) = 1
Set ^i("col12", id2) = 1
Ak chcete rýchlo vyhľadať informácie v prvom stĺpci, musíme sa pozrieť do globálneho ^i a nájdite primárne kľúče (id) zodpovedajúce požadovanej hodnote prvého stĺpca.
Pri vkladaní hodnoty môžeme okamžite vytvoriť globálne hodnoty aj indexy pre požadované polia. A kvôli spoľahlivosti to všetko zabalíme do transakcie.
TSTART
Set ^t(id1) = $LB("col11", "col21", "col31")
Set ^i("col11", id1) = 1
TCOMMIT
Podrobnosti o tom, ako to urobiť na M
Takéto tabuľky budú fungovať tak rýchlo ako v tradičných databázach (alebo ešte rýchlejšie), ak sú funkcie na vkladanie/aktualizáciu/vymazávanie riadkov napísané v COS/M a skompilované.Toto vyhlásenie som skontroloval testami hromadného INSERT a SELECT do jednej dvojstĺpcovej tabuľky, vrátane použitia príkazov TSTART a TCOMMIT (transakcie).
Netestoval som zložitejšie scenáre so súbežným prístupom a paralelnými transakciami.
Bez použitia transakcií bola rýchlosť vkladania 778 361 vložení za sekundu na milión hodnôt.
S 300 miliónmi hodnôt - 422 141 vložení za sekundu.
Pri použití transakcií - 572 082 vložiek za sekundu pre 50 miliónov vložiek. Všetky operácie boli vykonané z skompilovaného M kódu.
Pevné disky sú bežné, nie SSD. RAID5 so spätným zápisom. Procesor Phenom II 1100T.
Ak chcete otestovať databázu SQL podobným spôsobom, musíte napísať uloženú procedúru, ktorá bude vykonávať vkladanie v slučke. Pri testovaní MySQL 5.5 (úložisko InnoDB) som pomocou tejto metódy dostal čísla nie viac ako 11 XNUMX vložení za sekundu.
Áno, implementácia tabuliek na globals vyzerá zložitejšie ako v relačných databázach. Preto majú priemyselné databázy na globals prístup SQL na zjednodušenie práce s tabuľkovými údajmi.
Vo všeobecnosti, ak sa schéma údajov nebude často meniť, rýchlosť vkladania nie je kritická a celá databáza môže byť ľahko reprezentovaná vo forme normalizovaných tabuliek, potom je jednoduchšie pracovať s SQL, pretože poskytuje vyššiu úroveň abstrakcie. .
V tomto konkrétnom prípade som to chcel ukázať globals môžu pôsobiť ako konštruktor na vytváranie iných databáz. Ako assembler, v ktorom je možné písať iné jazyky. Tu sú príklady toho, ako môžete vytvoriť analógy na globáloch
Ak potrebujete vytvoriť nejaký druh neštandardnej databázy s minimálnym úsilím, mali by ste sa pozrieť na globálne.
3.3 Špeciálny prípad 3. Dvojúrovňový strom, každý uzol druhej úrovne má pevný počet vetiev
Pravdepodobne ste uhádli: ide o alternatívnu implementáciu tabuliek na globals. Porovnajme túto implementáciu s predchádzajúcou.
Stoly na dvojúrovňovom strome vs. na jednoúrovňovom strome.
Zápory
Pros
- Pomalšie vkladanie, pretože musíte nastaviť počet uzlov rovný počtu stĺpcov.
- Väčšia spotreba miesta na disku. Pretože globálne indexy (chápané ako indexy polí) s názvami stĺpcov zaberajú miesto na disku a sú duplikované pre každý riadok.
- Rýchlejší prístup k hodnotám jednotlivých stĺpcov, pretože nie je potrebné analyzovať reťazec. Podľa mojich testov je o 11,5% rýchlejší na 2 stĺpcoch a viac na väčšom počte stĺpcov.
- Jednoduchšia zmena dátovej schémy
- Jasnejší kód
Záver: nie pre každého. Keďže rýchlosť je jednou z najdôležitejších výhod globals, nemá zmysel používať túto implementáciu, pretože s najväčšou pravdepodobnosťou nebude fungovať rýchlejšie ako tabuľky v relačných databázach.
3.4 Všeobecný prípad. Stromy a objednané stromy
Akákoľvek dátová štruktúra, ktorá môže byť reprezentovaná ako strom, sa dokonale hodí k globálom.
3.4.1 Objekty s podpredmetmi
Toto je oblasť tradičného používania globálov. V oblasti medicíny existuje obrovské množstvo chorôb, liekov, symptómov a liečebných metód. Je iracionálne vytvárať tabuľku s miliónom políčok pre každého pacienta. Okrem toho bude 99% polí prázdnych.
Predstavte si SQL databázu tabuliek: „pacient“ ~ 100 000 polí, „Medicína“ - 100 000 polí, „Terapia“ - 100 000 polí, „Komplikácie“ - 100 000 polí atď. a tak ďalej. Alebo môžete vytvoriť databázu mnohých tisíc tabuliek, každú pre špecifický typ pacienta (a môžu sa prekrývať!), liečby, lieky a tisíce ďalších tabuliek na prepojenie medzi týmito tabuľkami.
Globals sú ideálne pre medicínu, pretože vám umožňujú vytvoriť pre každého pacienta presný popis jeho anamnézy, rôznych terapií a účinkov liekov vo forme stromu bez toho, aby ste zbytočne míňali miesto na disku v prázdnych stĺpcoch, ako by to bolo byť prípad vo vzťahovom prípade.
Pomocou globals je vhodné vytvoriť databázu s údajmi o ľuďoch, kedy je dôležité zhromaždiť a systematizovať maximum rôznych informácií o klientovi. To je žiadané v medicíne, bankovníctve, marketingu, archívnictve a ďalších oblastiach
.
Samozrejme, v SQL môžete tiež emulovať strom s niekoľkými tabuľkami (
Nie je žiadnym tajomstvom, že zmena dátovej schémy na obrovských tabuľkách (ALTER TABLE) môže trvať pomerne dlho. MySQL napríklad robí ALTER TABLE ADD|DROP COLUMN úplným skopírovaním informácií zo starej tabuľky do novej tabuľky (testované motory MyISAM, InnoDB). Čo môže zavesiť fungujúcu databázu s miliardami záznamov na dni, ak nie týždne.
Zmena štruktúry údajov, ak používame globals, nás nič nestojí. Kedykoľvek môžeme pridať akékoľvek nové vlastnosti, ktoré potrebujeme k akémukoľvek objektu, na akejkoľvek úrovni hierarchie. Zmeny spojené s premenovaním vetiev je možné spustiť na pozadí v spustenej databáze.
Preto, pokiaľ ide o ukladanie objektov s obrovským množstvom voliteľných vlastností, sú globals skvelou voľbou.
Okrem toho mi dovoľte pripomenúť, že prístup ku ktorejkoľvek z vlastností je okamžitý, pretože v globále sú všetky cesty B-stromy.
Globálne databázy sú vo všeobecnosti typom databázy orientovanej na dokumenty so schopnosťou uchovávať hierarchické informácie. Preto databázy orientované na dokumenty môžu v oblasti uchovávania zdravotných záznamov konkurovať svetovým. Ale stále to nie je úplne onoNa porovnanie si zoberme MongoDB. V tejto doméne prehráva s globálnymi z nasledujúcich dôvodov:
- Veľkosť dokumentu. Úložnou jednotkou je text vo formáte JSON (presnejšie BSON) s maximálnym objemom cca 16MB. Obmedzenie bolo urobené špeciálne preto, aby sa databáza JSON nespomalila počas analýzy, ak je v nej uložený obrovský dokument JSON a potom k nemu pristupujú polia. Tento dokument by mal obsahovať všetky informácie o pacientovi. Všetci vieme, aké hrubé môžu byť záznamy o pacientoch. Maximálna veľkosť karty 16 MB okamžite ukončí prácu pacientov, ktorých karta choroby obsahuje súbory MRI, röntgenové snímky a ďalšie štúdie. V jednej vetve globálnej môžete mať gigabajty a terabajty informácií. V zásade to môžeme ukončiť, ale budem pokračovať.
- Čas vedomia/zmeny/vymazania nových vlastností v tabuľke pacienta. Takáto databáza musí načítať celú mapu do pamäte (to je veľké množstvo!), analyzovať BSON, pridať/zmeniť/vymazať nový uzol, aktualizovať indexy, zabaliť do BSON a uložiť na disk. Globálny potrebuje iba prístup ku konkrétnej vlastnosti a manipulovať s ňou.
- Rýchly prístup k jednotlivým nehnuteľnostiam. S mnohými vlastnosťami v dokumente a jeho viacúrovňovou štruktúrou bude prístup k jednotlivým vlastnostiam rýchlejší vďaka tomu, že každá cesta v globále je B-strom. V BSON musíte lineárne analyzovať dokument, aby ste našli požadovanú vlastnosť.
3.3.2 Asociatívne polia
Asociatívne polia (dokonca aj s vnorenými poľami) sa dokonale hodia na globály. Napríklad také pole z PHP sa zobrazí na prvom obrázku 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 Hierarchické dokumenty: XML, JSON
Tiež ľahko uložené v globáloch. Na uskladnenie sa dá rozložiť rôznymi spôsobmi.
XML
Najjednoduchší spôsob, ako rozložiť XML na globály, je uložiť atribúty značiek do uzlov. A ak je potrebný rýchly prístup k atribútom značiek, môžeme ich presunúť do samostatných vetiev.
<note id=5>
<to>Вася</to>
<from>Света</from>
<heading>Напоминание</heading>
<body>Позвони мне завтра!</body>
</note>
Na COS by to zodpovedalo kódu:
Set ^xml("note")="id=5"
Set ^xml("note","to")="Саша"
Set ^xml("note","from")="Света"
Set ^xml("note","heading")="Напоминание"
Set ^xml("note","body")="Позвони мне завтра!"
komentár: Pre XML, JSON, asociatívne polia môžete prísť s mnohými rôznymi spôsobmi zobrazenia na globáloch. V tomto prípade sme nezohľadnili poradie podznačiek v značke poznámky. Globálne ^xml podznačky sa zobrazia v abecednom poradí. Na presné vyjadrenie objednávky môžete použiť napríklad nasledujúce zobrazenie:
JSON.
Prvý obrázok zo sekcie 3.3.1 ukazuje odraz tohto dokumentu JSON:
var document = {
"name": "Vince Medvedev",
"city": "Moscow",
"threatments": {
"surgeries": ["apedicectomy", "biopsy"],
"radiation": ["gamma", "x-rays"],
"physiotherapy": ["knee", "shoulder"]
},
};
3.3.4 Identické štruktúry spojené hierarchickými vzťahmi
Príklady: štruktúra obchodných zastúpení, umiestnenie ľudí v štruktúre MLM, databáza otvorov v šachu.
Databáza debutov. Odhad sily zdvihu môžete použiť ako hodnotu indexu globálneho uzla. Potom, aby ste vybrali najsilnejší ťah, bude stačiť vybrať vetvu s najväčšou hmotnosťou. V globále budú všetky pobočky na každej úrovni zoradené podľa sily pohybu.
Štruktúra obchodných zastúpení, štruktúra ľudí v MLM. Uzly môžu ukladať určité hodnoty vyrovnávacej pamäte, ktoré odrážajú charakteristiky celého podstromu. Napríklad objem predaja daného podstromu. V každom okamihu môžeme získať číslo, ktoré odráža úspechy akéhokoľvek odvetvia.
4. V akých prípadoch je najvýhodnejšie použiť globals?
Prvý stĺpec predstavuje prípady, kedy použitím globalov dosiahnete výrazné zvýšenie rýchlosti a druhý, keď sa zjednoduší návrh alebo dátový model.
Rýchlosť
Jednoduchosť spracovania/prezentácie údajov
- Vkladanie [s automatickým triedením na každej úrovni], [indexovanie podľa hlavného kľúča]
- Odstránenie podstromov
- Objekty s množstvom vnorených vlastností, ktoré vyžadujú individuálny prístup
- Hierarchická štruktúra so schopnosťou obísť detské vetvy z akejkoľvek vetvy, dokonca aj neexistujúcej
- Prechod podstromov do hĺbky
- Objekty/entity s veľkým počtom voliteľných [a/alebo vnorených] vlastností/entít
- Údaje bez schémy. Keď sa často môžu objaviť nové vlastnosti a staré zaniknúť.
- Musíte vytvoriť vlastnú databázu.
- Základy ciest a rozhodovacie stromy. Kedy je vhodné reprezentovať cesty ako strom.
- Odstránenie hierarchických štruktúr bez použitia rekurzie
Predĺženie
Vylúčenie zodpovednosti: Tento článok a moje komentáre k nemu sú mojím názorom a nesúvisia s oficiálnym stanoviskom InterSystems Corporation.
Zdroj: hab.com