我尝试了两种方法。
第一种方法:创建一个新的枚举并添加新值,然后直接在原位切换数据类型:
-- 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;
方法二:使用一个临时列
-- 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;
两种情况下,锁定(s)被创建并使我的应用程序崩溃。我认为第二种方法比第一种表现更好,但停机时间仍然无法接受。该表有数百万行。
请注意,我非常愿意使用除ENUM之外的其他东西--我正在考虑创建一个"物种(Species)"表,并在"动物(Animals)"中添加一个外键"species_id",但据我所知,这将创建相同的锁定问题(并且由于引入了新的外键约束,可能会更糟)。
感谢任何帮助!