Какой тип данных наиболее подходит для столбца таблицы?

В настоящее время я пытаюсь разработать схему базы данных PostgreSQL, в ней всего 2 таблицы, одна из которых содержит имена пользователей. Сложность в том, что по определенным причинам я не могу хранить имя пользователя напрямую, поэтому мне приходится хранить хэш (SHA256).

Postgres имеет тип данных bytea, который представляет собой массив байтов, технически это SHA256.

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

Возможно, стоит посмотреть в сторону NoSQL-решений, там такой поиск быстрее?

-----Добавлять-----

Ответ и комментарии подсказывают, что оптимально использовать bytea.

CREATE TABLE users (
    username bytea PRIMARY KEY,
    somedata text NOT NULL
);

Если вы ищете точные совпадения, не могли бы вы просто хешировать входное имя пользователя для поиска, а затем сравнивать его со столбцом? Или здесь будут другие сценарии поиска?

Tim Biegeleisen 04.07.2024 11:48

Да, я ищу точные совпадения, и да, имя пользователя будет хешировано на стороне клиента. Но что, если я выберу CHAR(64) вместо bytea? Или, может быть, что-то еще?

bylazy 04.07.2024 12:04
bytea — вероятно, самый компактный способ хранения хеша.
Tim Biegeleisen 04.07.2024 12:07
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вероятно, это микрооптимизация, но bytea будет занимать значительно меньше места и выполнять сравнение быстрее.

Если вы в конечном итоге используете text (избегайте character), убедитесь, что вы используете сопоставление C:

hash_value text COLLATE "C"

Другие сопоставления приведут к гораздо более дорогостоящим сравнениям.

Почему bytea — это микрооптимизация? 32 байта против 64 байтов кажутся существенной разницей, если они используются в качестве индексного ключа.

Charlieface 04.07.2024 14:00

@Charlieface Возможно, моя формулировка была не очень хороша. Я не думаю, что производительность будет сильно отличаться (используя сопоставление C). Разница в хранении может быть значительной.

Laurenz Albe 04.07.2024 14:16

Дважды длиннее = вдвое больше времени для проверки равенства в btree, а загрузка и сохранение также будут длиннее. Я не понимаю, почему производительность не станет немного медленнее.

Charlieface 04.07.2024 14:30
Ответ принят как подходящий

Попробуйте. Как вы и подозревали и как уже подтвердили в комментариях и ответе от @Laurenz Albe, bytea выигрывает, будучи самым компактным и быстрым для поиска.

Вот как сравнивается хранение 400 тыс. хэшей:

вариант pg_total_relation_size pg_size_pretty таблица1_bytea 48709632 46 МБ таблица2_текст 75530240 72 МБ table3_text_collate_c 75522048 72 МБ

И вот сколько времени нужно, чтобы его найти:

вариант среднее hashes_in_bytea 00:00:00.00003 hashes_in_text_collate_c 00:00:00.000035 hashes_in_text 00:00:00.000042 hashes_in_text_otf 00:00:00.00011

хэш-индекс, потому что меня интересуют только проверки на равенство

Вы не можете использовать using hash для уникальных индексов, поэтому вам нужно будет поддерживать и его, и отдельный уникальный индекс, который создается для обработки ограничения UNIQUE в вашем username столбце. Я бы просто придерживался уникального значения по умолчанию, которое у вас уже есть.

Кроме того, хеш-индексы не работают быстрее.

Laurenz Albe 04.07.2024 15:15

Другие вопросы по теме