sql >> Base de Datos >  >> RDS >> PostgreSQL

convertir el tipo de datos MySQL SET a Postgres

Podría usar una matriz para la columna y un operador "está contenido en" para la restricción CHECK:

create table pancakes (
    color varchar(10)[] not null,
    check (color <@ ARRAY['red', 'green', 'blue']::varchar[])
);

Y luego suceden cosas como esta:

=> insert into pancakes values (ARRAY['red']);
INSERT 0 1
=> insert into pancakes values (ARRAY['red','green','blue']);
INSERT 0 1
=> insert into pancakes values (ARRAY['red','green','blue','black']);
ERROR:  new row for relation "pancakes" violates check constraint "pancakes_color_check"
=> select * from pancakes;
      color       
------------------
 {red}
 {red,green,blue}
(2 rows)

Esto permitirá {red,red} aunque en la columna; si no permite {red,red} es importante, entonces podría agregar una función para verificar valores de color únicos en la matriz y ajustar la restricción CHECK:

create function has_unique_colors(varchar[]) returns boolean as $$
    select (select count(distinct c) from unnest($1) as dt(c)) = array_length($1, 1);
$$ language sql;

create table pancakes (
    color varchar(10)[] not null,
    check (color <@ ARRAY['red', 'green', 'blue']::varchar[] and has_unique_colors(color))
);

Otra opción sería un montón de tablas de asociación con valores escalares simples en las columnas. Sin embargo, esto puede ser engorroso si tiene seis de estas columnas. También podría usar la versión de la función de Erwin si necesita preocuparse por los valores NULL en los "conjuntos":

create function has_unique_colors(varchar[]) returns boolean as $$
    select not exists(select c from unnest($1) dt(c) group by 1 having count(*) > 1);
$$ language sql;