I am trying to convert a MySQL database to Postgres. It is frustrating, but proceeding along steadily. One issue that has me stumped is to convert the MySQL SET data type to Postgres. A SET data type in MySQL is not the same as the plain ENUM type, and can’t be emulated with a CHECK constraint.
As far as I understand, a SET type allows storing zero or more values from the set in the column. So, something like the following in MySQL
CREATE TABLE foo (color SET('red','green','blue'));
will allow any of the following as valid values
''
'red'
'red,blue'
'green,red'
and so on. A close approximation in Postgres is
CREATE TABLE foo (
color VARCHAR(10) NOT NULL,
CHECK (color IN ('red','green','blue'))
);
but the above doesn’t allow ‘red,blue’ or ‘green,red’ and so on.
Of course, the above is just a simplification. The actual database is fairly more complicated with about half a dozen columns defined as SET.
Suggestions?
You could use an array for the column and an “is contained by” operator for the CHECK constraint:
And then things like this happen:
This will allow
{red,red}in the column though; if disallowing{red,red}is important, then you could add a function to check for unique color values in the array and adjust the CHECK constraint:Another option would be a pile of association tables with simple scalar values in the columns. However, this might be cumbersome if you have six of these columns. You could also use Erwin’s version of the function if you needed to worry about NULLs in the “sets”: