web-dev-qa-db-ja.com

正規化するかしないか

一般に、結合コストがあっても、正規化は通常有益であることを理解しています。しかし、最近、興味深いジレンマを思いつきました。

データが重複していても、変更される可能性が低いとしたらどうでしょう。それは可能ですが、私はそれを予期していません。

nutrients列とunitテーブルがあり、単位はgkgugなどになります。

私はこれらの値が変わるたびに見ることはできません。

正規化してunitsテーブルを作成し、外部キーを使用してnutrientsテーブルから行をフェッチするたびに結合する必要があるのではなく、テーブル内の列としてそれらを単に配置したくなります。同時に、一般的には、結合コインを使用しても、正規化する必要があることを知っています。

私は何をすべきですか(そしてその理由)?

4
Adam Thompson

冗長データ(不良)と偶発的に繰り返されるデータ(不良ではない)には違いがあります。正規化は、挿入、更新、削除の異常を回避するために使用される手法です。データの繰り返しをすべて排除することを意図したものではありません。静的なデータは正規化の恩恵を受けません。

標準化された略語として示されている測定単位は、正規化する必要のある種類のデータではありません。

このように考えてください。測定単位を別のテーブルに正規化する場合、nutrientsテーブルからunitsテーブルへの外部キーが必要になります。測定単位コードは一意になるでしょうか(おそらく、はい)。したがって、これはunitsテーブルの候補キーです。 unitsの候補キーである場合は、nutrients外部キーとして使用できます。

最終的には、ユニットを正規化していても、nutrientsテーブルに測定単位コードが含まれることになります。

wouldunitsテーブルを作成したい場合です。単位コードに依存するが栄養素には依存しない他の述語(列)がある場合。たとえば、unit_typeまたは同じタイプの基本単位への変換係数(重量のグラムなど)これは、nutrients推移的機能依存関係になりますテーブルとその理由でそこに属していません。

12
Joel Brown

ジョエルの 優れた答え に追加するために、これが私の見解です。

現在のように、正規化する必要はありません。この場合、ENUMタイプを使用して、すべての可能なユニットを格納できます。これにより、ごみがユニットとして挿入されないようにします。

頻繁にポップアップする新しいユニットがある場合、これは少し面倒になる可能性があります。それ以外の場合は、新しい列挙値を追加することができます

ALTER TYPE units ADD VALUE 'kpc'; -- https://en.wikipedia.org/wiki/Parsec

以前のコメントの1つで提起された懸念に答えると、タイプによって可能な値を取得することもできます

SELECT unnest(enum_range(NULL::units));

正規化が本当に理にかなっている場合の1つは、単位も正規化する場合です。たとえば、1〜100グラムの範囲の同じ栄養素のアイテムが数千あり、総重量を計算する必要があるとします。要件に基づいて、「132456 g」または「132.456 kg」のような量を思い付くことができます。計算を行うには、異なる単位間の変換の記録を保持する必要があります。これには、別個のunitテーブルが必要になります。

3
dezso

一般に、正規化の方が優れています。ここにいくつかの長所があります

  1. インデックスが整数になるため、スペースがより有効に活用されます
  2. ユニットコードの変更はトランザクションテーブルに影響しません
  3. あなたは将来何が起こるのかわからないので。新しいユニットコードなどを処理するためのコードの変更がはるかに少なくなります
  4. インターフェイスでユニットのルックアップを表示している場合は、コードの個別の選択を使用する必要があります。これは高価であり、表のボリュームに基づいて時間とともに劣化します
1
srp