Плюсы и минусы использования хэша MD5 в качестве первичного ключа по сравнению с использованием идентификатора int в качестве первичного ключа в SQL Server



У меня есть приложение, которое обрабатывает файл и фрагментирует его на несколько сегментов, а затем сохраняет результат в базе данных sql server. Существует много дублированных файлов (возможно, с разными путями к файлам), поэтому сначала я просматриваю все эти файлы и вычисляю хэш Md5 для каждого файла, а затем помечаю дублированный файл с помощью столбца [Duplicated].



Затем каждый день я буду запускать это приложение и сохранять результаты в таблицу [Result].
Схема БД выглядит следующим образом:



    CREATE TABLE [dbo].[FilePath]
(
[FilePath] NVARCHAR(256) NOT NULL PRIMARY KEY,
[FileMd5Hash] binay(16) NOT NULL,
[Duplicated] BIT NOT NULL DEFAULT 0,
[LastRunBuild] NVARCHAR(30) NOT NULL DEFAULT 0
)

CREATE TABLE [dbo].[Result]
(
[Build] NVARCHAR(30) NOT NULL,
[FileMd5Hash] binay(16) NOT NULL ,
[SegmentId] INT NOT NULL,
[SegmentContent] text NOT NULL
PRIMARY KEY ([FileMd5Hash], [Build], [SegmentId])
)


И у меня есть требование соединить эти 2 таблицы на FileMd5Hash.



Поскольку число строк [Result] очень велико, я хотел бы добавить столбец идентификатора int, чтобы соединить их с таблицами, как показано ниже:



    CREATE TABLE [dbo].[FilePath]
(
[FilePath] NVARCHAR(256) NOT NULL PRIMARY KEY,
[FileMd5Hash] binay(16) NOT NULL,
**[Id] INT NOT NULL IDENTITY,**
[Duplicated] BIT NOT NULL DEFAULT 0,
[LastRunBuild] NVARCHAR(30) NOT NULL DEFAULT 0
)

CREATE TABLE [dbo].[Result]
(
[Build] NVARCHAR(30) NOT NULL,
**[Id] INT NOT NULL,**
[SegmentId] INT NOT NULL,
[SegmentContent] text NOT NULL
PRIMARY KEY ([FileMd5Hash], [Build], [SegmentId])
)


Итак, каковы плюсы и минусы этих двух способов?

650   3  

3 ответов:

Ключ int проще реализовать и легче использовать и понимать. Он также меньше (4 байта против 16 байт), поэтому индексы будут соответствовать примерно двойному количеству записей на странице ввода-вывода, что означает лучшую производительность. Строки таблицы тоже будут меньше (хорошо, не намного меньше), так что снова вы поместите больше строк на страницу = меньше ввода-вывода.

Хэш всегда может привести к конфликтам. Хотя и чрезвычайно редко, тем не менее, как показывает проблема дня рождения , столкновения становятся все более и более вероятными, поскольку количество записей увеличивается. Количество элементов, необходимых для 50% вероятности столкновения с различными хэшами битовой длины, выглядит следующим образом:

Hash length (bits)   Item count for 50% chance of collision
                32   77000
                64   5.1 billion
               128   22 billion billion
               256   400 billion billion billion billion

Существует также проблема передачи байтов, отличных от ascii, - сложнее отлаживать, отправлять по проводу и т. д.

Используйте int последовательные первичные ключи для ваших таблиц. Как и все остальные.

Используйте ints для первичных ключей, а не хэши. Все предупреждают о коллизиях хэшей, но на практике они не являются большой проблемой; легко проверить наличие коллизий и повторного хэша. Последовательные идентификаторы также могут сталкиваться, если вы объединяете базы данных.

Большая проблема с хэшами как ключами заключается в том, что вы не можете изменить свои данные. Если вы попытаетесь, ваш хэш изменится, и все внешние ключи станут недействительными. Вам нужно создать столбец "нет, это настоящий хэш" в вашей базе данных, и ваш старый хэш просто станет большим непоследовательное целое число.

Держу пари, что ваш бизнес-аналитик скажет :" мы внедряем червя, поэтому наши записи никогда не изменятся". Они будут доказаны неправыми.

Вот очень хорошая статья, объясняющая плюсы и минусы использования обоих:

Http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html

Использование хэша MD5 будет похоже на использование GUID для вашего первичного ключа. Хэш-коллизии редки, но случаются, вы можете захотеть справиться с ними.

Я лично пойду с идентичностью INT, но она может отличаться в зависимости от вашей реализации.

Comments

    Ничего не найдено.