
3. Alternativ strukturer vid anvÀndning av globala variabler
En sÄdan struktur som ett ordnat trÀd har olika specifika fall. LÄt oss övervÀga de som har praktiskt vÀrde vid arbete med globala variabler.
3.1 Specifikt fall 1. En nod utan grenar
Globala variabler kan anvÀndas inte bara som en array, utan Àven som vanliga variabler. Till exempel som en rÀknare:
Set ^counter = 0 ; stÀlla in rÀknaren
Set id=$Increment(^counter) ; atomÀr inkrementeringI det hÀr fallet kan den globala variabeln, förutom vÀrdet, Àven ha grenar. Det ena utesluter inte det andra.
3.2 Specifikt fall 2. En topp och mÄnga grenar
Detta Àr i allmÀnhet en klassisk key-value databas. Om vi sparar en tuple av vÀrden som vÀrde, fÄr vi en helt vanlig tabell med en primÀrnyckel.

För att implementera en tabell pÄ globala variabler mÄste vi sjÀlva skapa strÀngar av kolumnernas vÀrden och sedan spara dem i den globala variabeln med primÀrnyckeln. För att kunna separera strÀngen tillbaka till kolumner vid lÀsning kan man anvÀnda:
- avgrÀnsande tecken.
Set ^t(id1) = "col11/col21/col31" Set ^t(id2) = "col12/col22/col32" - en strikt schema, dÀr varje fÀlt tar en förutbestÀmd mÀngd byte. Precis som det görs i relationella databaser.
- en speciell funktion $LB (finns i Cache) som bildar en strÀng av vÀrden.
Set ^t(id1) = $LB("col11", "col21", "col31") Set ^t(id2) = $LB("col12", "col22", "col32")
Intressant nog Àr det inte svÄrt att skapa nÄgot liknande sekundÀra index i relationella databaser pÄ globala variabler. LÄt oss kalla sÄdana strukturer indexglobala variabler. En indexglobal variabel Àr ett hjÀlpbjÀlke för snabb sökning baserat pÄ fÀlt som inte Àr en del av den primÀra nyckeln för den huvudsakliga globala variabeln. För att fylla och anvÀnda den mÄste man skriva ytterligare kod.
LÄt oss skapa en indexglobal variabel baserat pÄ den första kolumnen.
Set ^i("col11", id1) = 1
Set ^i("col12", id2) = 1Nu, för att snabbt söka efter information i den första kolumnen, behöver vi titta i den globala variabeln ^i och hitta de primÀra nycklarna (id) som motsvarar det önskade vÀrdet i den första kolumnen.
Vid insÀttning av vÀrden kan vi omedelbart skapa bÄde vÀrdet och indexglobala variabler för de nödvÀndiga fÀlten. Och för tillförlitlighet ska vi omsluta allt i en transaktion.
TSTART
Set ^t(id1) = $LB("col11", "col21", "col31")
Set ^i("col11", id1) = 1
TCOMMITDetaljer om hur man gör pÄ M , .
Tabeller som dessa kommer att fungera lika snabbt som i traditionella databaser (eller till och med snabbare), om man skriver in-funktioner / uppdaterings- / raderingsfunktioner i COS / M och kompilera dem.Jag har verifierat detta pÄstÄendet genom tester av massiva INSERT- och SELECT-operationer i en tvÄkolumnig tabell, inklusive anvÀndning av kommandon TSTART och TCOMMIT (transaktioner).
Jag har inte testat mer komplexa scenarier med samtidig Ätkomst och paralella transaktioner.
Utan att anvÀnda transaktioner var hastigheten för insÀttningar vid en miljon vÀrden 778 361 insÀttningar / sekund.
Vid 300 miljoner vĂ€rden â 422 141 insĂ€ttningar / sekund.
Vid anvĂ€ndning av transaktioner â 572 082 insĂ€ttningar / sekund pĂ„ 50M insĂ€ttningar. Alla operationer utfördes frĂ„n den kompilerade M-koden.
Vanliga hÄrddiskar, inte SSD. RAID5 med Write-back. Processor Phenom II 1100T.
För liknande test av SQL-databasen behöver man skriva en lagrad procedur som i en loop gör insÀttningar. Vid testning av MySQL 5.5 (lagring InnoDB) med denna metod fick jag siffror pÄ högst 11K insÀttningar per sekund.
Ja, implementeringen av tabeller pÄ globala resurser ser mer komplex ut Àn i relationella databaser. DÀrför har industriella databaser pÄ globala resurser SQL-Ätkomst för att förenkla arbetet med tabulÀr data.
Om datamodellen inte kommer att förÀndras ofta, Àr insÀttningshastigheten inte kritisk och hela databasen kan lÀtt representeras som normaliserade tabeller, Àr det enklare att arbeta med just SQL, eftersom det ger en högre abstraktionsnivÄ.
I detta specifika fall ville jag visa att globala resurser kan fungera som en konstruktor för att skapa andra databaser. Som assembler som man kan skriva andra sprÄk pÄ. HÀr Àr exempel pÄ hur man kan skapa analoger pÄ globala resurser
Om man behöver skapa nÄgon icke-standarddatabas med minimal anstrÀngning, bör man titta mot globala resurser.
3.3 Specifikt fall 3. TvÄnivÄtrÀd, dÀr varje nod pÄ andra nivÄn har ett fast antal grenar
Ni har förmodligen gissat: detta Àr ett alternativt genomförande av tabeller pÄ globala resurser. LÄt oss jÀmföra detta genomförande med det tidigare.
Tabeller pÄ ett tvÄnivÄtrÀd vs. ett ennivÄtrÀd.
Nackdelar
Fördelar
- LÄngsammare vid insÀttning, eftersom antalet noder mÄste stÀllas in till antalet kolumner.
- Mer diskanvÀndning. Eftersom globala index (i betydelse som index för arrayer) med kolumnnamn tar upp plats pÄ disken och dupliceras för varje rad.
- Snabbare Ätkomst till vÀrden i individuella kolumner, eftersom det inte behövs nÄgon parsing av raden. Enligt mina tester Àr det snabbare med 11,5% för 2 kolumner och mer med ett större antal kolumner.
- Enklare att Àndra dataskeman
- Tydligare kod
Slutsats: Àven om det Àr en smaksak. Eftersom hastighet Àr en av de viktigaste fördelarna med globala index, finns det nÀstan ingen poÀng med att anvÀnda denna implementation, eftersom den troligtvis inte kommer att vara snabbare Àn tabeller i relationsdatabaser.
3.4 AllmÀnna fall. TrÀd och ordnade trÀd
All struktur av data som kan representeras som ett trÀd passar perfekt för globala index.
3.4.1 Objekt med delobjekt

Detta Àr den traditionella tillÀmpningsomrÄdet för globala index. Inom sjukvÄrden finns ett stort antal sjukdomar, mediciner, symptom och behandlingsmetoder. Att skapa en tabell för varje patient med en miljon fÀlt Àr oekonomiskt. Speciellt eftersom 99% av fÀlten kommer att vara tomma.
FörestÀll dig en SQL-databas med tabeller: "patient" ~ 100 000 fÀlt, "medicin" - 100 000 fÀlt, "terapi" - 100 000 fÀlt, "komplikationer" - 100 000 fÀlt osv. Alternativt kan man skapa en databas av tusentals tabeller, var och en för en specifik typ av patient (de kan överlappa!), behandling, medicin, och ytterligare tusentals tabeller för relationer mellan dessa tabeller.
Globala index passar perfekt för medicin, eftersom de gör det möjligt att skapa en noggrann beskrivning av varje patients sjukdomshistorik, olika terapier och lÀkemedelsverkan, i form av ett trÀd, utan att slösa onödig diskplats pÄ tomma kolumner, som det skulle vara i ett relationsfall.
Det Àr enkelt att skapa databaser med information om mÀnniskor med globala index, nÀr det Àr viktigt att samla in och systematisera sÄ mycket olika information som möjligt om klienten. Detta Àr efterfrÄgat inom medicin, bankverksamhet, marknadsföring, arkivhantering och andra omrÄden.
.
SjÀlvklart kan man ocksÄ emulera ett trÀd i SQL med endast nÄgra tabeller (, ,,,,,,,,,), men det Àr mycket mer komplicerat och kommer att fungera lÄngsammare. I sjÀlva verket skulle man behöva skriva globala funktioner som fungerar pÄ tabeller och dölja allt arbete med tabeller under ett lager av abstraktion. Det Àr fel att emulera en lÀgre nivÄsteknologi (globaler) med hjÀlp av en högre nivÄsteknologi (SQL). Oekonomiskt.
Det Àr ingen hemlighet att Àndra databasstrukturen pÄ gigantiska tabeller (ALTER TABLE) kan ta en anstÀndig tid. MySQL, till exempel, gör ALTER TABLE ADD|DROP COLUMN genom att kopiera all information frÄn den gamla till den nya tabellen (jag har testat motorer som MyISAM, InnoDB). Detta kan stÀnga ner en arbetsdatabas med miljarder poster i dagar, om inte veckor.
Att Ă€ndra databasstrukturen, om vi anvĂ€nder globaler, kostar oss ingenting. NĂ€r som helst kan vi lĂ€gga till alla nödvĂ€ndiga nya egenskaper till vilket objekt som helst, pĂ„ vilken nivĂ„ av hierarkin som helst. Ăndringar som rör omdöpning av grenar kan köras i bakgrunden pĂ„ en aktiv databas.
DÀrför Àr globaler ett utmÀrkt val nÀr det gÀller lagring av objekt med en stor mÀngd valfria egenskaper.
Och jag pÄminner om att tillgÄngen till varje egenskap Àr omedelbar, eftersom alla vÀgar i globalen representerar ett B-trÀd.
Databaser i globaler Àr i allmÀnhet en typ av dokumentorienterade databaser, med möjlighet till lagring av hierarkisk information. DÀrför kan dokumentorienterade databaser konkurrera med globaler inom omrÄdet lagring av medicinska kort. Men det Àr fortfarande inte riktigt det.LÄt oss ta, till exempel, MongoDB som en jÀmförelse. I detta omrÄde förlorar den mot globaler av följande skÀl:
- Dokumentets storlek. Lagrenheten Àr text i JSON-format (eller snarare BSON) med en maximal storlek pÄ cirka 16 MB. BegrÀnsningen Àr gjord avsiktligt för att JSON-databasen inte ska bli lÄngsam vid parsning, om den lagrar ett stort JSON-dokument och senare kommer att Ätkomma det via fÀlt. I detta dokument bör all information om patienten vara koncentrerad. Vi vet alla hur tjocka patientkort kan vara. Den maximala storleken pÄ 16 MB sÀtter snabbt stopp för patienter vars sjukdomskort innefattar MRT-filer, röntgenbilder och andra studier. I en gren av en global kan man dock ha information pÄ gigabytes och terabytes. I princip skulle man kunna sÀtta punkt hÀr, men jag fortsÀtter.
- Tiden för medvetenhet/Àndring/borttagning av nya egenskaper i patientkortet. En sÄdan databas mÄste ladda hela patientkortet i minnet (vilket Àr en stor mÀngd!), analysera BSON, lÀgga till/Àndra/ta bort en ny nod, uppdatera index, packa i BSON och spara pÄ disk. Globalen behöver Ä sin sida bara referera till en specifik egenskap och utföra manipulationer med den.
- à tkomsthastighet till individuella egenskaper. Vid mÄnga egenskaper i dokumentet och dess flernivÄstruktur kommer Ätkomsten till individuella egenskaper att vara snabbare eftersom varje vÀg i globalen Àr en B-tree. I BSON mÄste dokumentet analyseras linjÀrt för att hitta den erforderliga egenskapen.
3.3.2 Associativa arrayer
Associativa arrayer (Àven med inbÀddade arrayer) passar utmÀrkt för globaler. Till exempel kommer en sÄdan array frÄn PHP att visas i den första bilden 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 Hierarkiska dokument: XML, JSON
Dessa lagras ocksÄ enkelt i globaler. För lagring kan ordnas pÄ olika sÀtt.
XML
Det enklaste sÀttet att ordna XML i globaler Àr nÀr vi lagrar taggens attribut i noder. Om snabb Ätkomst till taggens attribut behövs kan vi lÀgga ut dem i separata grenar.

<note id="5">
<to>Vasya</to>
<from>Svetlana</from>
<heading>Påminnelse</heading>
<body>Ring mig imorgon!</body>
</note>I COS kommer koden att se ut sÄ hÀr:
Set ^xml("note")="id=5"
Set ^xml("note","to")="Sasha"
Set ^xml("note","from")="Sveta"
Set ^xml("note","heading")="PÄminnelse"
Set ^xml("note","body")="Ring mig imorgon!"AnmÀrkning: För XML, JSON, associativa arrayer kan mÄnga olika sÀtt att representera dem i globaler hittas. I detta fall har vi inte Ätergivit ordningen av inbÀddade taggar i taggen note. I globalen ^xml inbÀddade taggar kommer att visas i alfabetisk ordning. För att strikt Äterge ordningen kan ett sÄdant arrangemang anvÀndas:

JSON.
Den första bilden i avsnitt 3.3.1 visar Ätergivningen av detta JSON-dokument:
var document = {
"name": "Vince Medvedev",
"city": "Moscow",
"treatments": {
"surgeries": ["apedicectomy", "biopsy"],
"radiation": ["gamma", "x-rays"],
"physiotherapy": ["knee", "shoulder"]
},
};3.3.4 Liknande strukturer kopplade med hierarkiska relationer
Exempel: struktur av försÀljningskontor, positionering av mÀnniskor i MLM-struktur, databas av schacköppningar.
Databas av öppningar. Som man kan anvÀnda nodindex för globaler Àr bedömningen av dragstyrkan. DÄ rÀcker det att vÀlja grenen med högst vikt för att vÀlja det starkaste draget. I globalen kommer alla grenar pÄ varje nivÄ att sorteras efter dragets styrka.

Strukturen för försÀljningskontor, strukturen för mÀnniskor i MLM. I noder kan man lagra vissa cachade vÀrden som reflekterar egenskaperna hos hela undertrÀdet. Till exempel försÀljningsvolymen för detta undertrÀd. Vid vilken tidpunkt som helst kan vi fÄ en siffra som visar prestationerna för vilken gren som helst.

4. I vilka fall Àr det mest lönsamt att anvÀnda globaler.
I den första kolumnen presenteras fall dÀr du fÄr betydande vinster i hastighet genom att anvÀnda globaler, och i den andra nÀr utvecklingen eller datamodellen förenklas.
Hastighet
BekvÀmlighet vid hantering/visning av data.
- Infogning [med automatisk sortering pÄ varje nivÄ], [indexering efter huvudnyckel].
- Borttagning av undertrÀd.
- Objekt med en mÀngd inbÀddade egenskaper som krÀver individuell Ätkomst.
- Hierarkisk struktur med möjlighet att traversera dottergrenar frÄn vilken gren som helst, Àven om den inte existerar.
- Traversering av undertrÀd i djupet.
- Objekt/entiteter med ett enormt antal valfria [och/eller inbÀddade] egenskaper/entiteter.
- Schemafria data. NÀr nya egenskaper ofta kan tillkomma och gamla försvinna.
- Det behövs för att skapa en icke-standard databas.
- StigenÀt och beslutstrÀd. NÀr vÀgar Àr lÀmpliga att representera som trÀd.
- Borttagning av hierarkiska strukturer utan att anvÀnda rekursion.
FortsÀttning .
Ansvarsfriskrivning: Denna artikel och mina kommentarer till den Àr min Äsikt och har ingen koppling till företagets officiella stÀllning, InterSystems.
KĂ€lla: habr.com
