2010-08-14 15 views
5

Pregunta: Cuando usted tiene un GUID .NET para insertar en una base de datos, su estructura es la siguiente:localmente único identificador

60 bits of timestamp, 
48 bits of computer identifier, 
14 bits of uniquifier, and 
6 bits are fixed, 
---- 
128 bits total 

Ahora tengo un problema con un GUID, porque es un número de 128 bits, y algunos de los DB que uso solo admiten números de 64 bits.

Ahora no quiero resolver el dilema utilizando un valor biginc autoincrement, ya que quiero poder hacer la replicación sin conexión.

Así que tuve la idea de crear una clase identificadora localmente única, que básicamente es un GUID reducido a un valor de 64 bits.

me ocurrió esto:

day 9 bit (12*31=372 d) 
year 8 bit (2266-2010 = 256 y) 
seconds 17 bit (24*60*60=86400 s) 
hostname 12 bit (2^12=4096) 
random 18 bit (2^18=262144) 
------------------------ 
      64 bits total 

Mi pregunta ahora es: La marca de tiempo es más o menos fija en 34 bits, dejándome con 64-34 = 30 bits para el nombre de host + número aleatorio.

Ahora mi pregunta es: 1) ¿Preferiría aumentar el tamaño de host-hash bitsize y disminuir el tamaño de bits aleatorio, o aumentar el tamaño de bits aleatorio y disminuir el tamaño de host-hash bitsize.

2) Existe un algoritmo hash que reduce cada cadena a n-Bits? n idealmente = 12 o tan cerca como sea posible.

Respuesta

3

En realidad, los GUID generados .NET son 6 bits fijos y 122 bits de aleatoriedad.

Podría considerar usar 64 bits de aleatoriedad, con una mayor probabilidad de colisión debido a la menor longitud de bits. Funcionaría mejor que un hash.

+0

Existen varios enfoques; También me gusta la idea de una "identificación de nodo" con una marca de tiempo (sin aleatoriedad). Puede crear fácilmente un ID de nodo con cualquier cantidad de bits mediante la operación XOR de un hash criptográfico (por ejemplo, SHA1). Cuantos menos bits, mayor es la probabilidad de una colisión de identificación de nodo, por supuesto. El "uniquificador" que mencionaste es en realidad usado por otros algoritmos Guid para manejar los relojes del sistema que se remontan, para mantener las marcas de tiempo únicas por identificación de nodo. Pero al final del día, será difícil encontrar una solución que garantice menos colisiones que la aleatoriedad pura. Recuerde, eso es todo .NET Guids do ... –

+0

Si bien la probabilidad de 1/2^64 sigue siendo un número muy pequeño, no me gusta la idea de un número aleatorio puro. Pero pensé en omitir el hash de nombre de host por completo y simplemente aumentar el número aleatorio a 30 bits. Pero esa no es una buena idea, porque para n clientes fuera de línea, eso haría que la probabilidad de colisión sea de 2^30 * n. Para 100 clientes, eso es solo uno por cada 10 millones. Con mucha mala suerte, uno podría llegar al pozo allí ... –

+0

1/2^64 == uno en 18 septillones (un septillón == un billón de un billón, o un millón de millones de millones). Si va por el camino completamente aleatorio ... –

2

Si el espacio no es una preocupación, ¿por qué no usa 2 columnas de 64 bits de ancho, luego divide el guid por la mitad usando 8bytes para cada una, simplemente conviértelos a sus números de 64 bits y guárdelo en 2 columnas, entonces si alguna vez necesita hacer una conversión a otro sistema, usted seguirá siendo único, solo necesitará factorizar el reingreso de las 2 columnas.

+0

Luego tendré que comparar dos números para cada unión. ¿Eso no disminuye el rendimiento demasiado? –

+0

Bueno, estarás involucrando una columna adicional en tu clave [suponiendo que la guía sea una clave], así que tendrás un ligero cambio, pero de esta manera no perderás el Guid en los sistemas que pueden soportarlo y tienes una solución para aquellos que no lo hacen. –

0

¿Por qué escribir la suya? ¿Por qué no generar un número uniformemente aleatorio? Hará el trabajo bien. Simplemente tome los primeros X dígitos donde X tiene el tamaño que desee ... digamos 64 bits.

Ver here de información sobre RAND() vs NEWID() en SQL Server, que es en realidad sólo una acusación de GUID frente a los generadores de números aleatorios. Además, vea here si necesita algo más aleatorio que System.Random.

+0

Números completamente aleatorios no son una buena idea, en mi humilde opinión. No quiero preocuparme por duplicados y errores extraños a medida que la base de datos se hace cada vez más grande. Al menos una marca de tiempo necesita integrarse de alguna manera. Aunque pensando en ello, sería más prudente dejar los segundos y simplemente aumentar el tamaño entero aleatorio. De esa manera puedo tener un hash de nombre de host bastante largo y un número aleatorio bastante largo. –

Cuestiones relacionadas