Algorytm Hi/Lo

Hi/Lo to algorytm i strategia generowania kluczy używana do generowania unikalnych kluczy do wykorzystania w bazie danych jako klucz podstawowy . Wykorzystuje sekwencyjny wzór hi-lo do generowania wartości. Może być używany z projektowaniem opartym na domenie (DDD). Hi/Lo jest używany w scenariuszach, w których aplikacja wymaga, aby jej jednostki miały tożsamość przed trwałością. Jest to strategia generowania wartości. Alternatywą dla Hi/Lo byłoby generowanie kluczy jako uniwersalnie unikalnych identyfikatorów (UUID).

Wyjaśnienie

Warunki wstępne to:

  • Istnieje stała zdefiniowana do przechowywania maksymalnej niskiej wartości . Wartość musi być większa od zera. Odpowiednią wartością może być 1000 lub 32767 .
  • Istnieje zmienna zdefiniowana do przechowywania aktualnie przypisanej wysokiej wartości i jest jej przypisana wartość 0 (zero).
  • Istnieje zmienna zdefiniowana do przechowywania aktualnie przypisanej niskiej wartości i jest jej przypisana wartość maksymalnej niskiej wartości plus 1 (jeden).

Kroki są następujące:

  1. Jeśli aktualnie przypisana niska wartość jest większa lub równa niż maksymalna niska wartość, wywołaj funkcję, aby pobrać nową wysoką wartość i zresetować aktualnie przypisaną niską wartość do 0 (zero).
  2. Przypisz klawisz, mnożąc aktualnie przypisaną wysoką wartość przez maksymalnie niską wartość i dodając aktualnie przypisaną niską wartość .
  3. Zwiększ aktualnie przypisaną niską wartość o 1 (jeden).

A sequence diagram of the Hi/Lo algorithm.

Algorytm

Zmienne current_lo (liczba całkowita) i current_hi (liczba całkowita) są wewnętrznymi zmiennymi stanu. Stan wewnętrzny jest zachowywany we wszystkich wywołaniach. max_lo ) jest opcją konfiguracyjną. get_next_hi to funkcja, która pobiera nową wysoką wartość z serwera bazy danych. W systemie zarządzania relacyjnymi bazami danych może to odbywać się za pomocą procedury składowanej .

Warunek wstępny: max_lo musi być ustawione na wartość większą od zera.

       
        
     algorytm  wygeneruj_klucz  jest  wyprowadzany:  klucz  jako dodatnia liczba całkowita  jeśli  current_lo  max_lo  then  current_hi  := get_next_hi()  current_lo  := 0  key  :=  current_hi  ×  max_lo  +  current_lo  current_lo  :=  current_lo  + 1  klawisz  powrotu  

Przykład

Przykładowa implementacja w Pythonie .

 
    









             class  HiloKeyGenerator  :  """Generator kluczy, który używa algorytmu Hi/Lo.  Args:  get_next_hi: Funkcja wywoływalna, która pobiera nową wysoką wartość.  max_lo: Maksymalna najniższa wartość. Domyślnie 1000.  Podbicia:  ValueError: Jeśli wartość max_lo nie jest większe od zera.  """  def  __init__  (  self  ,  get_next_hi  :  Callable  [[],  int  ],  max_lo  :  int  =  1000   
           0
             
          0
            
          
          

        )  ->  Brak  :  if  max_lo  <=  :  raise  ValueError  (  "max_lo musi być większe od zera."  )  self  .  _bieżąca_hi  =  ja  .  _current_lo  =  max_lo  +  1  ja  .  _get_next_hi  =  get_next_hi  ja  .  _max_lo  =  max_lo  def  generuj_klucz  (  self  )  ->  int 
        
           
              
              0

              
          :  """Wygeneruj nowy unikalny klucz."""  if  self  .  _current_lo  >=  ja  .  _max_lo  :  ja  .  _bieżąca_hi  =  ja  .  _get_next_hi  ()  ja  .  _current_lo  =  klucz  =  sam  .  _bieżący_cześć  *  ja  .  _max_lo  +  ja  .  _current_lo  siebie  .  _bieżące_lo  +=  

         1  klucz  powrotu  

Wyjście:

 
       

  





 >>>  def  get_next_hi  ():  ...  return  2  # Z serwera bazy danych.  ...  >>>  generator  =  HiloKeyGenerator  (  get_next_hi  )  >>>  generator  .  wygeneruj_klucz  ()  2000  >>>  generator  .  wygeneruj_klucz  ()  2001  >>>  generator  .  wygeneruj_klucz  ()  2002 

Książki

Bardzo krótko wspomniano w książce Java Persistence for Relational Databases z 2003 roku autorstwa Richarda Sperko na stronie 236.

Bardzo krótko wspomniano w książce Better, Faster, Lighter Java z 2004 roku autorstwa Bruce'a Tate'a i Justina Gehtlanda na stronie 137.

Bardzo krótko wspomniano w książce Enterprise Java Development on a Budget: Leveraging Java Open Source z 2004 roku autorstwa Briana Sama-Boddena i Christophera M. Juda na stronie 386.

Wyjaśniono w książce Learning NHibernate 4 z 2015 r . Autorstwa Suhas Chatekar na stronach 53 i 144–145.

Wspomniano w książce kucharskiej NHibernate 4.x z 2017 r. na stronie 35.

Wspomniano w książce 2018 ASP.NET Core 2 Fundamentals na stronie 219.

Ta implementacja wykorzystuje algorytm hi/lo do generowania identyfikatorów. Algorytm wykorzystuje wysoką wartość pobraną z bazy danych i łączy ją z zakresem niskich wartości w celu wygenerowania unikalnego identyfikatora. Wysoka wartość pochodzi domyślnie z kolumny next_id tabeli hibernate_unique_key . Ale możesz to zmienić, aby użyć innej tabeli. Algorytm ten obsługuje również określanie gdzie , którego można użyć do pobrania wysokiej wartości dla różnych jednostek z różnych wierszy tabeli hibernate_unique_key .

Suhas Chatekar, Nauka NHibernate 4 (2015-07-31)

hilo potrzebuje zestawu dwóch liczb do pracy. Jeden to hi , który pochodzi z tabeli bazy danych, a drugi to lo , który jest obliczany przez NHibernate. NHibernate łączy te dwie liczby za pomocą formuły w celu wygenerowania unikalnej liczby, której można użyć jako identyfikatora.

Suhas Chatekar, Nauka NHibernate 4 (2015-07-31)

Podczas gdy automatycznie zwiększane identyfikatory są prostsze, za każdym razem, gdy dodajesz jednostkę do kontekstu, to dodanie wymusza wstawienie jednostki do bazy danych. Dzieje się tak dlatego, że możemy pobrać identyfikator tylko wtedy, gdy rzeczywiste wstawienie ma miejsce w przypadku automatycznie zwiększanych identyfikatorów. Algorytm HiLo uwalnia nas od tego ograniczenia, rezerwując wcześniej identyfikatory za pomocą sekwencji bazy danych.

Onur Gumus i Mugilan TS Ragupathi, podstawy ASP.NET Core 2 (2018-08-30)

Wsparcie

Obsługiwane przez Entity Framework Core (ORM dla .NET Core) z Microsoft SQL Server przy użyciu metody rozszerzenia UseHiLo . Nieobsługiwane przez poprzednika Entity Framework .

Obsługiwane przez Hibernate (ORM dla Java) i NHibernate (ORM dla .NET) za pośrednictwem SequenceHiLoGenerator i TableHiLoGenerator . Miał wsparcie od co najmniej 2002 roku. Miał wsparcie co najmniej od wersji 3.2 z kodem autorstwa Gavina Kinga.

Obsługiwane przez Doctrine (ORM dla PHP) poprzez klasę TableGenerator .

Obsługiwane przez Marten (biblioteka trwałości dla .NET) z PostgreSQL za pośrednictwem klasy HiLoSequence .

Obsługiwane przez RavenDB (baza danych dokumentów NoSQL).

Nieobsługiwane przez Apache Cayenne , ServiceStack.OrmLite, Ruby on Rails Active Record, Dapper i Dashing.

Zobacz też

Linki zewnętrzne