私は、非常に類似した関係をモデル化するいくつかのテーブルがあった、より抽象的なスキーマの構築に取り組んできました。「本質」だけをモデル化したいのです。私が使用している環境 (Drupal 7) のため、問題の性質を変更することはできません。つまり、同じ必須タイプの関係が、1 つのロール内のオブジェクトの 2 つの異なるテーブルのいずれかを参照する可能性があるということです。明確にするためにいくつかの例を挙げてみましょう (これは私の実際の問題ドメインではなく、同様の問題です)。要件は次のとおりです。
最初に、Drupal に慣れていない場合は、要点を次に示します。ユーザーは 1 つのテーブルに、他のすべてのエンティティは 1 つの 2 番目のテーブルに含まれます (全体的な一般化ですが、十分です)。
「works for」関係をモデル化したいとしましょう。「会社」のタイプは「エンティティ」であり、「スーパーバイザー」のタイプは「ユーザー」です (「タイプ」とは、それがテーブルであることを意味します)。タプルが存在するデータベース内)。簡略化された要件は次のとおりです。
- ユーザーは会社で働くことができます
- 会社は会社のために働くことができる
- これらの「有効な」関係は、同じテーブルにある必要があります。
私には 2 つのアイデアがありますが、どちらもスキーマの品質に対する私の現在の傾向とは完全に一致していません。
- 「タイプ」列と対になった 1 つの外部キー列
- 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 のどこが間違っているのでしょうか。また、「ユーザー」を「エンティティ」にリファクタリングしないという制約がある場合、この関係をどのようにモデル化できますか?
注: このため、実用的な解決策よりも理論的な純粋さに関心があります。