Какая правильная абстракция для хранения набора значений перечисления postgres для повторного использования? - PullRequest
2 голосов
/ 21 февраля 2020

У меня есть следующее перечисление и таблица:

CREATE TYPE public.event_type as ENUM (
  'eat_apple',
  'eat_banana',
  'brush_teeth'
);

CREATE TABLE public.events (
  id integer not null,
  type public.event_type,
  created_at timestamp without time zone
);

У меня есть много запросов к этой таблице, которые касаются только подмножества типов событий (eat_apple и eat_banana).

Я мог бы написать каждый из этих запросов с предложением WHERE type IN ('eat_banana', 'eat_apple'), однако существует высокая вероятность того, что в будущем мне потребуется добавить тип события eat_pear.

Каковы доступные абстракции в Postgres для хранения подмножества этих значений перечисления для повторного использования в запросах таким образом, чтобы подмножество могло быть расширено в будущем, чтобы существующие запросы учитывали это?

Ответы [ 2 ]

6 голосов
/ 21 февраля 2020

Я бы полностью отказался от enum и сделал бы event_type правильной таблицей, содержащей флаг, если это тип по умолчанию.

create table event_type
(
  id integer primary key,
  name text not null unique,
  is_default_type boolean not null default true
);

create table events 
(
  id integer not null,
  type integer not null references event_type,
  created_at timestamp without time zone
);

Чтобы найти людей с подмножеством по умолчанию, вы можете сделать:

select e.*
from events e
  join event_type et on et.id = e.type and et.is_default_type;

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

Если вы создаете представление с использованием оператора IN вместо объединения, оно также автоматически обновляется.

2 голосов
/ 21 февраля 2020

Вы бы использовали массив типа event_type[] и изменили бы запрос на (эквивалентный)

WHERE type = ANY (array_value)

Если вы хотите использовать строковую константу, вы можете написать

WHERE type = ANY ('{eat_banana,eat_apple}'::event_type[])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...