PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Konvertieren Sie den MySQL SET-Datentyp in Postgres

Sie könnten ein Array für die Spalte und einen „ist enthalten von“-Operator für die CHECK-Einschränkung verwenden:

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

Und dann passieren solche Dinge:

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

Dies erlaubt {red,red} in der Spalte aber; wenn {red,red} nicht zugelassen wird wichtig ist, dann könnten Sie eine Funktion hinzufügen, um nach eindeutigen Farbwerten im Array zu suchen und die CHECK-Einschränkung anpassen:

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

Eine andere Möglichkeit wäre ein Stapel von Assoziationstabellen mit einfachen Skalarwerten in den Spalten. Dies kann jedoch umständlich sein, wenn Sie sechs dieser Spalten haben. Sie könnten auch Erwins Version der Funktion verwenden, wenn Sie sich Sorgen um NULL-Werte in den "Sets" machen müssen:

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;