Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2Aan de slag - zie deel 1.

3. Varianten van structuren bij gebruik van globale waarden

Een structuur zoals een geordende boom kent verschillende bijzondere gevallen. Laten we eens kijken naar de onderwerpen die van praktische waarde zijn bij het werken met globals.

3.1 Speciaal geval 1. Eén knooppunt zonder vertakkingen


Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2Globalen kunnen niet alleen als array worden gebruikt, maar ook als reguliere variabelen. Als teller bijvoorbeeld:

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

In dit geval kan het globale, naast zijn betekenis, ook vertakkingen hebben. Het een sluit het ander niet uit.

3.2 Speciaal geval 2. Eén hoekpunt en veel vertakkingen

Over het algemeen is dit een klassieke sleutel-waardebasis. En als we een tupel waarden als waarde opslaan, krijgen we een heel gewone tabel met een primaire sleutel.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2

Om een ​​tabel met globale waarden te implementeren, zullen we zelf rijen moeten genereren uit de kolomwaarden en deze vervolgens opslaan in de globale tabel met behulp van de primaire sleutel. Om het mogelijk te maken de string bij het lezen weer in kolommen te verdelen, kun je gebruik maken van:

  1. scheidingstekens.
    Set ^t(id1) = "col11/col21/col31"
    Set ^t(id2) = "col12/col22/col32"
  2. een rigide schema waarin elk veld een vooraf bepaald aantal bytes beslaat. Zoals dat gebeurt in relationele databases.
  3. een speciale functie $LB (beschikbaar in Cache), die een reeks waarden creëert.
    Set ^t(id1) = $LB("col11", "col21", "col31")
    Set ^t(id2) = $LB("col12", "col22", "col32")

Interessant genoeg is het niet moeilijk om globale waarden te gebruiken om iets te doen dat lijkt op secundaire indexen in relationele databases. Laten we dergelijke structuren indexglobalen noemen. Een globale index is een hulpboom waarmee u snel in velden kunt zoeken die geen deel uitmaken van de primaire sleutel van de globale hoofdsleutel. Om het in te vullen en te gebruiken, moet u aanvullende code schrijven.

Laten we een globale index maken in de eerste kolom.

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

Om snel naar informatie in de eerste kolom te zoeken, moeten we nu naar het globale kijken ^i en zoek de primaire sleutels (id) die overeenkomen met de gewenste waarde van de eerste kolom.

Bij het invoegen van een waarde kunnen we onmiddellijk zowel de waarde- als de indexglobalen voor de vereiste velden maken. En laten we, voor de betrouwbaarheid, alles in één transactie verpakken.

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

Details over hoe u dit kunt doen op M tabellen over globale cijfers, emulatie van secundaire indexen.

Dergelijke tabellen werken net zo snel als in traditionele databases (of zelfs sneller) als de functies voor het invoegen/bijwerken/verwijderen van rijen in COS/M worden geschreven en gecompileerd.Ik heb deze verklaring gecontroleerd met tests op bulk INSERT en SELECT in één tabel met twee kolommen, inclusief het gebruik van de TSTART- en TCOMMIT-opdrachten (transacties).

Ik heb geen complexere scenario's getest met gelijktijdige toegang en parallelle transacties.

Zonder gebruik te maken van transacties bedroeg het invoegpercentage 778 invoegingen/seconde per miljoen waarden.
Met 300 miljoen waarden - 422 inserts/seconde.

Bij gebruik van transacties - 572 invoegingen/seconde voor 082 miljoen invoegingen. Alle bewerkingen werden uitgevoerd vanuit gecompileerde M-code.
Harde schijven zijn gewone schijven, geen SSD. RAID5 met terugschrijven. Phenom II 1100T-processor.

Om een ​​SQL-database op een vergelijkbare manier te testen, moet u een opgeslagen procedure schrijven die invoegingen in een lus uitvoert. Bij het testen van MySQL 5.5 (InnoDB-opslag) ontving ik met deze methode getallen van niet meer dan 11K inserts per seconde.
Ja, de implementatie van tabellen op globale gegevens ziet er complexer uit dan in relationele databases. Daarom hebben industriële databases op globals SQL-toegang om het werken met tabelgegevens te vereenvoudigen.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2Als het gegevensschema niet vaak verandert, de invoegsnelheid niet kritisch is en de gehele database gemakkelijk kan worden weergegeven in de vorm van genormaliseerde tabellen, is het in het algemeen gemakkelijker om met SQL te werken, omdat dit een hoger abstractieniveau biedt. .

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2In dit specifieke geval wilde ik dat laten zien globals kunnen fungeren als constructor voor het maken van andere databases. Zoals een assembler waarin andere talen geschreven kunnen worden. Hier zijn voorbeelden van hoe u analogen op globale waarden kunt maken sleutelwaarde-, lijsten, sets, tabellarische, documentgeoriënteerde databases.

Als je met minimale inspanning een soort niet-standaard database moet maken, dan moet je naar globals kijken.

3.3 Speciaal geval 3. Boom met twee niveaus, elk knooppunt van het tweede niveau heeft een vast aantal vertakkingen

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2Je raadt het waarschijnlijk al: dit is een alternatieve implementatie van tabellen over globale getallen. Laten we deze implementatie vergelijken met de vorige.

Tabellen op een boom met twee niveaus vs. op een boom met één niveau.

Tegens
Voors

  1. Langzamer voor invoeging, omdat u het aantal knooppunten gelijk moet stellen aan het aantal kolommen.
  2. Meer schijfruimteverbruik. Omdat globale indexen (opgevat als array-indexen) met kolomnamen schijfruimte in beslag nemen en voor elke rij worden gedupliceerd.

  1. Snellere toegang tot de waarden van individuele kolommen, omdat het niet nodig is om de string te parseren. Volgens mijn tests is het 11,5% sneller op 2 kolommen en meer op een groter aantal kolommen.
  2. Gemakkelijker om het gegevensschema te wijzigen
  3. Duidelijkere code

Conclusie: niet voor iedereen. Omdat snelheid een van de belangrijkste voordelen van globals is, heeft het weinig zin om deze implementatie te gebruiken, aangezien deze hoogstwaarschijnlijk niet sneller zal presteren dan tabellen in relationele databases.

3.4 Algemeen geval. Bomen en geordende bomen

Elke datastructuur die als een boom kan worden weergegeven, past perfect bij globalen.

3.4.1 Objecten met subobjecten

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2

Dit is het gebied van traditioneel gebruik van globals. Op medisch gebied is er een groot aantal ziekten, medicijnen, symptomen en behandelmethoden. Het is irrationeel om voor elke patiënt een tabel te maken met een miljoen velden. Bovendien zal 99% van de velden leeg zijn.

Stel je een SQL-database met tabellen voor: "patiënt" ~ 100 velden, "Geneeskunde" - 000 velden, "Therapie" - 100 velden, "Complicaties" - 000 velden, enz. enzovoort. Of u kunt een database maken met vele duizenden tabellen, elk voor een specifiek type patiënt (en ze kunnen elkaar overlappen!), behandelingen, medicijnen en duizenden andere tabellen voor verbindingen tussen deze tabellen.

Globals zijn ideaal voor de geneeskunde, omdat u hiermee voor elke patiënt een nauwkeurige beschrijving van zijn medische geschiedenis, verschillende therapieën en de werking van medicijnen kunt maken, in de vorm van een boom, zonder extra schijfruimte te verspillen aan lege kolommen, zoals zou gebeuren het geval zijn in een relationeel geval.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2Met behulp van globals is het handig om een ​​database aan te maken met gegevens over mensen, wanneer het belangrijk is om een ​​maximum aan verschillende informatie over de klant te verzamelen en te systematiseren. Hier is veel vraag naar in de geneeskunde, het bankwezen, marketing, archivering en andere gebieden

.
Natuurlijk kun je in SQL ook een boom emuleren met slechts een paar tabellen (EAV, 1,2,3,4,5,6,7,8,9,10), maar dit is aanzienlijk ingewikkelder en zal langzamer zijn. In wezen zou je een globale versie moeten schrijven die op tabellen werkt en al het werk met tabellen onder een abstractielaag moeten verbergen. Het is verkeerd om technologie op een lager niveau (globals) te emuleren met behulp van technologie op een hoger niveau (SQL). Ongepast.

Het is geen geheim dat het wijzigen van het gegevensschema op gigantische tabellen (ALTER TABLE) behoorlijk wat tijd kan kosten. MySQL doet bijvoorbeeld ALTER TABLE ADD|DROP COLUMN door informatie volledig van de oude tabel naar de nieuwe tabel te kopiëren (geteste MyISAM-, InnoDB-engines). Waardoor een werkende database met miljarden records dagen, zo niet weken kan blijven hangen.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2Het veranderen van de datastructuur als we globals gebruiken, kost ons niets. We kunnen op elk moment nieuwe eigenschappen toevoegen aan elk object, op elk niveau van de hiërarchie. Wijzigingen die verband houden met het hernoemen van vertakkingen kunnen op de achtergrond worden uitgevoerd in een actieve database.


Daarom zijn globals een goede keuze als het gaat om het opslaan van objecten met een groot aantal optionele eigenschappen.

Bovendien wil ik u eraan herinneren dat de toegang tot elk van de eigenschappen onmiddellijk is, aangezien in de globale paden alle paden B-bomen zijn.

Globale databases zijn over het algemeen een soort documentgeoriënteerde database met de mogelijkheid om hiërarchische informatie op te slaan. Daarom kunnen documentgeoriënteerde databases concurreren met mondiale databases op het gebied van het opslaan van medische dossiers. Maar het is nog steeds niet helemaal hetzelfdeLaten we MongoDB nemen ter vergelijking. In dit domein het verliest van de globals om de volgende redenen:

  1. Documentgrootte. De opslageenheid is tekst in JSON-formaat (meer bepaald BSON) met een maximaal volume van ongeveer 16 MB. De beperking is specifiek gemaakt zodat de JSON-database tijdens het parseren niet langzamer gaat werken als er een enorm JSON-document in wordt opgeslagen en vervolgens door velden wordt geopend. Dit document moet alle informatie over de patiënt bevatten. We weten allemaal hoe dik patiëntendossiers kunnen zijn. De maximale kaartgrootte van 16 MB maakt onmiddellijk een einde aan patiënten van wie de ziektekaart MRI-bestanden, röntgenscans en andere onderzoeken bevat. In één tak van de wereld kun je gigabytes en terabytes aan informatie hebben. In principe kunnen we hier een einde aan maken, maar ik ga door.
  2. Tijdstip van bewustzijn/verandering/verwijdering van nieuwe eigenschappen in het patiëntendossier. Zo'n database moet de volledige kaart in het geheugen lezen (dit is een grote hoeveelheid!), BSON parseren, een nieuw knooppunt toevoegen/wijzigen/verwijderen, indexen bijwerken, deze in BSON inpakken en op schijf opslaan. Een global hoeft alleen toegang te krijgen tot een specifieke eigenschap en deze te manipuleren.
  3. Snelle toegang tot individuele eigendommen. Met veel eigenschappen in een document en de structuur met meerdere niveaus zal de toegang tot individuele eigenschappen sneller zijn vanwege het feit dat elk pad in het globale een B-boom is. In BSON moet u het document lineair ontleden om de gewenste eigenschap te vinden.

3.3.2 Associatieve arrays

Associatieve arrays (zelfs met geneste arrays) passen perfect op globalen. Een dergelijke array uit PHP wordt bijvoorbeeld weergegeven in de eerste afbeelding 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 Hiërarchische documenten: XML, JSON

Ook gemakkelijk op te slaan in globals. Kan op verschillende manieren worden ingedeeld voor opslag.

XML
De eenvoudigste manier om XML in globalen op te splitsen is door tag-attributen in knooppunten op te slaan. En als snelle toegang tot tagkenmerken nodig is, kunnen we deze naar afzonderlijke vertakkingen verplaatsen.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2

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

Op COS zou dit overeenkomen met de code:

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

Commentaar: Voor XML, JSON en associatieve arrays kun je veel verschillende manieren bedenken om op globale waarden weer te geven. In dit geval hebben we de volgorde van de subtags in de notitietag niet weergegeven. Wereldwijd ^xml subtags worden in alfabetische volgorde weergegeven. Om de volgorde strikt weer te geven, kunt u bijvoorbeeld de volgende weergave gebruiken:

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2
JSON.
De eerste afbeelding uit paragraaf 3.3.1 toont een weerspiegeling van dit JSON-document:

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

3.3.4 Identieke structuren verbonden door hiërarchische relaties

Voorbeelden: de structuur van verkoopkantoren, de locatie van mensen in een MLM-structuur, de database met openingen in het schaakspel.

Debuteert database. U kunt de schatting van de slagkracht gebruiken als de indexwaarde van het globale knooppunt. Om vervolgens de sterkste zet te kiezen, is het voldoende om de tak met het grootste gewicht te kiezen. Op mondiaal niveau worden alle takken op elk niveau gesorteerd op bewegingssterkte.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2

De structuur van verkoopkantoren, de structuur van mensen in MLM. Knooppunten kunnen bepaalde cachingwaarden opslaan die de kenmerken van de gehele subboom weerspiegelen. Bijvoorbeeld het verkoopvolume van een bepaalde subboom. Op elk moment kunnen we een cijfer krijgen dat de prestaties van welke branche dan ook weerspiegelt.

Globals zijn schatzwaarden voor het opslaan van gegevens. Bomen. Deel 2

4. In welke gevallen is het het nuttigst om globale cijfers te gebruiken?

De eerste kolom presenteert gevallen waarin u een aanzienlijke snelheidswinst zult behalen door globals te gebruiken, en de tweede waarin het ontwerp of het datamodel wordt vereenvoudigd.

snelheid
Gemak van gegevensverwerking/presentatie

  1. Invoeging [met automatische sortering op elk niveau], [indexering via hoofdsleutel]
  2. Subbomen verwijderen
  3. Objecten met veel geneste eigenschappen waarvoor individuele toegang vereist is
  4. Hiërarchische structuur met de mogelijkheid om onderliggende vertakkingen van elke vertakking te omzeilen, zelfs niet-bestaande
  5. Diepte-eerste doorgang van subbomen
  1. Objecten/entiteiten met een groot aantal optionele [en/of geneste] eigenschappen/entiteiten
  2. Schemaloze gegevens. Wanneer er vaak nieuwe eigendommen kunnen verschijnen en oude verdwijnen.
  3. U moet een aangepaste database maken.
  4. Padbasissen en beslisbomen. Wanneer het handig is om paden als een boom weer te geven.
  5. Hiërarchische structuren verwijderen zonder gebruik te maken van recursie

Uitbreiding “Globals zijn schatzwaarden voor het opslaan van gegevens. Schaarse arrays. Deel 3".

Disclaimer: Dit artikel en mijn commentaar daarop zijn mijn mening en hebben geen betrekking op het officiële standpunt van InterSystems Corporation.

Bron: www.habr.com

Voeg een reactie