Есть простая задача, в таблице лежат данные для разных типов сущностей. К примеру, есть таблица комментариев, и в ней хранятся комментарии для постов, фотографий, видео.
В таблице есть два поля, которые отвечают за сущность entity_id – это id сущности, и entity_type – тип сущности (пост, фото, видео).
Поле entity_id – само собой int (bigint NOT NULL)
А вот поле entity_type вызывает у меня сомнения. Сейчас я сделал их типа enum (character varying(255) NOT NULL) CONSTRAINT comments_entity_type_check CHECK (entity_type::text = ANY (ARRAY['post'::character varying, 'image'::character varying, 'video'::character varying]::text[]))
Но сомневаюсь в производительности такого подхода. Не лучше сделать entity_type -
small int? Как бы с int и проще индекс строить, а с другой стороны enum ограничивает возможные варианты.
Если ли большой выигрыш в производительности между enum и small int?
Это реализация для PostgreSQL до версии 9.2 в котором нет типа ENUM.
В любом случаи это строковое поле с ограниченным вариантом ввода. Если даже строить индекс по типу ENUM который вы привели, это будет производительней smallint?
Скажу больше в 8.3 был enum.
А по производительности вам нужно конкретно смотреть на вашей ( видимо древней ) версии, что быстрее. Из общих соображений - отказ от ненужных констрейнтов ( aka system-level триггеров ) дело хорошее, а будет ли 2-хбайтовый тип заметно быстрее 4-хбайтового ( enum ) совсем неизвестно. Мой хрустальный шар подсказывает, что в реальном случае будет примерно ничья, но для enum мы бесплатно получаем типобезопасность.
В любом случаи это строковое поле
Числовое поле. То, что вам для удобства отображения подставляется строчка - это на свойства хранения не влияет.
AnjeyTsibylskij: Индексы в принципе не очень эффективны для данных с низкой селективностью. Например, если у вас из тысячи записей 600 будут с типом "пост", то поиск по индексу всех этих записей скорее всего будет менее эффективным, чем без индекса.
Впрочем, в каждом конкретном случае нужно проверять.
Примеры в статье
> Если ли большой выигрыш в производительности между enum и small int?
Есть выигрыш в логике от подхода с enum, тип удобно использовать как сущность в функциях.
Ещё можно объеденить entity_id и entity_type в одну колонку (bigint),
если нужно джойнить, то можно использовать уникальные ид по всей базе (префиксные ид),
так же будет удобно ссылаться на объекты из других мест просто одним числом, без указания типа, т.к. тип зашит в ид.