Как только HiLo используется, что произойдет, если вы измените емкость (максимальный Lo)?

Если я начну использовать генератор HiLo для назначения идентификаторов для таблицы, а затем решу увеличить или уменьшить емкость (т. Е. Максимальное значение «lo»), это вызовет коллизии с уже назначенными идентификаторами?

Мне просто интересно, нужно ли мне ставить большой красный флажок вокруг числа, говорящего: «Никогда не меняй это!»

Примечание - не специфично для NHibernate, мне просто любопытно узнать о HiLo алгоритм в целом.

8
задан Jon M 21 June 2010 в 11:16
поделиться

2 ответа

Алгоритмы HiLo в основном отображают два целых числа в один целочисленный идентификатор. Это гарантирует, что пара чисел будет уникальной для каждой базы данных. Как правило, следующим шагом является обеспечение соответствия уникальной пары чисел уникальному целочисленному идентификатору.

Хорошее объяснение того, как HiLo концептуально работает, дано в предыдущем ответе SO

. Изменение max_lo сохранит свойство, заключающееся в том, что ваша пара чисел будет уникальной. Однако обеспечит ли он уникальность отображаемого идентификатора и отсутствие конфликтов?

Давайте посмотрим на реализацию HiLo в Hibernate.Алгоритм, который они используют (как я понял), следующий: (и я могу не говорить о технических деталях)

h = high sequence (starting at 0)
l_size = size of low block
l = low sequence (starting at 1)

ID = h*l_size + l

Итак, если ваш низкий блок, скажем, 100, ваши зарезервированные блоки идентификаторов будут равны 1- 100, 101-200, 201-300, 301-400 ...

Ваша последовательность High теперь равна 3. Что произойдет, если вы вдруг измените свой l_size на 10? Ваш следующий блок, ваш максимум увеличивается, и вы получите 4 * 10 + 1 = 41

Ой. Это новое значение определенно попадает в «зарезервированный блок» 1-100 . Кто-то с высокой последовательностью 0 подумает: «Ну, у меня есть диапазон 1-100 , зарезервированный только для меня, поэтому я просто поставлю один на 41 , потому что я знайте, что это безопасно ».

Определенно, существует очень и очень высокая вероятность столкновения, когда понижает ваш l_max.

Как насчет противоположного случая, повышения его?

Вернемся к нашему примеру, давайте увеличим наш l_size до 500, превратив следующий ключ в 4 * 500 + 1 = 2001 , сохраняя диапазон 2001 -2501.

Похоже, что в этой конкретной реализации HiLo столкновения можно будет избежать, когда поднимет ваш l_max.

Конечно, вам следует провести несколько собственных тестов, чтобы убедиться, что это реальная реализация или близкая к ней. Один из способов - установить l_max на 100 и найти несколько первых ключей, затем установить его на 500 и найти следующий. Если произойдет огромный скачок, подобный упомянутому здесь, вы можете быть в безопасности.

Однако я ни в коем случае не предлагаю повысить l_max в существующей базе данных.

Используйте свое усмотрение; алгоритм HiLo - это не совсем тот, который создан с учетом меняющегося l_max, и ваши результаты могут в конечном итоге быть непредсказуемыми в зависимости от вашей точной реализации. Может быть, кто-то, у кого был опыт повышения l_max и поиска проблем, сможет доказать, что этот подсчет верен.

Итак, в заключение, хотя теоретически реализация HiLo Hibernate, скорее всего, будет избегать коллизий при повышении l_max, это, вероятно, все еще не является хорошей практикой. Вы должны кодировать так, как будто l_max не изменится со временем.

Но если вам повезет ...

20
ответ дан 5 December 2019 в 06:22
поделиться

Просто по опыту скажу: да, уменьшение вызовет коллизии. Когда у вас более низкий максимальный минимум, вы получаете меньшие числа, независимо от высокого значения в базе данных (которое обрабатывается одинаково, например, приращение с каждым экземпляром фабрики сеанса в случае NH).

Есть шанс, что увеличение не вызовет столкновений. Но вам нужно либо попробовать, либо спросить кого-нибудь, кто знает лучше меня, чтобы быть уверенным.

1
ответ дан 5 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: