Was ist der Hi / Lo-Algorithmus?

1. Einleitung

In diesem Tutorial erklären wir den Hi / Lo-Algorithmus. Es wird hauptsächlich als Strategie zur Generierung von Datenbankkennungen verwendet .

Wir beginnen mit der Algorithmusübersicht. Anschließend zeigen wir ein praktisches Beispiel, das auf dem Hibernate-Framework basiert. Abschließend werden die Anwendungsfälle des Algorithmus, seine Vor- und Nachteile erläutert.

2. Übersicht über den Hi / Lo-Algorithmus

2.1 Definition

Der Hauptzweck des Hi / Lo-Algorithmus besteht darin , einen Zahlenbereich zu erstellen, der sicher als Datenbankkennungen verwendet werden kann . Zu diesem Zweck werden drei Zahlenvariablen verwendet, die üblicherweise als high, low und incrementSize bezeichnet werden .

Die Variable incrementSize enthält die maximale Anzahl von Bezeichnern, die in einem Stapel generiert werden können. Es sollte als konstanter Wert behandelt werden, der zu Beginn des Algorithmus definiert wurde. Jede Laufzeitänderung kann in Umgebungen, in denen mehrere Clients dieselbe Hi / Lo-Konfiguration verwenden, um Einträge beizubehalten, schwerwiegende Probleme verursachen.

Die hohe Variable wird normalerweise aus einer Datenbanksequenz zugewiesen. In diesem Fall sind wir sicher, dass niemand zweimal dieselbe Nummer erhält.

Die niedrige Variable enthält die aktuell zugewiesene Nummer im Bereich [0 , incrementSize] .

Anhand dieser Punkte generiert der Hi / Lo-Algorithmus Werte im Bereich [( hi - 1) * incrementSize + 1 , ( hi * incrementSize )).

2.2 Pseudocode

Schauen wir uns die Schritte zum Generieren eines neuen Werts mit dem Hi / Lo-Algorithmus an:

  • Wenn low größer oder gleich incrementSize ist , weisen Sie high einen neuen Wert zu und setzen Sie low auf 0 zurück
  • Generieren Sie einen neuen Wert mit der Formel: ( hoch - 1) * incrementSize + low
  • Inkrement niedrig um 1
  • Geben Sie den generierten Wert zurück

3. Praktisches Beispiel

Lassen Sie uns den Hi / Lo-Algorithmus in Aktion sehen. Dazu verwenden wir das Hibernate-Framework und seine Hi / Lo-Implementierung.

Definieren wir zunächst eine Datenbankentität, mit der gearbeitet werden soll:

@Entity public class RestaurantOrder { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_sequence_generator") @GenericGenerator( name = "hilo_sequence_generator", strategy = "sequence", parameters = { @Parameter(name = "sequence_name", value = "hilo_seqeunce"), @Parameter(name = "initial_value", value = "1"), @Parameter(name = "increment_size", value = "3"), @Parameter(name = "optimizer", value = "hilo") } ) private Long id; }

Es ist eine einfache Restaurantbestellung mit einem ID- Feld. Um den Hi / Lo-Algorithmus im Ruhezustand korrekt zu definieren , müssen wir bei der Definition des ID- Felds eine Sequenzstrategie auswählen - Hilo Optimizer - und den Parameter increment_size angeben .

Um den Hi / Lo-Algorithmus in Aktion zu zeigen, werden neun Restaurantbestellungen in einer Schleife beibehalten:

public void persist() { Transaction transaction = session.beginTransaction(); for (int i = 0; i < 9; i++) { session.persist(new RestaurantOrder()); session.flush(); } transaction.commit(); }

Nach der angegebenen Schrittweite in der Einheit, sollten wir nur drei Anrufe auf die Datenbank für die nächste haben hohen Wert. Angenommen, die Datenbanksequenz beginnt bei 1, liegt der erste Stapel generierter Bezeichner im Bereich [1,3].

Wenn der Hi / Lo-Algorithmus 3 zurückgibt und Hibernate nach dem Wert des nächsten Bezeichners fragt, entspricht der Wert der niedrigen Variablen der Konstante incrementSize . In diesem Fall muss der nächste Aufruf der Datenbank für den neuen hohen Wert erfolgen. Mit 2 als neuem hohen Wert generiert der Algorithmus Werte im Bereich [4,6].

Schließlich ist der letzte Aufruf an die Datenbank für den nächsten Hoch wird Wert gemacht und Werte im Bereich [7, 9] werden den Einheiten zugeordnet.

Protokolle im Ruhezustand, die während der Ausführung der Methode persist () erfasst wurden , bestätigen diese Werte:

Hibernate: call next value for hilo_seqeunce org.hibernate.id.enhanced.SequenceStructure - Sequence value obtained: 1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 1, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 2, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 3, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Hibernate: call next value for hilo_seqeunce org.hibernate.id.enhanced.SequenceStructure - Sequence value obtained: 2 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 4, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 5, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 6, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Hibernate: call next value for hilo_seqeunce org.hibernate.id.enhanced.SequenceStructure - Sequence value obtained: 3 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 7, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 8, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 9, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator

4. Vor- und Nachteile des Algorithmus

Der Hauptvorteil des Hi / Lo-Algorithmus ist die reduzierte Anzahl von Datenbankaufrufen für die nächsten Sequenzwerte. Durch Erhöhen des Werts von incrementSize wird die Anzahl der Roundtrips zur Datenbank verringert. Dies bedeutet natürlich einen Leistungsgewinn in unserer Anwendung. Darüber hinaus ist der Hi / Lo-Algorithmus eine bevorzugte Wahl in Umgebungen mit einer schwachen Internetverbindung .

Andererseits ist der Hi / Lo-Algorithmus nicht die beste Wahl in Umgebungen, in denen mehrere verschiedene Clients Daten in derselben Tabelle in einer Datenbank speichern . Anwendungen von Drittanbietern kennen möglicherweise nicht die Hi / Lo-Strategie, mit der wir Kennungen generieren. Infolgedessen verwenden sie möglicherweise Entitäts-IDs aus dem generierten Zahlenbereich, der derzeit in unserer Anwendung verwendet wird. In diesem Fall können bei persistenten Daten Fehler auftreten, die schwer zu beheben sind.

5. Schlussfolgerung

In diesem Tutorial haben wir den Hi / Lo-Algorithmus besprochen.

Zunächst erklärten wir die Funktionsweise und diskutierten die Pseudocode-Implementierung. Anschließend haben wir ein praktisches Beispiel für die Implementierung des Hibernate-Algorithmus gezeigt. Schließlich haben wir die Vor- und Nachteile von Hi / Lo aufgelistet.

Wie immer ist der in diesem Artikel gezeigte Code über GitHub verfügbar.