Как добавить новое значение в ENUM в Postgres, не блокируя таблицу? - PullRequest
2 голосов
/ 08 июля 2019

Я испробовал два подхода.

Подход 1: Создайте новый ENUM с добавленным новым значением и переключите тип данных на место:

-- Rename existing enum
ALTER TYPE animal_species RENAME TO animal_species_old;

-- Create new enum with new value
CREATE TYPE animal_species AS ENUM (
  'dog',
  'cat',
  'elephant'
);

-- Update the column of Animals to use the new enum
ALTER TABLE "Animals" ALTER COLUMN species SET DATA TYPE animal_species USING species::text::animal_species;

DROP TYPE animal_species_old;

Подход 2: Используйтевременный столбец

-- Create new enum type with a new name (this will be the name of the enum from now on)
CREATE TYPE animal_type_enum AS ENUM (
  'dog',
  'cat',
  'elephant'
);

-- Create a temporary column
ALTER TABLE "Animals" ADD COLUMN species_new animal_species_enum;

-- Copy existing species into new column
UPDATE "Animals" SET species_new = species::text::animal_species_enum;

-- Drop old species column
ALTER TABLE "Animals" DROP COLUMN species;

-- Rename new column
ALTER TABLE "Animals" RENAME COLUMN species_new TO species;

-- Drop old enum
DROP TYPE animal_species;

В обоих случаях блокировки были созданы и закрыли мое приложение.Я считаю, что второй способ показал лучшие результаты, чем первый, но время простоя по-прежнему было неприемлемым.Таблица состоит из миллионов строк.

Обратите внимание, что я очень открыт для использования чего-то другого, кроме ENUM - я думал о создании таблицы "Species" с внешним ключом "видов_идей" в "«Животные», но, насколько я могу судить, это создаст такую ​​же проблему с блокировкой (и может быть еще хуже, если ввести новое ограничение внешнего ключа).

Спасибо за любую помощь!

1 Ответ

3 голосов
/ 09 июля 2019

Подход 3, просто добавьте новое значение в перечисление:

ALTER TYPE animal_type_enum ADD VALUE 'snake';

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

Добавление нового значения - это простая операция INSERT, которая ничего не блокирует ( особенно не таблица, ссылающаяся на таблицу поиска).

Хотя проверки внешнего ключа действительно увеличивают накладные расходы, они не должны иметь такого большого значения (при условии правильной индексации столбца FK), если вы не выполняете массовые операции INSERT или DELETE очень часто.

Для однострочных INSERT или DELETE (или только для «сотен» строк) вы, вероятно, даже не заметите накладных расходов при поиске в FK - особенно если таблица поиска мала и содержит всего несколько строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...