2008-11-11 7 views
410

¿Cuál es el algoritmo Hi/Lo?¿Cuál es el algoritmo Hi/Lo?

He encontrado esto en la documentación NHibernate (es un método para generar claves únicas, sección 5.1.4.2), pero no he encontrado una buena explicación de cómo funciona.

Sé que Nhibernate lo maneja, y no necesito conocer el interior, pero solo tengo curiosidad.

Respuesta

467

La idea básica es que tiene dos números para formar una clave principal: un número "alto" y un número "bajo". Un cliente puede básicamente incrementar la secuencia "alta", sabiendo que puede generar claves de forma segura desde todo el rango del valor "alto" anterior con la variedad de valores "bajos".

Por ejemplo, supongamos que tiene una secuencia "alta" con un valor actual de 35, y el número "bajo" está en el rango 0-1023. Luego el cliente puede incrementar la secuencia a 36 (para que otros clientes puedan generar claves mientras usa 35) y saber que las claves 35/0, 35/1, 35/2, 35/3 ... 35/1023 son todo disponible.

Puede ser muy útil (particularmente con ORM) para poder establecer las claves primarias en el lado del cliente, en lugar de insertar valores sin claves primarias y luego recuperarlos en el cliente. Aparte de cualquier otra cosa, significa que puede hacer fácilmente las relaciones padre/hijo y tener las claves en su lugar antes de hacer insertos, lo que hace que los lotes sean más sencillos.

+11

¿Está diciendo que los "rangos bajos" se coordinan dentro del cliente, mientras que la "secuencia alta" corresponde a una secuencia DB? –

+2

Sí, eso es básicamente eso. –

+11

¿Los valores de alta y baja normalmente se componen en un solo valor entero, o como una clave comercial de dos partes? –

140

Además de la respuesta de Jon:

Se utiliza para poder trabajar desconectado. Un cliente puede pedirle al servidor un número alto y crear objetos que aumenten el número de lo mismo. No necesita contactar al servidor hasta que se agote el rango lo.

18

Mejor que el asignador Hi-Lo, es el asignador "Linear Chunk". Esto utiliza un principio similar basado en tablas pero asigna trozos pequeños, de tamaño conveniente. & genera buenos valores amigables para los humanos.

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

para asignar los próximos, digamos, 20 teclas (que se llevan a cabo a continuación, como un rango en el servidor & utilizados según sea necesario):

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

Siempre que puede cometer esta transacción (reintentos uso de manejar contención), ha asignado 20 claves & puede dispensarlas según sea necesario.

Con un tamaño de porción de solo 20, este esquema es 10 veces más rápido que la asignación desde una secuencia de Oracle, y es 100% portátil entre todas las bases de datos. El rendimiento de asignación es equivalente a hi-lo.

A diferencia de la idea de Ambler, trata el espacio de teclas como una recta numérica contigua.

Esto evita el impulso de las claves compuestas (que en realidad nunca fueron una buena idea) y evita el desperdicio de lo-palabras completas cuando se reinicia el servidor. Genera valores clave "amigables" a escala humana.

La idea de Mr Ambler, en comparación, asigna los 16 o 32 bits altos, y genera grandes valores de clave nocivos para el ser humano como el incremento de las palabras altas.

Comparación de teclas asignadas:

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

realidad Me correspondió con el Sr. Ambler en los años 90 para sugerir este esquema mejorado para él, pero estaba demasiado pegado & reacio a reconocer las ventajas & simplicidad clara de la utilización de una recta numérica lineal.

En cuanto al diseño, su solución es fundamentalmente más compleja en la línea de números (claves compuestas, productos hi_word grandes) que Linear_Chunk sin obtener ningún beneficio comparativo. Su diseño está matemáticamente probado deficiente.

+0

¿Quién es mister Ambler? – Apocatastasis

+0

Scott Ambler promueve una estrategia de asignación llamada "hi-lo" usando palabras de 16 o 32 bits. Aquí está su página: http://www.ambysoft.com/scottAmbler.html –

+1

Bonita publicación, pero no estás respondiendo la pregunta. – orbfish

16

Los algoritmos de hi/lo dividen el dominio de las secuencias en grupos "hi". Un valor "hi" se asigna sincrónicamente. A cada grupo "hi" se le asigna un número máximo de entradas "lo", que pueden asignarse fuera de línea sin preocuparse por las entradas duplicadas concurrentes.

  1. El “hola” token se le asigne la base de datos, y dos llamadas simultáneas están garantizados para ver los valores consecutivos únicos
  2. Una vez que un “hola” token se recuperó sólo necesitamos la “incrementSize” (el número de “lO” entradas)
  3. el rango de identificadores está dada por la siguiente fórmula:

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

    y el “lo” valor estará en la gama:

    [0, incrementSize) 
    

    que se aplica desde el valor inicial de:

    [(hi -1) * incrementSize) + 1) 
    
  4. Cuando se utilizan todos los valores “LO”, un nuevo “hola” valor es exagerado y el ciclo continúa

Usted puede encontrar una explicación más detallada en this article:

Y esta presentación visual es fácil de seguir también:

enter image description here

Mientras hi optimizador/Lo está muy bien para optimizar la generación de identificador, que no juega bien con otros sistemas de insertar filas en nuestra base de datos, sin saber nada de nuestra estrategia identificador.

Hibernate ofrece el optimizador pooled-lo, que combina una estrategia de generador hi/lo con un mecanismo de asignación de secuencia de interoperabilidad. Este optimizador es tanto eficiente como interoperable con otros sistemas, siendo un mejor candidato que la estrategia anterior de identificador hi/lo heredado.

+2

Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. – kryger

+1

Es una buena idea, actualizaré en consecuencia. –

+0

Realmente no te entiendo a veces jajaja: mientras que el optimizador de alta/baja está bien para optimizar la generación de identificadores (bueno, bueno), no funciona bien con otros sistemas (¿qué quieres decir con otros sistemas?, Que son ¿primeros?) insertar filas en nuestra base de datos (¿no se utiliza la generación de identificador para insertar filas también?), sin saber nada sobre nuestra estrategia de identificación. – Adelin

1

Encontré que el algoritmo Hi/Lo es perfecto para múltiples bases de datos con escenarios de replicación basados ​​en mi experiencia. Imagina esto. tienes un servidor en Nueva York (alias 01) y otro servidor en Los Angeles (alias 02), entonces tienes una tabla PERSON ... entonces en Nueva York cuando una persona es creado ... siempre usas 01 como HI valor y el valor LO es el siguiente secuencial. por ejemplo.

  • 010000010 Jason
  • 010000011 David
  • 010000012 Theo

en Los Ángeles que siempre utilice el HI 02. Por ejemplo:

  • 020000045 Rupert
  • 020000046 Oswald
  • 020000047 Mario

Por lo tanto, cuando se utiliza la replicación de bases de datos (no importa qué marca) todas las claves principales y los datos se combinan con facilidad y, naturalmente, sin preocuparse de duplicados de las llaves primarias, collissions, etc.

Este es la mejor manera de ir en este escenario.

+0

No funciona en Hibernate. HiLo Algrotirm obtiene un nuevo valor de secuencia en cada transacción, por lo que el contador HI se incrementa de forma acorde. Pero en su ejemplo, el contador HI siempre es constante para un DB. – Dmitry1405

Cuestiones relacionadas