web-dev-qa-db-ja.com

データベースの正規化:特性の説明-テーブルへの外部キー、または値を持つvarcharフィールド?

私の同僚と私は、「ステータス」や「タイプ」など、データベースの記述的特性の正規化について話し合っています。ディスカッションの中央のテーブルを「順序」と呼びましょう。

通常の設計アプローチでは、注文のステータスを説明する別のテーブル「OrderStatus」を定義してから、「Order」テーブルに関係「OrderStatusID」などの外部キーを作成します。

これは私に参照整合性を与えるでしょう。いつでもステータスに参加でき、可能な値は常に「OrderStatus」テーブルに表示されます。

私の同僚はこの程度の正規化を好まないので、代わりに "Order"テーブルにvarcharフィールド "OrderStatus"を定義します。このフィールドには値が直接含まれます。

ステータスの可能な値は彼のアプリケーション、より具体的にはOrderStatusesのEnumで定義されているため、そのアプリケーションのソースコードにアクセスできない限り、私は使用できません。

私は、データベースのコンテキスト全体がリレーションシップとテーブルとしてデータベースに存在することに慣れており、 "WHERE OrderStatusID = 3"とは対照的に "WHERE OrderStatus = 'Sold'"と書かなければならないというバグがあります。

どう思う?私は両方のアプローチに対する賛成論と反対論を探していますが、主にパフォーマンスと可読性/保守性を懸念しています。

4
Sebastian

説明する設計の選択は、正規化とは直接関係ありません。

ルックアップテーブルがあるはずです。

OrderStatusIDの値はincreaseの冗長性になると思います。ステータス(テキスト)の値は、おそらく適切なキーの多くの品質を既に満たしていると考えられます。一意であり、安定していて、狭く、ユーザーにとって使い慣れています。もちろん、参照整合性はVARCHAR列に適用できます。キーを使用する各アプリケーションは、必要に応じてそれにenumを割り当てることができ、enum値をステータス(テキスト)値にマッピングする必要があります。これにより、ルックアップテーブルが単一列の「すべてのキー」テーブルになると考えられます(したがって、最高の正規形である6NFを満たします)。

[OrderStatusIDがOrderテーブルの属性である場合、6NFにはありませんが、私が言うように、正規化について実際に質問しているとは思わないでしょう。]

5
onedaywhen

ルックアップテーブルを使用する必要があります

  • すべてのクライアントがアプリケーションでENUMを使用するわけではありません
    ある時点で接続するレポートまたはMISまたはExcelアプリを取得します
  • それ以外の方法で「存在しない」を行うにはどうすればよいですか?
    あなたはこれを尋ねられます
  • あなたはクライアント列挙型の変更について知りません
  • 文字列はtinyintと比較して非効率的であり、特にWHERE句で文字列にインデックスを付ける必要がある場合は特にそうです。
  • データとデータベースはクライアントアプリケーションよりも長く存続します

また、これらを参照してください:

8
gbn