2010-10-28 3 views
2

В настоящее время мы широко используем метод GetHashCode для хранения хэш-кодов в базе данных для отслеживания уникальных элементов. MSDN имеет ужасную запись об этом здесьИспользование ToHashCode для хранения хэша в базе данных?

«Реализация метода GetHashCode по умолчанию не гарантирует уникальные возвращаемые значения для разных объектов. Кроме того, .NET Framework не гарантирует стандартную реализацию метода GetHashCode, а значение он будет одинаковым для разных версий .NET Framework. Следовательно, реализация этого метода по умолчанию не должна использоваться как уникальный идентификатор объекта для целей хэширования. "

Мы использовали этот подход в течение нескольких лет без проблем. Должны ли мы волноваться, и если да, то какой будет лучший подход?

Чтобы уточнить, данные поступают из внешнего источника. Мы берем от двух до трех строковых полей, добавляя их вместе в новую строку, а затем используем GetHashCode.

ответ

2

Использование хеш-кода в качестве уникального идентификатора - действительно плохая идея, потому что в конечном итоге у вас есть коллизии, если коллекция достаточно велика - и она не должна быть очень большой, статистически, вероятно, столкновение. Хэш-коды - это хороший, быстрый способ оценить, совпадают ли два объекта (при использовании одной и той же хеш-функции) - если они имеют разные значения, они совершенно разные. Однако, если они имеют хеш с одним и тем же значением, вам необходимо выполнить сравнение равенства, чтобы убедиться, что они являются одним и тем же объектом. В этот момент вам нужно сравнить свойства объекта, которые делают его уникальным, т. Е. Если эти свойства одинаковы, то объекты одинаковы.

Я бы предложил использовать уникальный индекс в базе данных о свойствах естественного ключа в сочетании с искусственным идентификатором автоинкремента в качестве первичного ключа. Тогда вы можете быть уверены, что не получаете дубликатов в БД (ограничение уникальности индекса), но вы можете быстро сравнивать объекты за пределами БД, просто сравнивая, имеют ли они один и тот же идентификатор - также гарантированно будут уникальными с помощью ограничения первичного ключа.

2

Да. Бояться. GetHashCode не может гарантировать гарантию отсутствия столкновений на любом типе, превышающем 32 бит. Учитывая, что в некоторых случаях реализация GetHashCode может быть менее совершенной (т. Е. Некоторые классы реализуют свою собственную нераспределенную версию), риск может быть выше в некоторых случаях. Несмотря на это, это плохой подход и нуждается в переосмыслении.

Я бы посоветовал немного прочитать о том, как работают таблицы хэшей, чтобы вы лучше понимали цель хеш-кода. Это действительно только эвристическая мера для быстрого хранения.

0

GetHashCode не является надежным.

У вас есть два варианта в этой связи:

  1. переопределять метод GetHashCode и он возвращает Guid вместо целого.
  2. Позвольте вашей БД создать уникальные значения id для вас.
+1

Неправильное присвоение GetHashCode для возврата различных значений между вызовами является ужасной идеей и будет ломаться намного больше, чем исправления. Вариант 2 избавляет вас от -1. – spender

+0

hmm ... кажется странным, поскольку MSDN рекомендует переопределять GetHashCode, чтобы гарантировать, что он возвращает уникальные значения. –

+0

, но вы должны возвращать одно и то же уникальное значение для объекта каждый раз. Каждый новый алгоритм будет нарушать это.Выяснение того, как получить один и тот же Guid каждый раз, намного больше, чем использование детерминированного алгоритма для построения уникального значения для сложного объекта. – tvanfosson

Смежные вопросы