2017-02-09 8 views
2

Я использую хэш-алгоритм для создания первичного ключа для таблицы базы данных. Я использую алгоритм SHA-1, который более чем подходит для моих целей. База данных даже отправляет реализацию для SHA-1. Функция, вычисляющая хеш, возвращает шестнадцатеричное значение как 40 символов. Поэтому я храню шестнадцатеричные символы в столбце char(40).Хранить SHA-1 в базе данных в меньшем пространстве, чем 40 шестнадцатеричных цифр

В таблице будет много строк,> = 200 Mio. строк, поэтому я ищу менее важные для хранения данных способы хранения хэша. 40 символов раз ~ 200 Mio. строки потребуют некоторого ГБ хранилища ... Так как hex - base16, я думал, что могу попытаться сохранить его в базе 256 в надежде уменьшить количество символов, необходимое примерно для 20 символов. У вас есть советы или документы по реализации сжатия с базой 256?

+2

Я думаю, что это вопрос программирования, который не соответствует теме. Объект, который вы пытаетесь сохранить, - это 160-битное число, и вы должны просто сохранить его как 160-битное число, вместо того, чтобы хранить его шестнадцатеричные цифры в виде строки. (Аналогично, если вы пытались сохранить десятизначное число из 5 цифр, вы сохранили бы его в 'int', а не в' char [5] '.) –

+0

@DavidRicherby Я не могу сохранить его' int', поскольку Мне нужен ключ без конфликтов, а выход хеширования - 'char (40)'. Я считаю, что сохранение шестнадцатеричной строки в int потребует больше байтов, так как число будет очень большим. –

+0

Несомненно, 'int' не будет содержать 160-битное число. Но хранение данных в каком-то целочисленном формате будет занимать меньше места, а не больше.позволит хранить 8 бит на байт, тогда как сохранение его в виде строки дает вам четыре бита полезных данных на каждый байт (и меньше, если базовая система использует 16-разрядный набор символов). –

ответ

2

Значение SHA-1 составляет 20 байт. Все биты в этих 20 байтах значительны, их невозможно сжать. Сохраняя байты в шестнадцатеричной нотации, вы теряете половину пространства - для хранения байта требуется ровно две шестнадцатеричные цифры. Таким образом, вы не можете сжать базовое значение, но вы можете использовать лучшую кодировку, чем шестнадцатеричную.

Storing as a blob - правильный ответ. Это база 256. Вы храните каждый байт в качестве этого байта без кодировки, которая создавала бы некоторые накладные расходы. Пустое пространство: 0.

Если по какой-то причине вы не можете этого сделать, и вам нужно использовать печатную строку, то вы можете сделать лучше, чем шестнадцатеричный, используя более компактную кодировку. С шестнадцатеричным значением требование хранения в два раза меньше (при условии, что каждый символ хранится как один байт). Вы можете использовать Base64, чтобы довести требования к хранению до 4 символов на 3 байта, т. Е. Вам потребуется 28 символов для сохранения значения. На самом деле, учитывая, что вы знаете, что длина составляет 20 байт, а не 21, кодировка base64 всегда будет заканчиваться =, поэтому вам нужно только сохранить 27 символов и восстановить завершающий = перед декодированием.

Вы можете улучшить кодирование, используя большее количество символов. Base64 использует 64 кодовых пункта из доступных 256 байтовых значений. ASCII (де-факто портативный) имеет 95 печатных символов (включая пробел), но нет общей кодировки «base95», вам придется сворачивать самостоятельно. Base85 является промежуточным выбором, он действительно используется на практике и позволяет хранить 20-байтовое значение в 25 печатных символах ASCII.

2
  • магазин это как сгустка: хранящий 8 бит данных для одного символа вместо 4 является сжатием 2x (вам нужен способ, чтобы преобразовать его, хотя),
  • Отрежьте несколько символов: У вас есть 160 бит, но для уникальных ключей достаточно 128 бит, даже если юниверс закончится, и для большинства целей будет достаточно 80 бит (вам не нужна криптографическая защита). Если у вас есть алгоритм против столкновения, достаточно использовать 36 или 40 бит.
+0

Но сохраните вещи в перспективе: 20 байтов сохранены значительно по сравнению с типичным общим размером строки? – TripeHound

+0

К сожалению, я не могу хранить его как BLOB. У меня есть CHAR, VARCHAR, DECIMAL, DATE, TIMESTAMP, BOOLEAN и GEOMETRY. –