PostgreSQL имеет специальный тип данных, который называется enum и который представляет набор констант. И столбец подобного типа может в качестве значения принимать одну из этих констант. Рассмотрим, как использовать перечисления.
Для создания перечисления используется команда CREATE TYPE. Например, создадим простейшее перечисление:
create type request_state as enum ('created', 'approved', 'finshed');
Данное перечисление называется "request_state". После слова enum в скобках указывается через запятую список констант, которые составляют данное перечисление. То есть в данном случае перечисление request_status может принимать три значения: 'created', 'approved', 'finshed'.
После создания перечисления мы можем использовать его в качестве типа столбца. Например, создадим следующую таблицу:
create table requests( id serial primary key, title varchar(30), status request_state );
Здесь третий столбец - status представляет перечисление request_state и может принимать одно из трех выше указанных значений. Поэтому при добавлении данных нужно указать для данного столбца одно из этих трех значений:
insert into requests(title, status) values ('Request 1', 'created');
При этом важно, что столбец может иметь только одно из этих трех значений, а не какие-то произвольные значения. Кроме того, большую роль играет регистр символов, например, "created" не эквивалентно "Created".
При обновлении данных также необходиом предоставить одно из значений перечисления:
update requests set status='approved' where id=1;
После создания перечисления вполне возможно нам захочется его изменить, например, добавить новое значение. Для этого применяется команда ALTER TYPE.
Добавление нового значения:
ALTER TYPE request_state ADD VALUE 'blocked';
К сожалению, удалить так просто уже имеющееся значение из перечисления не получится. В этому случае мы можем создать новое перечисление и указать, чтобы таблица использовала именно новое перечисление:
CREATE TYPE status_enum AS ENUM('created', 'approved', 'done'); ALTER TABLE requests ALTER COLUMN status TYPE status_enum USING status::text::status_enum;
Если перечисление больше не нужно, то с помощью команды DROP TYPE его можно удалить:
DROP TYPE request_state;