Алгоритм Hi/Lo
Hi/Lo — это алгоритм и стратегия генерации ключей, используемые для генерации уникальных ключей для использования в базе данных в качестве первичного ключа . Для генерации значений он использует шаблон «высокий-низкий» на основе последовательности. Hi/Lo используется в сценариях, где приложению необходимо, чтобы его объекты имели идентификатор перед сохранением. Это стратегия создания ценности. Альтернативой Hi/Lo может быть создание приложением ключей в виде универсально уникальных идентификаторов (UUID).
Объяснение
[ редактировать ]Предварительные условия:
- Существует константа, определенная для хранения максимально низкого значения . Значение должно быть больше нуля. Подходящим значением может быть 1000 или 32767 .
- Существует переменная, определенная для хранения текущего назначенного высокого значения , и ей присвоено значение 0 (ноль).
- Существует переменная, определенная для хранения текущего присвоенного нижнего значения , и ей присваивается значение максимального нижнего значения плюс 1 (единица).
Шаги:
- Если текущее назначенное нижнее значение больше или равно максимальному нижнему значению , вызовите функцию для получения нового верхнего значения и сброса текущего назначенного нижнего значения на 0 (ноль).
- Назначьте ключ, умножив назначенное в данный момент высокое значение на максимальное нижнее значение и добавив назначенное в данный момент нижнее значение .
- Увеличить текущее присвоенное нижнее значение на 1 (один).
Базе данных нужна таблица со столбцом для имени таблицы и столбцом с высоким значением.
Алгоритм
[ редактировать ]Переменные current_lo ( (целое) и current_hi целое) являются внутренними переменными состояния. Внутреннее состояние сохраняется при вызовах. Константа max_lo ( целое число) — это опция конфигурации. get_next_hi
— это функция, которая получает новое высокое значение с сервера базы данных. В системе управления реляционными базами данных это может осуществляться с помощью хранимой процедуры .
Предварительное условие: для параметра max_lo должно быть установлено значение больше нуля.
algorithm generate_key is output: key as a positive integer if 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 return key
Пример
[ редактировать ]Пример реализации на Python .
class HiloKeyGenerator:
"""Key generator that uses a Hi/Lo algorithm.
Args:
get_next_hi: A callable function that retrieves a new high value.
max_lo: The maximum low value. Defaults to 1000.
Raises:
ValueError: If the value of max_lo is not greater than zero.
"""
def __init__(self, get_next_hi: Callable[[], int], max_lo: int = 1000) -> None:
if max_lo <= 0:
raise ValueError("max_lo must be greater than zero.")
self._current_hi = 0
self._current_lo = max_lo + 1
self._get_next_hi = get_next_hi
self._max_lo = max_lo
def generate_key(self) -> int:
"""Generate a new unique key."""
if self._current_lo >= self._max_lo:
self._current_hi = self._get_next_hi()
self._current_lo = 0
key = self._current_hi * self._max_lo + self._current_lo
self._current_lo += 1
return key
Выход:
>>> def get_next_hi():
... return 2 # From database server.
...
>>> generator = HiloKeyGenerator(get_next_hi)
>>> generator.generate_key()
2000
>>> generator.generate_key()
2001
>>> generator.generate_key()
2002
Книги
[ редактировать ]Очень кратко упоминается в книге «Сохраняемость Java для реляционных баз данных» 2003 года на странице 236. Ричарда Сперко [1]
Очень кратко упоминается в книге Лучше, быстрее, легче Java» 2004 года на странице 137. Брюса Тейта и Джастина Гехтланда « [2]
Очень кратко упоминается в книге Разработка корпоративных Java с ограниченным бюджетом: использование открытого исходного кода Java» 2004 года на странице 386. Брайана Сэма-Боддена и Кристофера М. Джада « [3]
Объясняется в книге «Изучение NHibernate 4» 2015 года на страницах 53 и 144–145. Сухаса Чатекара [4]
Упоминается в книге рецептов NHibernate 4.x 2017 года на странице 35. [5]
Упоминается в книге ASP.NET Core 2 Fundamentals 2018 года на странице 219. [6]
Эта реализация использует алгоритм hi/lo для генерации идентификаторов. Алгоритм использует высокое значение, полученное из базы данных, и объединяет его с диапазоном низких значений для создания уникального идентификатора. Высокое значение из столбца
next_id
столаhibernate_unique_key
по умолчанию. Но вы можете переопределить это, чтобы использовать другую таблицу. Этот алгоритм также поддерживает указаниеwhere
параметр, который можно использовать для получения высокого значения для разных объектов из разных строк таблицы.hibernate_unique_key
стол.— Сухас Чатекар, Изучение NHibernate 4 (31 июля 2015 г.)
Для работы hilo нужен набор из двух чисел. Один из них — hi , который берется из таблицы базы данных, а другой — lo , который рассчитывается NHibernate. NHibernate объединяет эти два числа с использованием формулы для создания уникального числа, которое можно использовать в качестве идентификатора.
— Сухас Чатекар, Изучение NHibernate 4 (31 июля 2015 г.)
Хотя автоматически увеличиваемые идентификаторы проще, всякий раз, когда вы добавляете объект в контекст, это добавление приводит к принудительной вставке объекта в базу данных. Это связано с тем, что мы можем получить идентификатор только в том случае, если фактическая вставка происходит в случае автоматического увеличения идентификаторов. Алгоритм HiLo освобождает нас от этого ограничения, заранее резервируя идентификаторы с использованием последовательности базы данных.
— Онур Гумус и Мугилан Т.С. Рагупати, Основы ASP.NET Core 2 (30 августа 2018 г.)
Поддерживать
[ редактировать ]Поддерживается Entity Framework Core (ORM для .NET Core) с Microsoft SQL Server с использованием UseHiLo
метод расширения. [7] Не поддерживается предшественником Entity Framework .
Поддерживается Hibernate (ORM для Java) и NHibernate (ORM для .NET) через SequenceHiLoGenerator
[8] и TableHiLoGenerator
. [9] Поддержка как минимум с 2002 года. Поддержка как минимум с версии 3.2 с кодом, автором которого является Гэвин Кинг.
Поддерживается Доктриной [10] (ORM для PHP) через TableGenerator
сорт. [11]
При поддержке Мартена [12] (библиотека персистентности для .NET) с PostgreSQL через HiLoSequence
сорт. [13]
При поддержке RavenDB [14] (база данных документов NoSQL).
Не поддерживается Apache Cayenne , ServiceStack.OrmLite, Ruby on Rails Active Record, Dapper и Dashing.
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Сперко, Ричард. Сохраняемость Java для реляционных баз данных . Апресс. п. 236. ИСБН 9781590590713 .
- ^ Тейт, Брюс; Гетланд, Джастин. Лучше, быстрее и легче Java (1-е изд.). О'Рейли. п. 137 . ISBN 0-596-00676-4 .
- ^ Сэм-Бодден, Брайан; М. Джад, Кристофер. Бюджетная корпоративная разработка Java: использование технологий Java с открытым исходным кодом . Апресс. п. 386. ИСБН 978-1-59059-125-3 .
- ^ Чатекар, Сухас (31 июля 2015 г.). Изучение NHibernate 4: изучите весь потенциал NHibernate для создания надежного кода доступа к данным . Packt Publishing Ltd. с. 53. ИСБН 9781784392062 .
- ^ Лильяс, Гуннар; Зайцев, Александр; Дентлер, Джейсон (31 января 2017 г.). Книга рецептов NHibernate 4.x: более 90 невероятных и мощных рецептов, которые помогут вам эффективно использовать NHibernate в вашем приложении (второе изд.). Packt Publishing Ltd. с. 35. ISBN 9781784394110 .
- ^ Гумус, Онур; Т. С. Рагупати, Мугилан (30 августа 2018 г.). Основы ASP.NET Core 2: создавайте кроссплатформенные приложения и динамические веб-службы с помощью этой серверной платформы веб-приложений . Packt Publishing Ltd. с. 219. ИСБН 9781789533552 .
- ^ «Метод SqlServerPropertyBuilderExtensions.UseHiLo (Microsoft.EntityFrameworkCore)» . docs.microsoft.com .
- ^ «Реляционный преобразователь объектов NHibernate» . Гитхаб . НГибернейт. 14 ноября 2019 года . Проверено 14 ноября 2019 г.
- ^ «Реляционный преобразователь объектов NHibernate» . Гитхаб . НГибернейт. 14 ноября 2019 года . Проверено 14 ноября 2019 г.
- ^ «Doctrine\ORM\Sequencing\TableGenerator | API» . www.doctrine-project.org .
- ^ «Doctrine Object Relational Mapper (ORM)» . Гитхаб . Доктрина. 14 ноября 2019 года . Проверено 14 ноября 2019 г.
- ^ «Мартен — последовательные идентификаторы с Хило» . martendb.io .
- ^ «Postgresql как база данных документов и хранилище событий для приложений .Net: JasperFx/marten» . Гитхаб . Jasper Framework и связанные с ним проекты. 14 ноября 2019 года . Проверено 14 ноября 2019 г.
- ^ «Алгоритм HiLo | Документация RavenDB 5.1» . ravendb.net .