Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2Erste Schritte – siehe Teil 1.

3. Varianten von Strukturen bei der Verwendung von Globals

Eine Struktur wie ein geordneter Baum hat verschiedene Sonderfälle. Betrachten wir diejenigen, die bei der Arbeit mit Globals einen praktischen Wert haben.

3.1 Sonderfall 1. Ein Knoten ohne Zweige


Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2Globals können nicht nur wie ein Array, sondern auch wie reguläre Variablen verwendet werden. Als Zähler zum Beispiel:

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

In diesem Fall kann das Globale neben seiner Bedeutung auch Verzweigungen haben. Das eine schließt das andere nicht aus.

3.2 Sonderfall 2. Ein Knoten und viele Zweige

Im Allgemeinen handelt es sich hierbei um eine klassische Schlüssel-Wert-Basis. Und wenn wir ein Tupel von Werten als Wert speichern, erhalten wir eine ganz normale Tabelle mit einem Primärschlüssel.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2

Um eine Tabelle mit Globals zu implementieren, müssen wir selbst Zeilen aus den Spaltenwerten generieren und diese dann mithilfe des Primärschlüssels im Global speichern. Um den String beim Lesen wieder in Spalten aufteilen zu können, können Sie Folgendes verwenden:

  1. Trennzeichen.
    Set ^t(id1) = "col11/col21/col31"
    Set ^t(id2) = "col12/col22/col32"
  2. ein starres Schema, bei dem jedes Feld eine vorgegebene Anzahl von Bytes belegt. Wie es in relationalen Datenbanken der Fall ist.
  3. eine spezielle Funktion $LB (verfügbar im Cache), die eine Zeichenfolge von Werten erstellt.
    Set ^t(id1) = $LB("col11", "col21", "col31")
    Set ^t(id2) = $LB("col12", "col22", "col32")

Interessanterweise ist es nicht schwierig, Globals zu verwenden, um etwas Ähnliches wie Sekundärindizes in relationalen Datenbanken zu tun. Nennen wir solche Strukturen Index-Globals. Ein Index-Global ist ein Hilfsbaum zum schnellen Durchsuchen von Feldern, die nicht Teil des Primärschlüssels des Haupt-Global sind. Um es auszufüllen und zu verwenden, müssen Sie zusätzlichen Code schreiben.

Erstellen wir einen globalen Index für die erste Spalte.

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

Um nun schnell nach Informationen in der ersten Spalte zu suchen, müssen wir einen Blick ins Globale werfen ^i und finden Sie die Primärschlüssel (id), die dem gewünschten Wert der ersten Spalte entsprechen.

Beim Einfügen eines Werts können wir sofort sowohl den Wert als auch den Index global für die erforderlichen Felder erstellen. Und aus Gründen der Zuverlässigkeit fassen wir alles in einer Transaktion zusammen.

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

Details zur Vorgehensweise bei M Tabellen zu Globals, Emulation von Sekundärindizes.

Solche Tabellen funktionieren genauso schnell wie in herkömmlichen Datenbanken (oder sogar schneller), wenn die Funktionen zum Einfügen/Aktualisieren/Löschen von Zeilen in COS/M geschrieben und kompiliert werden.Ich habe diese Anweisung mit Tests zu Massen-INSERT und SELECT in einer zweispaltigen Tabelle überprüft, einschließlich der Verwendung der Befehle TSTART und TCOMMIT (Transaktionen).

Komplexere Szenarien mit gleichzeitigem Zugriff und parallelen Transaktionen habe ich nicht getestet.

Ohne die Verwendung von Transaktionen betrug die Einfügungsrate 778 Einfügungen/Sekunde pro Million Werte.
Bei 300 Millionen Werten – 422 Einfügungen/Sekunde.

Bei Verwendung von Transaktionen – 572 Einfügungen/Sekunde für 082 Millionen Einfügungen. Alle Operationen wurden mit kompiliertem M-Code ausgeführt.
Festplatten sind normal, keine SSD. RAID5 mit Write-Back. Phenom II 1100T-Prozessor.

Um eine SQL-Datenbank auf ähnliche Weise zu testen, müssen Sie eine gespeicherte Prozedur schreiben, die Einfügungen in einer Schleife durchführt. Beim Testen von MySQL 5.5 (InnoDB-Speicher) habe ich mit dieser Methode Zahlen mit nicht mehr als 11 Einfügungen pro Sekunde erhalten.
Ja, die Implementierung von Tabellen auf Globals sieht komplexer aus als in relationalen Datenbanken. Daher verfügen Industriedatenbanken auf Globals über SQL-Zugriff, um die Arbeit mit Tabellendaten zu vereinfachen.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2Wenn sich das Datenschema nicht häufig ändert, die Einfügegeschwindigkeit nicht kritisch ist und die gesamte Datenbank problemlos in Form normalisierter Tabellen dargestellt werden kann, ist es im Allgemeinen einfacher, mit SQL zu arbeiten, da es eine höhere Abstraktionsebene bietet .

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2In diesem speziellen Fall wollte ich das zeigen Globals können als Konstruktor zum Erstellen anderer Datenbanken fungieren. Wie ein Assembler, in dem andere Sprachen geschrieben werden können. Hier finden Sie Beispiele dafür, wie Sie Analoga zu Globals erstellen können Schlüsselwert, Listen, Mengen, tabellarische, dokumentenorientierte Datenbanken.

Wenn Sie mit minimalem Aufwand eine nicht standardmäßige Datenbank erstellen müssen, sollten Sie sich für Globals entscheiden.

3.3 Sonderfall 3. Zweistufiger Baum, jeder Knoten der zweiten Ebene hat eine feste Anzahl von Zweigen

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2Sie haben es wahrscheinlich erraten: Dies ist eine alternative Implementierung von Tabellen auf Globals. Vergleichen wir diese Implementierung mit der vorherigen.

Tabellen in einem zweistufigen Baum vs. auf einem einstufigen Baum.

Cons
Pros

  1. Langsameres Einfügen, da Sie die Anzahl der Knoten gleich der Anzahl der Spalten festlegen müssen.
  2. Mehr Speicherplatzverbrauch. Da globale Indizes (als Array-Indizes verstanden) mit Spaltennamen Speicherplatz beanspruchen und für jede Zeile dupliziert werden.

  1. Schnellerer Zugriff auf die Werte einzelner Spalten, da kein Parsen der Zeichenfolge erforderlich ist. Laut meinen Tests ist es bei 11,5 Spalten 2 % schneller und bei einer größeren Anzahl von Spalten mehr.
  2. Einfachere Änderung des Datenschemas
  3. Klarerer Code

Fazit: nicht für jeden. Da Geschwindigkeit einer der größten Vorteile von Globals ist, macht die Verwendung dieser Implementierung wenig Sinn, da sie höchstwahrscheinlich nicht schneller als Tabellen in relationalen Datenbanken sein wird.

3.4 Allgemeiner Fall. Bäume und geordnete Bäume

Jede Datenstruktur, die als Baum dargestellt werden kann, passt perfekt zu Globals.

3.4.1 Objekte mit Unterobjekten

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2

Dies ist der Bereich der traditionellen Verwendung von Globals. Im medizinischen Bereich gibt es eine Vielzahl von Krankheiten, Medikamenten, Symptomen und Behandlungsmethoden. Es ist irrational, für jeden Patienten eine Tabelle mit einer Million Feldern zu erstellen. Darüber hinaus sind 99 % der Felder leer.

Stellen Sie sich eine SQL-Datenbank mit Tabellen vor: „Patient“ – 100 Felder, „Medizin“ – 000 Felder, „Therapie“ – 100 Felder, „Komplikationen“ – 000 Felder usw. usw. Oder Sie können eine Datenbank mit vielen Tausend Tabellen erstellen, jede für einen bestimmten Patiententyp (und sie können sich überschneiden!), Behandlungen, Medikamenten und Tausenden weiterer Tabellen für Verbindungen zwischen diesen Tabellen.

Globals sind ideal für die Medizin, da sie es Ihnen ermöglichen, für jeden Patienten eine genaue Beschreibung seiner Krankengeschichte, verschiedener Therapien und der Wirkung von Medikamenten in Form eines Baums zu erstellen, ohne wie sonst zusätzlichen Speicherplatz für leere Spalten zu verschwenden in einem relationalen Fall der Fall sein.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2Mithilfe von Globals ist es praktisch, eine Datenbank mit Daten über Personen zu erstellen, wenn es wichtig ist, möglichst viele verschiedene Informationen über den Kunden zu sammeln und zu systematisieren. Dies ist in der Medizin, im Bankwesen, im Marketing, in der Archivierung und anderen Bereichen gefragt

.
Natürlich kann man in SQL auch einen Baum mit nur wenigen Tabellen emulieren (EAV, 1,2,3,4,5,6,7,8,9,10), allerdings ist dies deutlich komplizierter und wird langsamer sein. Im Wesentlichen müssten Sie ein globales Programm schreiben, das mit Tabellen arbeitet, und die gesamte Arbeit mit Tabellen unter einer Abstraktionsschicht verbergen. Es ist falsch, Technologien auf niedrigerer Ebene (Globals) mithilfe von Technologien auf höherer Ebene (SQL) zu emulieren. Unangemessen.

Es ist kein Geheimnis, dass das Ändern des Datenschemas auf riesigen Tabellen (ALTER TABLE) ziemlich viel Zeit in Anspruch nehmen kann. MySQL führt beispielsweise ALTER TABLE ADD|DROP COLUMN durch, indem es Informationen vollständig aus der alten Tabelle in die neue Tabelle kopiert (getestete MyISAM- und InnoDB-Engines). Dadurch kann eine funktionierende Datenbank mit Milliarden von Datensätzen tagelang, wenn nicht sogar wochenlang lahmgelegt werden.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2Das Ändern der Datenstruktur, wenn wir Globals verwenden, kostet uns nichts. Wir können jederzeit jedem Objekt auf jeder Ebene der Hierarchie neue Eigenschaften hinzufügen, die wir benötigen. Mit dem Umbenennen von Zweigen verbundene Änderungen können im Hintergrund in einer laufenden Datenbank ausgeführt werden.


Wenn es darum geht, Objekte mit einer großen Anzahl optionaler Eigenschaften zu speichern, sind Globals eine gute Wahl.

Darüber hinaus möchte ich Sie daran erinnern, dass der Zugriff auf alle Eigenschaften sofort erfolgt, da im globalen Kontext alle Pfade B-Bäume sind.

Globale Datenbanken sind im Allgemeinen eine Art dokumentenorientierte Datenbank mit der Möglichkeit, hierarchische Informationen zu speichern. Daher können dokumentenorientierte Datenbanken im Bereich der Speicherung von Krankenakten mit globalen Unternehmen konkurrieren. Aber es ist immer noch nicht ganz dasselbeNehmen wir zum Vergleich MongoDB. In dieser Domäne Es verliert aus folgenden Gründen gegen die Globals:

  1. Dokumentgröße. Die Speichereinheit ist Text im JSON-Format (genauer BSON) mit einem maximalen Volumen von etwa 16 MB. Die Einschränkung wurde speziell vorgenommen, damit die JSON-Datenbank beim Parsen nicht langsamer wird, wenn ein großes JSON-Dokument darin gespeichert ist und dann über Felder darauf zugegriffen wird. Dieses Dokument sollte alle Informationen über den Patienten enthalten. Wir alle wissen, wie umfangreich Patientenakten sein können. Die maximale Kartengröße von 16 MB macht Schluss mit Patienten, deren Krankheitskarte MRT-Dateien, Röntgenaufnahmen und andere Untersuchungen enthält. In einem Zweig der Welt können Gigabyte und Terabyte an Informationen vorhanden sein. Im Prinzip können wir dem ein Ende setzen, aber ich werde weitermachen.
  2. Zeitpunkt der Bewusstwerdung/Änderung/Löschung neuer Eigenschaften in der Patientenakte. Eine solche Datenbank muss die gesamte Karte in den Speicher einlesen (das ist eine große Menge!), BSON analysieren, einen neuen Knoten hinzufügen/ändern/löschen, Indizes aktualisieren, sie in BSON packen und auf der Festplatte speichern. Ein Global muss nur auf eine bestimmte Eigenschaft zugreifen und diese bearbeiten.
  3. Schneller Zugriff auf einzelne Immobilien. Bei vielen Eigenschaften in einem Dokument und seiner mehrstufigen Struktur ist der Zugriff auf einzelne Eigenschaften schneller, da jeder Pfad im globalen Verzeichnis ein B-Baum ist. In BSON müssen Sie das Dokument linear analysieren, um die gewünschte Eigenschaft zu finden.

3.3.2 Assoziative Arrays

Assoziative Arrays (auch mit verschachtelten Arrays) passen perfekt auf globale Arrays. Ein solches Array aus PHP wird beispielsweise im ersten Bild 3.3.1 angezeigt.

$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 Hierarchische Dokumente: XML, JSON

Lässt sich auch problemlos in Globals speichern. Kann zur Aufbewahrung unterschiedlich ausgelegt werden.

XML
Der einfachste Weg, XML in Globale zu zerlegen, besteht darin, Tag-Attribute in Knoten zu speichern. Und wenn ein schneller Zugriff auf Tag-Attribute erforderlich ist, können wir diese in separate Zweige verschieben.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2

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

Auf COS würde dies dem Code entsprechen:

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

Hinweis: Für XML, JSON und assoziative Arrays können Sie viele verschiedene Möglichkeiten zur Anzeige auf Globals finden. In diesem Fall haben wir die Reihenfolge der Untertags im Notiz-Tag nicht wiedergegeben. Global ^xml Untertags werden in alphabetischer Reihenfolge angezeigt. Um die Reihenfolge genau wiederzugeben, können Sie beispielsweise die folgende Anzeige verwenden:

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2
JSON.
Das erste Bild aus Abschnitt 3.3.1 zeigt eine Reflexion dieses JSON-Dokuments:

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

3.3.4 Identische Strukturen, verbunden durch hierarchische Beziehungen

Beispiele: die Struktur von Verkaufsbüros, der Standort von Personen in einer MLM-Struktur, die Datenbank mit Eröffnungen im Schach.

Debütdatenbank. Sie können die Hubkraftschätzung als Indexwert des globalen Knotens verwenden. Um dann den stärksten Zug auszuwählen, reicht es aus, den Zweig mit dem größten Gewicht auszuwählen. Auf globaler Ebene werden alle Zweige auf jeder Ebene nach Zugstärke sortiert.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2

Die Struktur der Vertriebsbüros, die Struktur der Menschen im MLM. Knoten können bestimmte Caching-Werte speichern, die die Eigenschaften des gesamten Teilbaums widerspiegeln. Zum Beispiel das Verkaufsvolumen eines bestimmten Teilbaums. Wir können jederzeit eine Zahl erhalten, die die Erfolge einer Branche widerspiegelt.

Globals sind Schatzschwerter zum Speichern von Daten. Bäume. Teil 2

4. In welchen Fällen ist die Verwendung von Globals am vorteilhaftesten?

In der ersten Spalte werden Fälle aufgeführt, in denen Sie durch die Verwendung von Globals einen erheblichen Geschwindigkeitsgewinn erzielen, und in der zweiten Spalte werden Fälle aufgeführt, in denen das Design oder Datenmodell vereinfacht wird.

Geschwindigkeit
Einfache Datenverarbeitung/-präsentation

  1. Einfügen [mit automatischer Sortierung auf jeder Ebene], [Indizierung nach Hauptschlüssel]
  2. Teilbäume entfernen
  3. Objekte mit vielen verschachtelten Eigenschaften, die individuellen Zugriff erfordern
  4. Hierarchische Struktur mit der Möglichkeit, untergeordnete Zweige von jedem Zweig zu umgehen, auch von nicht vorhandenen
  5. Tiefendurchquerung von Teilbäumen
  1. Objekte/Entitäten mit einer großen Anzahl optionaler [und/oder verschachtelter] Eigenschaften/Entitäten
  2. Daten ohne Schema. Wenn oft neue Immobilien entstehen und alte verschwinden.
  3. Sie müssen eine benutzerdefinierte Datenbank erstellen.
  4. Pfadbasen und Entscheidungsbäume. Wenn es praktisch ist, Pfade als Baum darzustellen.
  5. Entfernen hierarchischer Strukturen ohne Verwendung von Rekursion

Erweiterung „Globals sind Schatzschwerter zum Speichern von Daten. Sparse-Arrays. Teil 3".

Haftungsausschluss: Dieser Artikel und meine Kommentare dazu stellen meine Meinung dar und stehen in keinem Zusammenhang mit der offiziellen Position der InterSystems Corporation.

Source: habr.com

Kommentar hinzufügen