Joshua Drake published his fascinating researches about pros and cons of using ENUMs, DOMAINs, FOREIGN KEY and CHECK constraints. Since I haven’t found a way to leave a comment I’m writing this post.
A DOMAIN for this problem suffers from the same problems as ENUM as it registers as a type. However a DOMAIN is more flexible as you can apply complex logic to the validation (just as you can with a CHECK). For example a DOMAIN could contain the regex to validate if a email address is correctly formed. I have used domains many times in the past to create complex validating types. They are useful.
In addition I could say that DOMAIN is more flexible because it can have several CHECK constraints. Hence, DOMAIN doesn’t suffer much from being a type. In case of ENUM we must drop the whole type to change its values, but with DOMAIN we may just drop needed CONSTRAINT(s) and(or) create new one.
Let’s imagine situation when we need to add or remove some values to pass validating:
--create domain CREATE DOMAIN my_domain AS text CONSTRAINT my_domain_check CHECK(VALUE IN ('foo1','foo2')); --add additional values ALTER DOMAIN my_domain ADD CONSTRAINT my_domain_check2 CHECK(VALUE IN ('foo3','foo4')); --remove some values ALTER DOMAIN my_domain DROP CONSTRAINT my_domain_check; --list available constraints information SELECT conname, pg_get_constraintdef(pg_constraint.oid) FROM pg_constraint, pg_type WHERE pg_constraint.contypid = pg_type.oid AND pg_type.oid = 'my_domain'::regtype; --P.S. Do not like JOINs ;)