Тип даних 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) функціонально залежний (псевдо-природний) ПК є нормальним. Але те саме було б болем, коли 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 приймає кілька розумних подань тексту як вхідні дані для 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.