一般に、結合コストがあっても、正規化は通常有益であることを理解しています。しかし、最近、興味深いジレンマを思いつきました。
データが重複していても、変更される可能性が低いとしたらどうでしょう。それは可能ですが、私はそれを予期していません。
nutrients
列とunit
テーブルがあり、単位はg
、kg
、ug
などになります。
私はこれらの値が変わるたびに見ることはできません。
正規化してunits
テーブルを作成し、外部キーを使用してnutrients
テーブルから行をフェッチするたびに結合する必要があるのではなく、テーブル内の列としてそれらを単に配置したくなります。同時に、一般的には、結合コインを使用しても、正規化する必要があることを知っています。
私は何をすべきですか(そしてその理由)?
冗長データ(不良)と偶発的に繰り返されるデータ(不良ではない)には違いがあります。正規化は、挿入、更新、削除の異常を回避するために使用される手法です。データの繰り返しをすべて排除することを意図したものではありません。静的なデータは正規化の恩恵を受けません。
標準化された略語として示されている測定単位は、正規化する必要のある種類のデータではありません。
このように考えてください。測定単位を別のテーブルに正規化する場合、nutrients
テーブルからunits
テーブルへの外部キーが必要になります。測定単位コードは一意になるでしょうか(おそらく、はい)。したがって、これはunits
テーブルの候補キーです。 units
の候補キーである場合は、nutrients
の外部キーとして使用できます。
最終的には、ユニットを正規化していても、nutrients
テーブルに測定単位コードが含まれることになります。
wouldがunits
テーブルを作成したい場合です。単位コードに依存するが栄養素には依存しない他の述語(列)がある場合。たとえば、unit_type
または同じタイプの基本単位への変換係数(重量のグラムなど)これは、nutrients
の推移的機能依存関係になりますテーブルとその理由でそこに属していません。
ジョエルの 優れた答え に追加するために、これが私の見解です。
現在のように、正規化する必要はありません。この場合、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
テーブルが必要になります。
一般に、正規化の方が優れています。ここにいくつかの長所があります