制約を実装するには、次の 3 つの方法が考えられます。
真のカテゴリ変数を別のテーブルに格納し、参照されるたびにそのテーブルを指す外部キーを持つケースを作成できます。これにより、多くの場合、データベースをクリーンに保ち、保守を容易にすることができます。ユーザーの "State" 属性が、"MA"、"ma"、"Mass."、または "Massachusetts" などの文字列ではなく、1 から 50 までの数値変数であることを知っていれば、DBA (および開発者) は確実に維持されます。したがって、エンドユーザー) は幸せです。
ただし、変数が完全にカテゴリカルではなく、特定の基準がある場合は、 CHECK 制約を使用してそれらを課すことができます(MySQL の詳細はこちら)。これらを使用すると、可能な値をそれぞれ列挙することなく、有効な値の特定の範囲を定義できます。これは、外部キー ルックアップのペナルティを被ることなく、挿入時に有効性を確認したい場合に役立ちます。
最後に、ビジネス ロジックに制約を課す場所が確かに存在します。複雑な制約 (正規表現の一致など) は、SQL データベースではなく、アプリケーション コードで維持するのが最適であることがわかりました。
外部キーが必ずしもパフォーマンスに悪影響を与えるとは限らないことに注意してください。いくつかのテストを実行できますが、大きな (50 万行) テーブルを小さな (20 行) カテゴリ テーブルに結合しても、パフォーマンスに目立った影響がないことがわかりました。なので、気にしなくても大丈夫です。
ENUM にしたい数十の潜在的な値がある場合、常に必要というわけではありませんが、結合を行うときにのみパフォーマンスの低下が発生することに注意してください。多くの場合、データの取得では、実際の値ではなく ID を取得するだけで済みます。この場合、外部キーの存在は決して SELECT に影響を与えず、システムが外部キーが有効であることを確認する必要があるため、INSERT/UPDATE ごとにわずかなペナルティが発生するだけです。