it-swarm.com.de

Was ist der Hi / Lo-Algorithmus?

Was ist der Hi/Lo-Algorithmus?

Ich habe dies in der Dokumentation NHibernate gefunden (es ist eine Methode, um eindeutige Schlüssel zu generieren, Abschnitt 5.1.4.2), aber ich habe keine gute Erklärung dafür gefunden, wie es funktioniert.

Ich weiß, dass Nhibernate damit umgeht, und ich muss das Innere nicht kennen, aber ich bin nur neugierig.

450
DiegoCofre

Die Grundidee ist, dass Sie zwei Zahlen haben, um einen Primärschlüssel zu bilden - eine "hohe" Zahl und eine "niedrige" Zahl. Grundsätzlich kann ein Client die "High" -Sequenz inkrementieren, in dem Wissen, dass er dann sicher Schlüssel aus dem gesamten Bereich des vorherigen "High" -Werts mit der Vielzahl von "Low" -Werten generieren kann.

Angenommen, Sie haben eine "High" -Sequenz mit einem aktuellen Wert von 35 und die "Low" -Nummer liegt im Bereich von 0-1023. Dann kann der Client die Sequenz auf 36 inkrementieren (damit andere Clients Schlüssel generieren können, während er 35 verwendet) und wissen, dass die Schlüssel 35/0, 35/1, 35/2, 35/3 ... 35/1023 vorhanden sind alles Verfügbar.

Es kann sehr nützlich sein (insbesondere bei ORMs), die Primärschlüssel auf der Clientseite festzulegen, anstatt Werte ohne Primärschlüssel einzufügen und sie dann wieder auf den Client abzurufen. Abgesehen von allem anderen bedeutet dies, dass Sie auf einfache Weise Eltern-Kind-Beziehungen herstellen und die Schlüssel vor dem Ausführen von any einfügen können, wodurch das Stapeln vereinfacht wird.

512
Jon Skeet

Zusätzlich zu Jons Antwort:

Es wird verwendet, um getrennt arbeiten zu können. Ein Client kann dann den Server nach einer Hi-Nummer fragen und Objekte erstellen, die die Lo-Nummer selbst erhöhen. Der Server muss erst kontaktiert werden, wenn der LO-Bereich aufgebraucht ist.

151

Die Hi/Lo-Algorithmen teilen die Sequenzdomäne in „Hi“ -Gruppen auf. Ein Hi-Wert wird synchron vergeben. Jede "Hi" -Gruppe erhält eine maximale Anzahl von "Lo" -Einträgen, die offline zugewiesen werden können, ohne sich um gleichzeitige doppelte Einträge kümmern zu müssen.

  1. Das "hi" -Token wird von der Datenbank zugewiesen, und zwei gleichzeitige Aufrufe sehen garantiert eindeutige aufeinanderfolgende Werte
  2. Sobald ein "Hi" -Token abgerufen wurde, benötigen wir nur noch "incrementSize" (die Anzahl der "Lo" -Einträge).
  3. Der Bezeichnerbereich wird durch die folgende Formel angegeben:

    [(hi -1) * incrementSize) + 1, (hi * incrementSize) + 1)
    

    und der "lo" -Wert liegt im Bereich:

    [0, incrementSize)
    

    angewendet ab dem Startwert von:

    [(hi -1) * incrementSize) + 1)
    
  4. Wenn alle "lo" -Werte verwendet werden, wird ein neuer "hi" -Wert abgerufen und der Zyklus fortgesetzt

Eine ausführlichere Erklärung finden Sie in dieser Artikel :

Diese visuelle Präsentation ist ebenfalls leicht zu verfolgen:

enter image description here

Während der Hi/Lo-Optimierer für die Optimierung der Identifikatorgenerierung in Ordnung ist, funktioniert er nicht gut mit anderen Systemen, die Zeilen in unsere Datenbank einfügen, ohne etwas über unsere Identifikatorstrategie zu wissen.

Hibernate bietet den Optimierer Pooled-Lo , der eine Hi/Lo-Generatorstrategie mit einem Interoperabilitäts-Sequenzzuweisungsmechanismus kombiniert. Dieser Optimierer ist sowohl effizient als auch interoperabel mit anderen Systemen. Er ist ein besserer Kandidat als die bisherige Hi/Lo-Identifizierungsstrategie.

24
Vlad Mihalcea

Lo ist ein zwischengespeicherter Allokator, der den Schlüsselbereich in große Teile aufteilt, in der Regel basierend auf der Größe eines Maschinenworts und nicht auf den Bereichen mit sinnvoller Größe (z. B. Abrufen von jeweils 200 Schlüsseln), die ein Mensch sinnvoll auswählen könnte.

Die Verwendung von Hi-Lo führt dazu, dass beim Neustart des Servers eine große Anzahl von Schlüsseln verschwendet und große, für den Menschen unfreundliche Schlüsselwerte generiert werden.

Besser als der Hi-Lo-Allokator ist der Allokator "Linear Chunk". Hierbei wird ein ähnliches tabellenbasiertes Prinzip verwendet, es werden jedoch kleine, zweckmäßige Blöcke zugeordnet und nette, menschenfreundliche Werte generiert.

create table KEY_ALLOC (
    SEQ varchar(32) not null,
    NEXT bigint not null,
    primary key (SEQ)
);

Um den nächsten zuzuweisen, sagen wir 200 Schlüssel (die dann als Bereich auf dem Server gespeichert und bei Bedarf verwendet werden):

select NEXT from KEY_ALLOC where SEQ=?;
update KEY_ALLOC set NEXT=(old value+200) where SEQ=? and NEXT=(old value);

Vorausgesetzt, Sie können diese Transaktion festschreiben (verwenden Sie Wiederholungsversuche, um Konflikte zu behandeln), haben Sie 200 Schlüssel zugewiesen und können diese bei Bedarf ausgeben.

Mit einer Blockgröße von nur 20 ist dieses Schema 10-mal schneller als die Zuweisung aus einer Oracle-Sequenz und zu 100% portierbar für alle Datenbanken. Die Allokationsleistung entspricht der von hi-lo.

Anders als bei Ambler wird der Schlüsselraum als zusammenhängende lineare Zahlenlinie behandelt.

Dies vermeidet den Anstoß für zusammengesetzte Schlüssel (was nie wirklich eine gute Idee war) und vermeidet die Verschwendung ganzer lo-Wörter, wenn der Server neu gestartet wird. Es generiert "freundliche" Schlüsselwerte auf menschlicher Ebene.

Im Vergleich dazu ordnet die Idee von Herrn Ambler die hohen 16- oder 32-Bit-Werte zu und erzeugt große menschenunfreundliche Schlüsselwerte als das Inkrement der Hi-Words.

Vergleich der zugewiesenen Schlüssel:

Linear_Chunk       Hi_Lo
100                65536
101                65537
102                65538
.. server restart
120                131072
121                131073
122                131073
.. server restart
140                196608

In Bezug auf das Design ist seine Lösung in Bezug auf die Anzahl der Elemente (zusammengesetzte Tasten, große hi_Word-Produkte) wesentlich komplexer als Linear_Chunk, ohne dass ein vergleichbarer Nutzen erzielt wird.

Das Hi-Lo-Design entstand früh in OO= Mapping und Persistenz. In diesen Tagen bieten Persistenz-Frameworks wie Hibernate einfachere und bessere Allokatoren als Standard.

20
Thomas W

Ich fand, dass der Hi/Lo-Algorithmus für mehrere Datenbanken mit Replikationsszenarien meiner Erfahrung nach perfekt ist. Stell dir das vor. Sie haben einen Server in New York (Alias ​​01) und einen anderen Server in Los Angeles (Alias ​​02). Dann haben Sie eine PERSON-Tabelle. Wenn also eine Person erstellt wird, verwenden Sie in New York immer 01 als HI-Wert und der LO-Wert ist der nächste secuential. Zum Beispiel.

  • 010000010 Jason
  • 010000011 David
  • 010000012 Theo

in Los Angeles benutzen Sie immer das HI 02. Zum Beispiel:

  • 020000045 Rupert
  • 020000046 Oswald
  • 020000047 Mario

Wenn Sie also die Datenbankreplikation verwenden (unabhängig von der Marke), lassen sich alle Primärschlüssel und Daten auf einfache und natürliche Weise kombinieren, ohne sich um doppelte Primärschlüssel, Kollisionen usw. sorgen zu müssen.

Dies ist der beste Weg, um in diesem Szenario vorzugehen.

1
Theo