Тип данных uuid
будет отлично подходят для выполнения этой задачи. Он занимает всего 16 байтов, а не 37 байтов в оперативной памяти для представления varchar
или text
. (Или 33 байта на диске, но нечетное число потребует заполнения во многих случаях, чтобы эффективно сделать его 40 байтов.) И у uuid
типа есть еще некоторые преимущества.
Пример:
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash
Подробности и подробное объяснение:
Вы можете рассмотреть другие (более дешевые) хеш-функции, если вам не нужен криптографический компонент md5, но я бы остановился на md5 для вашего случая использования (в основном только для чтения).
Слово предупреждения : В вашем случае ( immutable once written
) а функционально зависит (псевдо-натуральный) PK прекрасно. Но то же самое было бы болью, где возможны обновления text
. Подумайте об исправлении опечатки: PK и все зависимые от него индексы, столбцы FK dozens of other tables
и другие ссылки также должны быть изменены. Разворот таблиц и индексов, проблемы с блокировками, медленные обновления, потерянные ссылки, ...
Если text
может измениться в нормальной работе, суррогатное ПК будет лучшим выбором. Я предлагаю bigserial
столбец (диапазон -9223372036854775808 to +9223372036854775807
- это девять квинтиллионов двести двадцать три квадриллиона триста семьдесят два триллиона тридцать шесть с лишним миллиардов ) различных значений billions of rows
. В любом случае это может быть хорошей идеей : 8 вместо 16 байтов для десятков столбцов и индексов FK!). Или случайный UUID для гораздо больших мощностей или распределенных систем. Вы всегда можете сохранить указанный md5 (as uuid
) дополнительно, чтобы быстро найти строки в главной таблице из исходного текста. Связанный:
Что касается вашего запроса :
Чтобы ответить на комментарий @ Daniel : Если вы предпочитаете представление без дефисов, удалите дефисы для отображения:
SELECT replace('90b7525e-84f6-4850-c2ef-b407fae3f271', '-', '')
Но я бы не стал беспокоиться. Представление по умолчанию просто отлично. И проблема действительно не в представлении здесь.
Если другие партии должны использовать другой подход и добавлять строки без дефисов, это тоже не проблема. Postgres принимает несколько разумных текстовых представлений в качестве входных данных для a uuid
. Документация :
PostgreSQL также принимает следующие альтернативные формы для ввода: использование цифр в верхнем регистре, стандартный формат, заключенный в фигурные скобки, пропуск некоторых или всех дефисов, добавление дефиса после любой группы из четырех цифр. Примеры:
A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
Более того, эти md5()
функции возвращаются text
, вы будете использовать , decode()
чтобы преобразовать в bytea
и представление по умолчанию , что это:
SELECT decode(md5('Store hash for long string, maybe for index?'), 'hex')
\220\267R^\204\366HP\302\357\264\007\372\343\362q
Вы должны были бы encode()
снова получить исходное текстовое представление:
SELECT encode(my_md5_as_bytea, 'hex');
В довершение всего, значения, хранящиеся как bytea
, занимают 20 байт в ОЗУ (и 17 байт на диске, 24 с заполнением ) из-за внутренних varlena
издержек , что особенно неблагоприятно для размера и производительности простых индексов.
Все работает в пользу uuid
здесь.