2010-08-14 3 views
5

Question: Lorsque vous avez un GUID .NET pour l'insertion dans une base de données, sa structure est comme ceci:identifiant localement unique,

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

Maintenant, j'ai problème avec un GUID, car il est un nombre de 128 bits, et certains des DB que j'utilise ne supportent que des nombres de 64 bits.

Maintenant, je ne veux pas résoudre le dilemme en utilisant une valeur autoincrement bigint, puisque je veux être en mesure de faire une réplication hors ligne. J'ai donc eu l'idée de créer une classe d'identificateur localement unique, qui est essentiellement un GUID réduit à une valeur de 64 bits.

je suis venu avec ceci:

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 

Ma question est maintenant: L'horodatage est à peu près fixé à 34 bits, me laissant avec 64-34 = 30 bits pour le nom d'hôte + nombre aléatoire.

Maintenant ma question: 1) Préféreriez-vous augmenter la taille de nom d'hôte-hash bitsize et diminuer la taille des bits aléatoires, ou augmenter la taille de bits aléatoires et diminuer la taille de bits hostname-hash.

2) Existe-t-il un algorithme de hachage qui réduit chaque chaîne à n-bits? n étant idéalement = 12 ou aussi proche que possible.

Répondre

3

En fait, les GUID générés par .NET sont 6 bits fixes et 122 bits aléatoires.

Vous pourriez envisager d'utiliser 64 bits de hasard, avec un risque accru de collision en raison de la plus petite longueur de bits. Cela fonctionnerait mieux qu'un hachage.

+0

Il existe différentes approches; J'aime aussi l'idée d'un "node id" avec un horodatage (pas de hasard). Vous pouvez facilement créer un ID de nœud avec n'importe quel nombre de bits en effectuant une opération XOR à l'aide d'un hachage cryptographique (par exemple, SHA1). Moins il y a de bits, plus le risque de collision d'un nœud est élevé, bien sûr. L '"uniquificateur" que vous avez mentionné est en fait utilisé par d'autres algorithmes de Guid pour gérer les horloges système en remontant, pour garder les horodateurs uniques par identifiant de nœud. Mais à la fin de la journée, vous aurez du mal à trouver une solution qui garantit moins de collisions que le hasard pur. Rappelez-vous, c'est tout .NET Guids faire ... –

+0

Alors que la probabilité de 1/2^64 est encore un très petit nombre, je n'aime pas la pensée d'un nombre aléatoire pur. Mais j'ai pensé en omettant complètement le hachage de nom d'hôte et juste augmenter le nombre aléatoire à 30 bits. Mais ce n'est pas une bonne idée, car pour n clients hors ligne, cela ferait passer la chance de collision à 2^30 * n. Pour 100 clients, c'est seulement environ un pour 10 millions. Avec beaucoup de malchance, on pourrait juste frapper le jackpot là ... –

+0

1/2^64 == un sur 18 septillion (un septillion = un billion de billion, soit un million de millions de millions). Si vous allez de manière totalement aléatoire ... –

2

Si l'espace n'est pas un problème, pourquoi n'utilisez-vous pas simplement 2 colonnes de 64 bits, puis divisez le guid en deux en utilisant 8 octets pour chaque, puis convertissez-les en 64 bits et stockez-le en 2 colonnes, alors si vous avez besoin de migrer vers un autre système, vous serez toujours unique, vous aurez juste besoin de prendre en compte le retour des 2 colonnes.

+0

Ensuite, je vais devoir comparer deux nombres pour chaque jointure. Cela ne diminue-t-il pas les performances? –

+0

Eh bien vous impliquerez une colonne supplémentaire dans votre clé [im supposant que le guid est une clé] donc vous aurez un léger changement, mais de cette façon vous ne perdez pas le guid sur les systèmes qui peuvent le supporter et vous avez une solution de contournement pour ceux qui ne le font pas. –

0

Pourquoi écrire le vôtre? Pourquoi ne pas simplement générer un nombre uniformément aléatoire? Cela fera bien le travail. Il suffit de saisir les premiers chiffres X où X est la taille que vous voulez ... disons 64 bits.

Voir here infos sur RAND() vs NEWID() dans SQL Server, ce qui est vraiment juste un acte d'accusation contre GUIDs générateurs de nombres aléatoires. Aussi, voir here si vous avez besoin de quelque chose de plus aléatoire que System.Random.

+0

Des nombres complètement aléatoires ne sont pas une bonne idée, à mon humble avis. Je ne veux pas m'inquiéter des doublons et des erreurs étranges que la base de données devient de plus en plus grande. Au moins un horodatage doit être intégré d'une manière ou d'une autre. Bien qu'en y réfléchissant, il pourrait être plus sage de laisser les secondes et d'augmenter simplement la taille de l'entier aléatoire. De cette façon, je peux avoir un hash de nom d'hôte assez long et un nombre aléatoire assez long. –

Questions connexes