「すべてのデータベースがこれをサポートしているわけではない」と言うとき、それを置くより良い方法は次のとおりだと思います。
トリガー、関数、その他の高度な機能を幅広くサポートしているため、すべての主要なデータベースがこれをサポートしています。
これにより、これは高度なSQLの一部であり、ある時点で理にかなっているという結論に至ります。
Do people actually use domains in their database designs?
広範囲にわたるカバレッジが必要なため(オペレーター、インデックスなどを検討)
If so to what extent?
繰り返しになりますが、既存の型を少し追加の定義済みロジック(チェックなど)と組み合わせてトリックを実行できる場合は、可能な限り制限します。
How useful are they?
たくさんの。MySQLのようなあまり良くないDBMSを1秒間考えてみましょう。これは、1つの理由でこの例のために選びました。inet(IPアドレス)タイプの適切なサポートがありません。
範囲などすべてのIPデータに主に焦点を当てたアプリケーションを作成し、デフォルトのタイプとその制限された機能に縛られている場合、追加の関数と演算子(postgreSQLでネイティブにサポートされているような例)または必要なすべての機能に対してより複雑なクエリを記述します。
これは、独自の関数(PostgreSQLのinet >> inet:範囲演算子に含まれる範囲)の定義に費やす時間を簡単に正当化できる場合です。
その時点で、データ型のサポートを拡張することはすでに正当化されています。新しいデータ型を定義するための手順は他に1つしかありません。
PostgreSQLに戻りましょう。これは本当に素晴らしい型のサポートを持っていますが、必要なunsigned intはありません。ストレージ/パフォーマンス(...を知っている)を本当に心配しているので、演算子-もちろん、これは主に既存のint演算子に由来します。
What pitfalls have you encountered?
これまでは、これに必要な時間を必要とする正当な理由を持つプロジェクトを持っていなかったので、いじくり回していません。
私が目にする最大の問題は、車輪の再発明、「安全な」層(db)のバグの導入、不完全な型サポートです。これは、あなたがCONCAT(cast * AS varchar) cast(newtype as varchar)などを定義しませんでした。
「珍しい」などについて話している答えがあります。間違いなくこれらは珍しいことではないはずです(そうでなければdbmsには多くの重要なタイプが欠けていることを意味します)が、一方で、アプリケーションとは異なります)、一貫性に関連するものはすべてそこに保持される方がよいこと。
ビジネスロジックがソフトウェアレイヤーで処理され、SQLで実行でき、より安全な場合が多くあります。アプリ開発者は、アプリケーション層でより快適に感じる傾向があり、多くの場合、SQLで実装されたより良いソリューションを避けます。これは、良い習慣と見なされるべきではありません。
UDTは最適化のための良い解決策になる可能性があります。char(1)を使用したm / fタイプに関する別の回答で良い例を示します。UDTであった場合、代わりにブール値を使用できます(3番目と4番目のオプションを提供したい場合を除く)。もちろん、これは列のオーバーヘッドのために実際には最適化ではないことを知っていますが、可能性はあります。