Gibt es eine einfache Art und Weise einen einzigartigen Integer-Schlüssel von einem Zwei-Integer-Composite-Schlüssel zu erstellen?

StackOverflow https://stackoverflow.com/questions/1745048

Frage

Aus verschiedenen Gründen, die nicht zu relevant für die Frage sind, habe ich eine Tabelle mit einem zusammengesetzten Schlüssel bekam zweier ganzer Zahlen gemacht und ich möchte einen einzigen eindeutigen Schlüssel aus diesen beiden Zahlen erstellen. Mein erster Gedanke war sie nur verketten, aber ich lief in ein Problem schnell, als ich erkennen, dass ein Verbundschlüssel (51,1) in dem gleichen eindeutigen Schlüssel als (5,11) führen würde, nämlich 511.

Hat jemand eine kluge Art und Weise hat eine ganze Zahl von zwei ganzen Zahlen zu erzeugen, so dass die erzeugte ganz Zahl ist einzigartig für das Paar von Anfang ganzen Zahlen?

Edit: Nach dem mit einer beeindruckenden Menge Mathematik konfrontiert, ich erkennen, dass ein Detail, das ich habe enthalten sollte die Größen des Schlüssels in Frage. In dem Ursprungspaar ist der erste Schlüssel zur Zeit 6 Ziffern und wird wahrscheinlich in 7 Stellen für die gesamte Lebensdauer des Systems bleiben; der zweite Schlüssel muss noch größer wird als 20. diese Einschränkungen gegeben, es sieht aus wie das Problem ist viel weniger abschreckend.

War es hilfreich?

Lösung

Multiplizieren eines mit einem ausreichend hohen Wert

SELECT id1 * 1000000 + id2

oder benutzen Text Verkettung:

SELECT CAST(CAST(id1 AS nvarchar(10)) + RIGHT('000000' + CAST(id2 AS nvarchar(10)), 6) AS int)

überspringen oder die ganze Zahl Sache und trennen Sie die IDs mit etwas nicht-numerischen:

SELECT CAST(id1 AS nvarchar) + ':' + CAST(id2 AS nvarchar)

Andere Tipps

Sie können mathematisch beweisen dies nicht möglich ist, wenn Sie die resultierenden Schlüssel wollen die gleiche Anzahl von Bits wie seine beiden Komponenten umfassen. Wenn Sie jedoch mit zwei 32-Bit-Ints beginnen und kann ein 64-Bit-int für das Ergebnis verwenden, könnte man natürlich so etwas tun:

key1 << 32 | key2

in einer recht detailliert wurde bereits diskutiert (als rekursive gesagt, muss jedoch die Leistung von mehr Bits als die einzelnen Eingänge umfassen).

Mapping zwei ganze Zahlen ein, in eine einzigartige und deterministisch

Wie man verwendet zwei Zahlen als Map-Taste

http://en.wikipedia.org/wiki/Cantor_pairing_function#Cantor_pairing_function

Sie können es nur tun, wenn Sie haben eine obere für einen der Schlüssel gebunden. Angenommen, Sie haben key1 und key2 und up1 ist ein Wert, den key1 nie erreichen, dann können Sie die Tasten wie folgt kombiniert werden:

combined = key2 * up1 + key1;

Auch wenn die Tasten theoretisch unbegrenzt wachsen konnte, ist es in der Regel möglich, eine schätzen speichern oberen in der Praxis gebunden ist.

Sowohl die vorgeschlagenen Lösungen erfordern einige Kenntnisse über den Bereich der akzeptierten Schlüssel.

Um zu vermeiden, diese Annahme zu machen, kann man die Ziffern zusammen Riffle.

Key1 = ABC => Digits = A, B, C
Key2 = 123 => Digits = 1, 2, 3
Riffle(Key1, Key2) = A, 1, B, 2, C, 3

Zero-Padding kann verwendet werden, wenn es nicht genügend Ziffern sind:

Key1 = 12345, Key2 = 1 => 1020304051

Diese Methode verallgemeinert auch für eine beliebige Anzahl von Schlüsseln.

Als ich wie die theoretische Seite Ihrer Frage (es ist wirklich schön), und zu widersprechen, was viele der praktischen Antworten sagen, würde Ich mag eine Antwort auf die „Mathematik“ Teil Ihrer Tags geben:)

In der Tat ist es möglich, alle zwei Zahlen zur Karte (oder eigentlich jede Reihe von Zahlen) auf eine einzige Zahl. Dies wird in der Gödelzahl genannt und wurde erstmals im Jahr 1931 von Kurt Gödel veröffentlicht.

ein schnelles Beispiel zu geben, mit Ihrer Frage; v1 und v2 sagen wir zwei Variablen haben. Dann v3 = 2 v1 * 3 v2 würde eine eindeutige Nummer geben. Diese Zahl auch eindeutig identifiziert v1 und v2.

Natürlich ist die resultierende Zahl v3 unerwünscht schnelle wachsen. Bitte, nehmen Sie nur diese Antwort als eine Antwort auf den theoretischen Aspekt in Ihrer Frage.

schrieb diese für mysql sie funktionieren

CREATE FUNCTION pair (x BIGINT unsigned, y BIGINT unsigned) RETURNS BIGINT unsigned DETERMINISTIC RETURN ((x + y) * (x + y + 1)) / 2 + y;

CREATE FUNCTION reversePairX (z BIGINT unsigned) RETURNS BIGINT unsigned DETERMINISTIC RETURN (FLOOR ((- 1 + SQRT (1 + 8 * z)) / 2)) * ((FLOOR ((- 1 + SQRT (1 + 8 * z)) / 2)) + 3) / 2 - Z ;

CREATE FUNCTION reversePairY (z BIGINT unsigned) RETURNS BIGINT unsigned DETERMINISTIC RETURN z - (FLOOR ((- 1 + SQRT (1 + 8 * z)) / 2)) * ((FLOOR ((- 1 + SQRT (1 + 8 * z)) / 2)) + 1) / 2 ;

Auf der Gefahr der Sondierung facetious:

NewKey = fn(OldKey1, OldKey2)

Dabei gilt fn () ist eine Funktion, die Blicke auf einen neuen autonumbered Schlüsselwert aus einer Spalte zu Ihrer bestehenden Tabelle hinzugefügt.

Offensichtlich zwei Integer-Felder kann ein einzelnes Integer-Feld exponentiell mehr Werte halten als.

Warum gehst du nicht einfach verwenden ROW_NUMBER () oder IDENTITY (int, 1,1) neue ID zu setzen? Haben sie wirklich brauchen in Bezug auf sein?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top