
3. Variationen der Struktur bei der Verwendung von Globals
Eine Struktur wie ein geordnetes Baumdiagramm hat verschiedene spezielle FĂ€lle. Betrachten wir die, die praktischen Nutzen bei der Arbeit mit Globals haben.
3.1 Spezialfall 1. Ein Knoten ohne Ăste
Globals können nicht nur wie ein Array, sondern auch wie normale Variablen verwendet werden. Zum Beispiel als ZÀhler:
Set ^counter = 0 ; ZĂ€hler setzen
Set id=$Increment(^counter) ; atomar inkrementierenDabei kann der Global, neben dem Wert, auch Ăste besitzen. Das Eine schlieĂt das Andere nicht aus.
3.2 Spezialfall 2. Ein Knoten und viele Ăste
Im Grunde handelt es sich um eine klassische Key-Value-Datenbank. Wenn wir als Wert ein Tupel von Werten speichern, erhalten wir die ganz gewöhnliche Tabelle mit einem PrimĂ€rschlĂŒssel.

Um eine Tabelle in Globals zu realisieren, mĂŒssen wir selbst die Zeilen aus den Werten der Spalten bilden und sie dann im Global nach dem PrimĂ€rschlĂŒssel speichern. Um beim Auslesen die Zeile wieder in Spalten aufteilen zu können, können wir verwenden:
- Trennzeichen.
Set ^t(id1) = "col11/col21/col31" Set ^t(id2) = "col12/col22/col32" - ein striktes Schema, bei dem jedes Feld eine vordefinierte Anzahl von Bytes belegt, wie es auch in relationalen Datenbanken gemacht wird.
- eine spezielle Funktion $LB (verfĂŒgbar in Cache), die eine Zeichenkette aus Werten erstellt.
Set ^t(id1) = $LB("col11", "col21", "col31") Set ^t(id2) = $LB("col12", "col22", "col32")
Interessant ist, dass es auf globalen Variablen nicht schwierig ist, etwas Ăhnliches wie sekundĂ€re Indizes in relationalen Datenbanken zu erstellen. Wir nennen solche Strukturen Index-Globals. Ein Index-Global ist ein Hilfsbaum fĂŒr eine schnelle Suche nach Feldern, die keine Bestandteile des PrimĂ€rschlĂŒssels des Hauptglobals sind. Um ihn zu fĂŒllen und zu nutzen, muss zusĂ€tzlicher Code geschrieben werden.
Lassen Sie uns einen Index-Global fĂŒr die erste Spalte erstellen.
Set ^i("col11", id1) = 1
Set ^i("col12", id2) = 1Jetzt mĂŒssen wir fĂŒr eine schnelle Informationssuche in der ersten Spalte in den Globalen sehen ^i und die PrimĂ€rschlĂŒssel (id) finden, die dem gewĂŒnschten Wert der ersten Spalte entsprechen.
Beim EinfĂŒgen eines Wertes können wir sofort sowohl den Wert als auch die Index-Globals fĂŒr die benötigten Felder erstellen. Zur Sicherheit verpacken wir das alles in eine Transaktion.
TSTART
Set ^t(id1) = $LB("col11", "col21", "col31")
Set ^i("col11", id1) = 1
TCOMMITDetails, wie man es in M macht , .
Diese Tabellen arbeiten ebenso schnell wie in traditionellen DBs (oder sogar schneller), wenn die Funktionen zum EinfĂŒgen/Ăndern/Löschen von Zeilen in COS/M geschrieben und kompiliert werden.Diese Aussage habe ich durch Tests mit massiven INSERT- und SELECT-Befehlen in einer zweispaltigen Tabelle ĂŒberprĂŒft, einschlieĂlich der Nutzung von TSTART- und TCOMMIT-Befehlen (Transaktionen).
Komplexere Szenarien mit konkurrierendem Zugriff und parallelen Transaktionen wurden nicht getestet.
Ohne Nutzung von Transaktionen lag die EinfĂŒgeschwindigkeit bei einer Million Werten bei 778.361 EinfĂŒgungen/Sekunde.
Bei 300 Millionen Werten â 422.141 EinfĂŒgungen/Sekunde.
Bei der Nutzung von Transaktionen â 572.082 EinfĂŒgungen/Sekunde bei 50 Millionen EinfĂŒgungen. Alle Operationen wurden aus kompiliertem M-Code durchgefĂŒhrt.
Es wurden gewöhnliche Festplatten verwendet, keine SSDs. RAID5 mit Write-back. Prozessor Phenom II 1100T.
FĂŒr vergleichbare Tests einer SQL-Datenbank muss eine gespeicherte Prozedur geschrieben werden, die in einer Schleife EinfĂŒgungen durchfĂŒhrt. Bei Tests mit MySQL 5.5 (InnoDB-Store) erhielt ich nicht mehr als 11.000 EinfĂŒgungen pro Sekunde.
Ja, die Implementierung von Tabellen in Global-DBs erscheint komplizierter als in relationalen Datenbanken. Daher bieten industrielle Datenbanken mit Global-DBs SQL-Zugriff, um die Arbeit mit tabellarischen Daten zu erleichtern.
Wenn das Datenschema also nicht hĂ€ufig geĂ€ndert wird, die EinfĂŒgeschwindigkeit nicht kritisch ist und die gesamte Datenbank leicht in normalisierte Tabellen dargestellt werden kann, ist es einfacher, mit SQL zu arbeiten, da es ein höheres Abstraktionsniveau bietet.
In diesem speziellen Fall wollte ich zeigen, dass Global-DBs als BaukĂ€sten zur Erstellung anderer Datenbanken dienen können.Wie ein Assembler, auf dem man andere Sprachen schreiben kann. Hier sind Beispiele, wie man in Global-DBs Entsprechungen schaffen kann fĂŒr
Wenn eine nicht standardmĂ€Ăige Datenbank mit minimalem Aufwand erstellt werden soll, lohnt es sich, einen Blick auf Global-DBs zu werfen.
3.3 Spezialfall 3. Zweistufiger Baum, bei dem jeder Knoten der zweiten Ebene eine fixe Anzahl von Zweigen hat.
Sie haben wahrscheinlich erraten: Das ist eine alternative Implementierung von Tabellen in Global-DBs. Lassen Sie uns diese Implementierung mit der vorherigen vergleichen.
Tabellen in einem zweistufigen Baum vs. in einem einstufigen Baum.
Nachteile
Vorteile
- Langsame EinfĂŒgung, da die Anzahl der zu installierenden Knoten der Anzahl der Spalten entsprechen muss.
- Höherer Speicherplatzverbrauch. Da globale Indizes (in dem Sinne wie Array-Indizes) mit Spaltennamen Platz auf der Festplatte beanspruchen und fĂŒr jede Zeile dupliziert werden.
- Schnellerer Zugriff auf die Werte einzelner Spalten, da die Zeile nicht geparst werden muss. Laut meinen Tests ist der Zugriff auf 2 Spalten um 11,5% schneller, und bei einer höheren Anzahl von Spalten noch schneller.
- Einfacherer Wechsel des Datenschemas.
- Anschaulicherer Code.
Fazit: FĂŒr Liebhaber. Da Geschwindigkeit eines der wesentlichen Vorteile von Globals ist, macht es kaum Sinn, diese Implementierung zu nutzen, da sie wahrscheinlich nicht schneller als Tabellen in relationalen Datenbanken arbeitet.
3.4 Allgemeiner Fall. BĂ€ume und geordnete BĂ€ume.
Jede Datenstruktur, die als Baum dargestellt werden kann, eignet sich hervorragend fĂŒr Globals.
3.4.1 Objekte mit Unterobjekten.

Dies ist ein traditioneller Anwendungsbereich fĂŒr Globals. Im medizinischen Bereich gibt es eine riesige Anzahl an Krankheiten, Medikamenten, Symptomen und Behandlungsmethoden. Eine Tabelle mit einer Million Feldern fĂŒr jeden Patienten zu erstellen, ist ineffizient. Zumal 99% der Felder leer bleiben wĂŒrden.
Stellen Sie sich eine SQL-Datenbank aus Tabellen vor: âPatientâ ~ 100.000 Felder, âMedikamentâ â 100.000 Felder, âTherapieâ â 100.000 Felder, âKomplikationenâ â 100.000 Felder usw. Man könnte auch eine Datenbank aus vielen Tausenden von Tabellen erstellen, jede fĂŒr einen bestimmten Patiententyp (die sich ĂŒberschneiden können!), Behandlung, Medikament und noch Tausende von Tabellen fĂŒr die Verbindungen zwischen diesen Tabellen.
Globale Variablen sind ideal fĂŒr die Medizin, da sie es ermöglichen, fĂŒr jeden Patienten eine prĂ€zise Beschreibung seiner Krankengeschichte, verschiedener Therapien und Medikamentenwirkungen in Form eines Baums zu erstellen, ohne dabei ĂŒberflĂŒssigen Speicherplatz fĂŒr leere Spalten zu verschwenden, wie es im relationalen Fall der Fall wĂ€re.
Es ist bequem, mit globalen Variablen Datenbanken mit Informationen ĂŒber Menschen zu erstellen,wenn es wichtig ist, eine maximale Vielfalt an Informationen ĂŒber den Kunden zu sammeln und zu systematisieren. Dies ist in der Medizin, im Bankwesen, im Marketing, im Archivwesen und in anderen Bereichen gefragt.
.
NatĂŒrlich kann man auch mit SQL einen Baum nur mit wenigen Tabellen emulieren (, ,,,,,,,,,), jedoch ist dies erheblich komplizierter und wird langsamer funktionieren. Im Grunde mĂŒsste man globale Datenstrukturen erstellen, die auf Tabellen basieren, und die gesamte Tabellenverarbeitung hinter einer Abstraktionsschicht verbergen. Es ist nicht korrekt, eine technologie mit niedrigerem Niveau (Globale) mit Mitteln einer höherstufigen Technologie (SQL) zu emulieren. Das ist ineffizient.
Es ist kein Geheimnis, dass die Ănderung des Datenbankschemas auf riesigen Tabellen (ALTER TABLE) erheblich Zeit in Anspruch nehmen kann. MySQL zum Beispiel fĂŒhrt ALTER TABLE ADD|DROP COLUMN durch vollstĂ€ndiges Kopieren der Informationen aus der alten in die neue Tabelle aus (ich habe die Engines MyISAM und InnoDB getestet). Das kann eine Produktionsdatenbank mit Milliarden von DatensĂ€tzen fĂŒr Tage, wenn nicht Wochen, lahmlegen.
Die Ănderung der Datenstruktur, wenn wir globale Datenstrukturen verwenden, kostet uns nichts. Jederzeit können wir neue Eigenschaften zu jedem Objekt auf jeder Hierarchieebene hinzufĂŒgen, die wir benötigen. Ănderungen, die das Umbenennen von Zweigen betreffen, können im Hintergrund auf einer aktiven Datenbank durchgefĂŒhrt werden.
Deshalb sind globale Datenstrukturen eine ausgezeichnete Wahl, wenn es um die Speicherung von Objekten mit einer enormen Anzahl an optionalen Eigenschaften geht.
Ich erinnere daran, dass der Zugang zu jeder der Eigenschaften sofort erfolgt, da im Globalen alle Wege B-BĂ€ume sind.
Datenbanken in den Globalen sind im Allgemeinen eine Art dokumentenbasierter Datenbanken, die die Speicherung hierarchischer Informationen ermöglichen. Daher können dokumentenbasierte Datenbanken im Bereich der Speicherung von medizinischen Akten mit den Globalen konkurrieren. Aber das ist immer noch nicht ganz das.Nehmen wir zum Vergleich beispielsweise MongoDB. In diesem Bereich verliert sie gegenĂŒber den Globalen aus folgenden GrĂŒnden:
- Die GröĂe des Dokuments. Die Speichereinheit ist ein Text im JSON-Format (genauer gesagt BSON) mit einem maximalen Volumen von etwa 16 MB. Diese Begrenzung wurde absichtlich eingefĂŒhrt, um sicherzustellen, dass die JSON-Datenbank beim Parsen nicht ins Stocken gerĂ€t, wenn darin ein riesiges JSON-Dokument gespeichert wird und man spĂ€ter auf die Felder zugreift. In diesem Dokument sollte alle Informationen ĂŒber den Patienten gesammelt werden. Wir wissen alle, wie dick die Patientenakten sein können. Die maximale GröĂe von 16 MB schlieĂt Patienten aus, deren Krankheitsakte MRT-Dateien, Röntgenaufnahmen und andere Untersuchungen enthĂ€lt. In einem Branch kann man jedoch Informationen im Umfang von Gigabytes und Terabytes speichern. An sich könnte man hier aufhören, aber ich werde fortfahren.
- Zeit fĂŒr Bewusstsein/Ănderungen/Löschungen neuer Eigenschaften in der Patientenakte. Eine solche Datenbank muss die gesamte Akte in den Speicher laden (das ist ein groĂer Umfang!), das BSON parsen, einen neuen Knoten hinzufĂŒgen/Ă€ndern/löschen, die Indizes aktualisieren, in BSON packen und auf der Festplatte speichern. Dem Globalen reicht es jedoch, nur auf eine bestimmte Eigenschaft zuzugreifen und mit ihr zu arbeiten.
- Zugriffsgeschwindigkeit auf einzelne Eigenschaften. Bei einer Vielzahl von Eigenschaften in einem Dokument und seiner mehrstufigen Struktur ist der Zugriff auf einzelne Eigenschaften schneller, da jeder Pfad im globalen Bereich ein B-Baum ist. In BSON hingegen muss das Dokument linear geparst werden, um die benötigte Eigenschaft zu finden.
3.3.2 Assoziative Arrays
Assoziative Arrays (auch mit verschachtelten Arrays) lassen sich hervorragend in globale Bereiche abbilden. Ein solches Array aus PHP wird in der ersten Abbildung 3.3.1 dargestellt.
$a = array(
"name" => "Vince Medvedev",
"city" => "Moskau",
"threatments" => array(
"surgeries" => array("Apendektomie", "Biopsie"),
"radiation" => array("Gamma", "Röntgen"),
"physiotherapy" => array("Knie", "Schulter")
)
);3.3.3 Hierarchische Dokumente: XML, JSON
Lassen sich ebenfalls leicht in globalen Bereichen speichern. FĂŒr die Speicherung können verschiedene Anordnungen verwendet werden.
XML
Der einfachste Weg, XML in globale Bereiche zu gliedern, besteht darin, die Attribute der Tags in den Knoten zu speichern. Wenn ein schneller Zugriff auf die Tag-Attribute erforderlich ist, können wir diese in separate Zweige auslagern.

<note id="5">
<to>Vasya</to>
<from>Licht</from>
<heading>Erinnerung</heading>
<body>Ruf mich morgen an!</body>
</note>Im COS entspricht dies dem folgenden Code:
Set ^xml("note")="id=5"
Set ^xml("note","to")="Sasha"
Set ^xml("note","from")="Sveta"
Set ^xml("note","heading")="Erinnerung"
Set ^xml("note","body")="Ruf mich morgen an!"Hinweis: FĂŒr XML, JSON und assoziative Arrays gibt es viele verschiedene Möglichkeiten, sie in Globals darzustellen. In diesem Fall haben wir die Reihenfolge der verschachtelten Tags im Tag note nicht reflektiert. In der Globale. ^xml Verschachtelte Tags werden alphabetisch angezeigt. FĂŒr eine strikte Reflektion der Reihenfolge kann beispielsweise diese Darstellung verwendet werden:

JSON.
Im ersten Bild aus Abschnitt 3.3.1 wird die Darstellung dieses JSON-Dokuments gezeigt:
var document = {
"name": "Vince Medvedev",
"city": "Moscow",
"threatments": {
"surgeries": ["Apedektomie", "Biopsie"],
"radiation": ["Gamma", "Röntgen"],
"physiotherapy": ["Knie", "Schulter"]
},
};3.3.4 Gleiche Strukturen mit hierarchischen Beziehungen
Beispiele: Struktur von VerkaufsbĂŒros, Anordnung von Personen in einer MLM-Struktur, Datenbank von Schacheröffnungen.
Datenbank von Eröffnungen. Als Wert des Knoteninex im Global kann die Bewertung der ZugstĂ€rke verwendet werden. Dann reicht es aus, den Ast mit dem höchsten Gewicht zu wĂ€hlen, um den stĂ€rksten Zug auszuwĂ€hlen. In der Global werden alle Ăste auf jeder Ebene nach ZugstĂ€rke sortiert.

Struktur von VerkaufsbĂŒros, Struktur der Menschen in MLM. In den Knoten können bestimmte zwischengespeicherte Werte gespeichert werden, die die Merkmale des gesamten Teilbaums widerspiegeln. Zum Beispiel das Verkaufsvolumen dieses Teilbaums. Zu jeder Zeit können wir eine Zahl abrufen, die die Erfolge eines beliebigen Zweigs darstellt.

4. In welchen FĂ€llen ist die Verwendung von Globals am vorteilhaftesten?
In der ersten Spalte sind die FĂ€lle aufgefĂŒhrt, in denen Sie einen erheblichen Geschwindigkeitsgewinn durch die Verwendung von Globals erzielen, und in der zweiten, wann die Entwicklung oder das Datenmodell vereinfacht wird.
Geschwindigkeit
Komfort bei der Verarbeitung/PrÀsentation von Daten
- EinfĂŒgen [mit automatischer Sortierung auf jeder Ebene], [indizierung nach dem HauptschlĂŒssel]
- Entfernen von TeilbÀumen
- Objekte mit einer Vielzahl von verschachtelten Eigenschaften, die individuellen Zugriff benötigen
- Hierarchische Struktur mit der Möglichkeit, untergeordnete Zweige von jedem, sogar nicht existierenden, aus zu durchlaufen
- Durchlaufen von TeilbÀumen in der Tiefe
- Objekte/EntitÀten mit einer riesigen Anzahl von optionalen [und/oder verschachtelten] Eigenschaften/EntitÀten
- Schemafreie Daten (schema-less). Wenn hÀufig neue Eigenschaften auftauchen und alte verschwinden können.
- Es muss eine nicht standardisierte Datenbank erstellt werden.
- Datenbank von Pfaden und EntscheidungsbÀumen. Wenn Wege bequem in Form eines Baums dargestellt werden.
- Entfernung von hierarchischen Strukturen ohne Rekursion
Fortsetzung .
Haftungsausschluss: Dieser Artikel und meine Kommentare dazu spiegeln meine persönliche Meinung wider und stehen nicht im Zusammenhang mit der offiziellen Position der InterSystems Corporation.
Quelle: habr.com
