Pour diverses raisons qui ne sont pas trop utiles à la question, j'ai une table avec une clé composite composée de deux entiers et je souhaite créer une clé unique unique de ces deux chiffres. Ma pensée initiale était de les concaténer, mais j'ai rencontré rapidement un problème lorsque je me suis rendu compte qu'une clé composite de (51,1) entraînerait la même clé unique que (5,11), à savoir 511. P >
Est-ce que quelqu'un a un moyen intelligent de générer un entier sur deux entiers de sorte que l'entier généré soit unique à la paire d'entiers de départ? P>
edit: strong> Après avoir été confronté à une quantité impressionnante de mathématiques, je me rends compte qu'un détail que j'aurais dû inclus est la taille des clés en question. Dans la paire d'origine, la première clé est de 6 chiffres et restera probablement dans 7 chiffres pour la vie du système; La deuxième clé n'a pas encore atteint de plus de 20 ans. Compte tenu de ces contraintes, on dirait que le problème est beaucoup moins décourageant. P>
9 Réponses :
Vous pouvez prouver mathématiquement cela est impossible si vous souhaitez que la clé résultante comprend le même nombre de bits que ses deux composants. Toutefois, si vous commencez avec deux INT 32 bits et pouvez utiliser un Int 64 bits pour le résultat, vous pouvez évidemment faire quelque chose comme ceci: Syntaxe SQL P> SELECT key1 * POWER(2, 32) + key2
Cette. Bien sûr, assurez-vous d'inclure des chèques de santé mentale sur les deux entiers pour vous assurer qu'ils sont tous deux 32 bits. (En supposant que vous utilisiez des entiers signés, ils devront être inférieurs à 2 ^ 31, à 2 147 483 648).
Malheureusement, je le fais dans T-SQL et je manque un opérateur bossu.
Puis simulez cette mère avec une multiplication. :-) Je pense que "Key1 * 2 ^ 32" accomplit la même chose, mais mes mathématiques sont un TAD Rusty.
De dbaspot.com/forums/sqlserver-programming / ... , pour atteindre @i << @j code>:
Sélectionnez @I * Power (2, @j) Code>
+1 Même si si key1 code> est un entier 32 bits, alors
key1 << 32 == 0 code> (vous devez la jeter à 64 bits d'abord)
Ceci a été discuté dans une juste quantité de détails déjà (comme ledite récursif, toutefois, la sortie doit être comprise en plus de bits que les entrées individuelles). P>
cartographier deux entiers à un, dans une manière unique et déterministe p>
Comment utiliser deux numéros comme clé de carte a> p>
http://fr.wikipedia.org/wiki/cantor_pairing_funcuncunction_pairing_function p>
Assez compliqué. Ces réponses me sont perdues à "Bijectif". : p
@TCHALVAK: Si vous n'êtes pas une grande partie d'une personne mathématique, gardez simplement Wikipedia-ing les termes que vous ne connaissez pas! (Personnellement, j'aime vraiment "éduquer" moi-même avec ce genre de procrastination productive.) Cela se résume à des trucs assez simples; L'utilisation des mots mathématiques de fantaisie conserve simplement les définitions concises et exactes.
au risque de retenue facétieuse: où Fn () est une fonction qui lève une nouvelle valeur de clé auto-au-dessus d'une colonne ajoutée à votre table existante. P> < P> Évidemment, deux champs entiers peuvent contenir de manière exponentielle plus de valeurs qu'un seul champ entier. P> P>
Vous ne pouvez le faire que si vous avez une limite supérieure pour l'une des clés. Dis que vous avez même si les clés pouvaient se développer théoriquement sans limite, il est généralement possible d'estimer une limite supérieure de sauvegarde dans la pratique. P> P> key1 code> et
key2 code> et
up1 code> est une valeur que
key1 code> n'atteindra jamais, alors vous pouvez combiner Les clés comme ceci:
J'aime, plus propre que ma réponse était. Il suffit de vous assurer que vous avez toujours "encoder" les clés dans les commandes prédéfinies et "décodez" dans le même ordre.
multiplier un avec une valeur suffisamment élevée ou utilisez la concaténation du texte: p> ou ignorer la chose entier et séparer les identifiants avec quelque chose de non numérique: p>
Les deux des solutions suggérées nécessitent des connaissances sur la gamme de clés acceptées. P>
Pour éviter de faire cette hypothèse, on peut riffler les chiffres ensemble. p>
Le rembourrage zéro peut être utilisé quand il n'y a pas assez de chiffres: p>
Cette méthode est également généralisée pour un nombre quelconque de clés. P> clé1 = abc => chiffres = a, b, c code>
Key2 = 123 => chiffres = 1, 2, 3 code>
Riffle (Key1, Key2) = A, 1, B, 2, C, 3 Code> P>
clé1 = 12345, clé2 = 1 => 1020304051 code> p>
Pourquoi n'utilisez-vous pas simplement Row_Number () ou identité (int, 1,1) pour définir un nouvel identifiant? Ont-ils vraiment besoin d'être en relation? P>
Comme j'aime le côté théorique de votre question (c'est vraiment beau) et à contredire à quoi disent de nombreuses réponses pratiques, je voudrais donner une réponse à la partie "Math" de vos tags :) p>
En fait Pour donner un exemple rapide, avec votre question; Disons que nous avons deux variables v1 et v2. Alors v3 = 2 v1 sup> * 3 v2 sup> donnerait un numéro unique. Ce numéro identifie également de manière unique V1 et V2. P>
Bien sûr, le nombre résultant v3 résultant peut augmenter de manière indésirable rapide. S'il vous plaît, prenez simplement cette réponse comme une réponse à l'aspect théorique de votre question. P>
a écrit celles-ci pour mysql ils fonctionnent bien p>
Créer une fonction Créer une fonction Créer une fonction paire code> (x bigint non signé, y Bigint non signé)
Renvoie Bigint TRANSITIONNÉ DÉTERNINISTE
Retour (x + y) * (x + y + 1)) / 2 + y; p>
ReversePairx code> (Z Bigint Unsigné)
Renvoie Bigint TRANSITIONNÉ DÉTERNINISTE
Retour (plancher ((- 1 + sqrt (1 + 8 * Z)) / 2)) * ((((- 1 + sqrt (1 + 8 * z)) / 2)) + 3) / 2 - z ; p>
ReversePairy code> (Z Bigint non signé)
Renvoie Bigint TRANSITIONNÉ DÉTERNINISTE
Retour Z - (étage ((- 1 + sqrt (1 + 8 * z)) / 2)) * ((((- 1 + sqrt (1 + 8 * z)) / 2)) + 1) / 2 ; p>
Aucun DBA ne devrait vous laisser sortir avec ceci - si besoin d'être, créer une colonne de clé primark et utiliser une contrainte unique sur les deux colonnes.
Voir la réponse de Matt Ball pour des doublons