PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

convertir le type de données MySQL SET en Postgres

Vous pouvez utiliser un tableau pour la colonne et un opérateur "est contenu par" pour la contrainte CHECK :

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

Et puis des choses comme ça arrivent :

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

Cela permettra à {red,red} dans la colonne cependant; si vous n'autorisez pas {red,red} est important, vous pouvez ajouter une fonction pour vérifier les valeurs de couleur uniques dans le tableau et ajuster la contrainte 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))
);

Une autre option serait une pile de tables d'association avec des valeurs scalaires simples dans les colonnes. Cependant, cela peut être fastidieux si vous avez six de ces colonnes. Vous pouvez également utiliser la version d'Erwin de la fonction si vous avez besoin de vous soucier des valeurs NULL dans les "sets" :

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;