PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

convertire il tipo di dati MySQL SET in Postgres

Puoi usare un array per la colonna e un operatore "è contenuto da" per il vincolo CHECK:

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

E poi succedono cose del genere:

=> 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)

Ciò consentirà {red,red} nella colonna però; se non è consentito {red,red} è importante, quindi puoi aggiungere una funzione per verificare la presenza di valori di colore univoci nell'array e regolare il vincolo 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))
);

Un'altra opzione sarebbe una pila di tabelle di associazione con semplici valori scalari nelle colonne. Tuttavia, questo potrebbe essere ingombrante se hai sei di queste colonne. Potresti anche usare la versione di Erwin della funzione se dovessi preoccuparti dei NULL nei "set":

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;