Существует ли простой способ создать уникальный целочисленный ключ из составного ключа с двумя целыми числами?

public override int GetHashCode()
{
    unchecked
    {
        return (str1 ?? String.Empty).GetHashCode() +
            (str2 ?? String.Empty).GetHashCode();
    }
}

Используя '+' оператор мог бы быть лучше, чем использование '^ ', потому что, хотя Вы явно хотите ('AA', 'BB') и ('BB', 'AA') явно быть тем же, Вы не можете хотеть ('AA', 'AA') и ('BB', 'BB') быть тем же (или все равные пары в этом отношении).

'максимально быстро' правило не полностью придерживается к в этом решении, потому что в случае пустых указателей это выполняет 'GetHashCode ()' на пустой строке, а не сразу возвратите известную константу, но даже явно не имея размеры я готов рисковать предположением, что различие не было бы достаточно большим для волнения о том, если Вы не ожидаете много пустых указателей.

5
задан abeger 16 November 2009 в 22:20
поделиться

8 ответов

Умножьте единицу на достаточно высокое значение

SELECT id1 * 1000000 + id2

Или используйте конкатенацию текста:

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

Или пропустите целое число и разделите идентификаторы чем-то нечисловым:

SELECT CAST(id1 AS nvarchar) + ':' + CAST(id2 AS nvarchar)
2
ответ дан 18 December 2019 в 05:36
поделиться

Вы можете математически доказать, что это невозможно, если вы хотите, чтобы результирующий ключ содержал то же количество битов, что и два его компонента. Однако, если вы начнете с двух 32-битных int и можете использовать для результата 64-битное int, вы, очевидно, можете сделать что-то вроде этого:

key1 << 32 | key2
21
ответ дан 18 December 2019 в 05:36
поделиться

Вы можете сделать это, только если у вас есть верхняя граница для одного из ключей. Предположим, у вас есть key1 и key2 , а up1 - это значение, которое никогда не достигнет key1 , тогда вы можете комбинировать ключи следующим образом :

combined = key2 * up1 + key1;

Даже если ключи теоретически могут неограниченно расти, обычно на практике можно оценить верхнюю границу сохранения.

2
ответ дан 18 December 2019 в 05:36
поделиться

Оба предлагаемых решения требуют некоторых знаний о диапазоне принимаемых ключей.

Чтобы избежать этого предположения, можно перемешать цифры вместе.

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

Если не хватает цифр, можно использовать заполнение нулями:

Key1 = 12345, Key2 = 1 => 1020304051

Этот метод также универсален для любого количества ключей.

1
ответ дан 18 December 2019 в 05:36
поделиться

Рискну показаться шутливым:

NewKey = fn(OldKey1, OldKey2)

где fn () - это функция, которая ищет новое значение ключа с автоматической нумерацией из столбца, добавленного к существующей таблице.

Очевидно, два Целочисленные поля могут содержать экспоненциально больше значений, чем одно целочисленное поле.

0
ответ дан 18 December 2019 в 05:36
поделиться

Почему бы вам просто не использовать ROW_NUMBER () или IDENTITY (int , 1,1) установить новый ID? Они ДЕЙСТВИТЕЛЬНО должны быть в отношениях?

0
ответ дан 18 December 2019 в 05:36
поделиться

Поскольку мне нравится теоретическая сторона вашего вопроса (она действительно прекрасна), и чтобы опровергнуть то, что говорят многие практические ответы, я хотел бы дать ответ на «математическую» часть ваших тегов :)

Фактически возможно сопоставить любые два числа (или фактически любую серию чисел) одному числу. Это число называется числом Гёделя и было впервые опубликовано в 1931 году Куртом Гёделем.

Чтобы дать быстрый пример, с вашим вопросом; скажем, у нас есть две переменные v1 и v2. Тогда v3 = 2 v1 * 3 v2 даст уникальный номер. Этот номер также однозначно идентифицирует v1 и v2.

Конечно, результирующее число v3 может расти нежелательно быстро. Пожалуйста, примите этот ответ как ответ на теоретический аспект вашего вопроса.

1
ответ дан 18 December 2019 в 05:36
поделиться

This has been discussed in a fair amount of detail already (as recursive said, however, the output must be comprised of more bits than the individual inputs).

Mapping two integers to one, in a unique and deterministic way

How to use two numbers as a Map key

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

4
ответ дан 18 December 2019 в 05:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: