2

私は、非常に類似した関係をモデル化するいくつかのテーブルがあった、より抽象的なスキーマの構築に取り組んできました。「本質」だけをモデル化したいのです。私が使用している環境 (Drupal 7) のため、問題の性質を変更することはできません。つまり、同じ必須タイプの関係が、1 つのロール内のオブジェクトの 2 つの異なるテーブルのいずれかを参照する可能性があるということです。明確にするためにいくつかの例を挙げてみましょう (これは私の実際の問題ドメインではなく、同様の問題です)。要件は次のとおりです。

最初に、Drupal に慣れていない場合は、要点を次に示します。ユーザーは 1 つのテーブルに、他のすべてのエンティティは 1 つの 2 番目のテーブルに含まれます (全体的な一般化ですが、十分です)。

「works for」関係をモデル化したいとしましょう。「会社」のタイプは「エンティティ」であり、「スーパーバイザー」のタイプは「ユーザー」です (「タイプ」とは、それがテーブルであることを意味します)。タプルが存在するデータベース内)。簡略化された要件は次のとおりです。

  1. ユーザーは会社で働くことができます
  2. 会社は会社のために働くことができる
  3. これらの「有効な」関係は、同じテーブルにある必要があります。

私には 2 つのアイデアがありますが、どちらもスキーマの品質に対する私の現在の傾向とは完全に一致していません。

  1. 「タイプ」列と対になった 1 つの外部キー列
  2. 2 つの外部キー列、常に多くても 1 つしか使用されません (いや!)

あなたが視覚的に考える人のために、ユーザー 123 と 632、およびエンティティ 123 がすべてエンティティ 435 で機能するという事実を表す 2 つのオプションを次に示します。

  Option 1
+---------------+-------------+---------------+-------------+
| employment_id | employee_id | employee_type | employer_id |
+---------------+-------------+---------------+-------------+
|             1 |         123 |          user |         435 |
+---------------+-------------+---------------+-------------+
|             2 |         123 |        entity |         435 |
+---------------+-------------+---------------+-------------+
|             3 |         632 |          user |         435 |
+---------------+-------------+---------------+-------------+

  Option 2
+---------------+------------------+--------------------+-------------+
| employment_id | employee_user_id | employee_entity_id | employer_id |
+---------------+------------------+--------------------+-------------+
|             1 |              123 |             <NULL> |         435 |
+---------------+------------------+--------------------+-------------+
|             2 |           <NULL> |                123 |         435 |
+---------------+------------------+--------------------+-------------+
|             3 |              632 |             <NULL> |         435 |
+---------------+------------------+--------------------+-------------+

オプション 1 についての考え: employee_id 列に具体的な roleがあるのは好きですが、あいまいな targetがあるのは嫌いです。オプション 2 にはあいまいな役割 (どの列が従業員ですか? ) がありますが、特定の FK の具体的なターゲットがあるため、次のように考えることができます。

+-----------+-----------+----------+
|           |         ROLE         |
|           | ambiguous | concrete |
+-----------+-----------+----------+
| T         |           |          |
| A  ambig. |           |     1    |
| R         |           |          |
| G  -------+-----------+----------+
| E         |           |          |
| T  concr. |     2     |     ?    |
|           |           |          |
+-----------+-----------+----------+

オプション 2 には、私のプロジェクトにとって非常に実用的なメリットがありますが、あまりにも多くの null を使用するのは好ましくありません (1NF とは呼ばないかもしれません!)。

SO に対する私の質問の要点は次のとおりです。オプション 1 を改善するにはどうすればよいでしょうか。違反している特定のルールを思い出すことはできませんが、設計が正規化の意図に沿っていないことは明らかです (関係を一意に識別するために 2 つの列を必要とすることは、異常に対する保護に何の恩恵も与えません)。

理想的な解決策は、ここで「エンティティ」と呼んでいるものと同じになるようにユーザーエンティティを再設計することであることは理解していますが、ポイント/状況に加えてそれを考慮してください (または、少なくとも実用的な線をそこに正確に引きましょう)この質問のために)。

繰り返しますが、重要な質問です。正規化に関して、スキーマ オプション 1 のどこが間違っているのでしょうか。また、「ユーザー」を「エンティティ」にリファクタリングしないという制約がある場合、この関係をどのようにモデル化できますか?

注: このため、実用的な解決策よりも理論的な純粋さに関心があります。

4

2 に答える 2

1

あなたが提示する解決策は、@podiluskaが言うように第4正規形に違反します。これを以下の形式に再キャストすると、ソリューションはこれを取り除き、5NF(さらには6NF?)になります。

サブ/スーパータイプのパターンの1つを採用します。これは、以下に示す関係定義に加えて、スーパー/サブタイプ制約を使用します。この制約は、スーパータイプリレーションの各タプルが1つのサブタイプタプルに正確に対応している必要があるということです。言い換えると、サブタイプは、スーパータイプをカバーする互いに素なセットを形成する必要があります。

実際の状況でこれを実行するには、かなりの調整が必要になると思います。

    Table: Employment
    +---------------+-------------+
    | employee_id   | employer_id |
    +---------------+-------------+
    |             1 |         435 |
    +---------------+-------------+
    |             2 |         435 |
    +---------------+-------------+
    |             3 |         435 |
    +---------------+-------------+
    Table: Employee (SuperType)
    +---------------+
    | employee_id   |
    +---------------+
    |             1 |
    +---------------+
    |             2 |
    +---------------+
    |             3 |
    +---------------+
    Table: User employee (SubType)
    +---------------+-------------+
    | employee_id   | user_id     |
    +---------------+-------------+
    |             1 |         123 |
    +---------------+-------------+
    |             3 |         632 |
    +---------------+-------------+
    Table: Entity employee (SubType)
    +---------------+-------------+
    | employee_id   |   entity_id |
    +---------------+-------------+
    |             2 |         123 |
    +---------------+-------------+
于 2012-08-31T09:01:48.487 に答える
0

オプション 1 (およびオプション 2) の問題点は、それが多値の依存関係であり、第 4 正規形に違反していることです。ただし、与えられた制約内では、それについてできることはあまりありません。

テーブルをビューに置き換えることができればworksfor、ユーザーと会社の関係と会社と会社の関係を分けることができます。

2 つの選択肢のうち、オプション 2 には、プラットフォームによっては参照整合性をより簡単に適用できるという利点があります。

現在の制約内で厄介な場合の実用的な解決策の1つは、企業に正のIDを与え、ユーザーに負のIDを与えることです。 .

同様に、結合によって判別できる限り、エンティティの型を知る必要がない場合は、Guid を ID として使用すると、type列の必要がなくなります。

于 2012-08-31T06:09:23.133 に答える