web-dev-qa-db-ja.com

重複データを参照テーブルに移動することが有益なのはいつですか?

ある有限集合Sの値を持つ列がある場合、たとえばpersonsテーブルのS = { alive, dead, unknown }列のlife_stateの場合、参照テーブルを追加するのはいつ有益ですか?

オプション

  • 重複した静的データをlife_state列に保存する

    • 単純な文字列SELECT DISTINCTに一部の値がない可能性があるため、可能なデータ値を取得するには、アプリケーション層レベルのコードが存在する必要があります。

    • ENUMlife_stateのすべての可能なデータ値を取得する場合は、SHOW COLUMN..からINFORMATION_SCHEMAを実行してすべての可能なデータを取得する必要があります値を設定し、そのデータをアプリケーション層レベルで解析するか、アプリケーション層レベルでコードが重複しています。新しいlife_state値を追加する必要がある場合は、テーブルをALTERし、変更中のプロセスでテーブル全体をロックする必要があります。必要に応じて、life_state値ごとに追加のデータを保存することはできません。

  • Normalized参照テーブルlife_statesと、personsテーブルに戻るリンクテーブルを作成します。可能な値は、3行を返すSELECT name from life_states;から導出できます。 personsインスタンスのlife_stateを取得するには、追加の結合が必要になりました。これは遅いだけでなく、アプリケーション層レベルでより長いクエリ/より多くのコードを必要とします。予期されていませんが、必要に応じて追加の値を簡単に追加できます。さらに、life_stateタイプに他のデータを追加する必要がある場合は、簡単に追加できます。

その他の考慮事項

  • INT/ENUMインデックス作成は、より高速で、占有するスペース文字列が少なくなる可能性があります。

関連する議論

1
Adam Thompson

この回答は、MySQLに適用されるENUM型の使用に主に焦点を当てています。これは、MySQLが使用されているように見えるためです。

あなたはあなた自身の投稿の下部で強調したスレッドを介してあなた自身の質問に答えました-それはすべて説明されています ここ すなわちENUMsは:-)!

データベース内のデータはテーブルに保存する必要があります-データベースの管理に関するデータはシステムテーブル(データディクショナリ)に保存する必要があります。 ENUMの内容を知りたい場合は、システムテーブルをクエリする必要があります。

私のアドバイスは、2つ以上の値を持つすべてのものにテーブルを使用することです。それでも、この問題を取り巻く性別についての議論を見てください。

あなたが指摘したスレッドで示されているように、VIEWsを使用して頻繁に使用する参照テーブルのいくつかを事前に結合することにより、結合から手間のかかる作業の一部を取り除くことができます。さらに、参照テーブルには詳細な説明を含めることができます。これらの契約プログラマーは、あいまいなコードの意味について何も覚えておく必要はありません。

基本的に、データベースでENUMを使用する理由がわかりません。プログラミングしてからしばらく経ちましたので、言語で使用することの長所と短所についてはあまり詳しくありません。 !!

2
Vérace

重複データを参照テーブルに移動することが有益なのはいつですか?

  1. 参照データが参照データとは独立して存在する場合。この例では、問題のドメインで、personsに行がない場合でも可能なライフ状態が何であるかを知ることが役立ちます。

  2. 値が既知の有限集合からのみ描画できる場合。これはしばしば「参照データ」と呼ばれます。外部キー制約はこれを強制できます。

  3. 2つ(またはそれ以上)の正規化されたエンティティ間で参照整合性を維持する必要がある場合。これは、値が事前にわからないトランザクションデータ用です。たとえば、アプリケーションが実行時に新しいユーザーの追加を許可し、各テーブルにlast_updated_useridがある場合です。この場合も、外部キーがこれを強制します。

  4. Life_stateのみに依存する追加のドメイン値が検出された場合。これは通常のキー依存関係の正規化です。

  5. メタデータが必要な場合(例:システムから値を完全に削除するのではなく、「ソフト削除」の場合はis_active

参照テーブルの代理キーを作成するのが通例ですが、必須ではありません。与えられた例では、参照テーブルは3行の単一の7文字の列を持つことができます。人間が読める値は、参照テーブルに表示されます。これにより、参照されるテーブルに結合する必要がなくなります。

2
Michael Green

なぜあなたは穴にいるのか(例固有)

ここでの問題は、主に「不明」と「不明であることがわかっている」をどのように区別するかです。誰かがdeath_dateを持っていた場合、

  • IS NOT NULL確実に彼らが死んでいることを知ることができたとき、あなたは実際にwhen彼らが死んだことを知るでしょう。 (これまでの死は日付に起因する可能性があると仮定して)

  • ただし、IS NULLの場合、データは2つの方法のいずれかで解釈できます。

    • あなたはnotknow死ぬ人。
    • あなた知っている生きている人(つまり、not死んでいる)。

それらは意味的に非常に異なります。 これらの若者 死んでいることはわかりませんが、safe彼らが生きていることを伝えることもできません。特に、このデータを使用してリソースを割り当て、それらを見つける場合。

間違った施設

たとえば、ここには多くの虚偽表示があります

  • ENUMは標準機能ではなく、一般的な拡張機能です。 PostgreSQLでは、

    • ENUMは重複したデータです。」:実際にはそうではないか、そうであるべきではありません。 ENUMは、ユーザーテーブルへのリンクと同じ方法で、システムテーブル(カタログ)へのリンクを介して実装でき、ユーザーに対して完全に透過的にすることができます。たとえばPostgreSQLでは、ENUMは4バイト(intのサイズ)です。最良の場合のリンクのコストは別のバイトになるため、リンクすると3バイトしか節約できません。
    • SHOW COLUMNで潜在的な値を取得する」:これも常に必要なわけではありません。可能な enumSELECTの値を取得するのは非常に自然です。あいまいなSHOW構文は必要ありません。
    • ENUMを使用する複数のテーブルは、タイプとは関係ありません。タイプitselfALTER TYPE で変更できます。それは即座に値を追加し、それはタイプを使用するすべてのテーブルで有効になります。
1
Evan Carroll