オプション #1 では、各ページが他の 1 つのエンティティのみに属していることを確認しますが、parentId フィールドが複数の場所を指す可能性があるため、関係を実際に適用することはできません。
右。リレーショナル理論の観点から言えば、問題は " " 列が第 3 正規形parentId
に違反していることです。これは、その意味が(非キー列)の値に基づいて行ごとに異なるためです。parentType
他のフラグに応じて、単一の列に誰かの電話番号または生年月日が行ごとに含まれる場合、適切に設計されたデータベースはありません。これらは、その人物に関する 2 つの異なる事実であり、それぞれ独自のコラムを書く価値があります。同様に、site_id または node_id の両方を 1 つの列に格納すると、同じ問題が発生します。
これが設計に問題があることを示すもう 1 つの手がかりは、参照される 2 つのテーブルのいずれかを指す外部キー制約を宣言できないことです。
オプション #2 の方がクリーンですが、基本的には、サイトが 2 つのエラー ページと見つからないページに「属している」ことを示しており、これはおそらく悪い習慣です。
Railsのようなフレームワークの規則に属しているため、あなたがそう言っている理由がわかりました。しかし、これらは慣例です。これらは、必ずしも外部キーがモデル化できる唯一の関係ではありません。has oneリレーションシップでは、1 つのエンティティが正確に 1 つの他のエンティティを参照するようにすることができます。この場合、外部キーは方向を逆にします。
エラー ページと Not Found ページがサイトに属していることは論理的に正しいと言えます。その逆ではありません。それらを必須にする方法は、別のエンティティにこれらのページを参照させ、NOT NULL
これらの参照に制約を適用することです。これはあなたが説明したものです。
CREATE TABLE site (
. . .
error_page_id INT NOT NULL,
notfound_page_id INT NOT NULL,
FOREIGN KEY (error_page_id) REFERENCES pages (page_id),
FOREIGN KEY (notfound_page_id) REFERENCES pages (page_id)
);
これは差し迫ったニーズを満たし、強制力があり、通常の形式です。
@NXCは、Error ページと Not Found ページのダミー ノードを作成することを提案しています。これにより、これらのノードをノード階層に格納できますが、サイトにこれらのページが必要であるという強制はできません。つまり、これらのノードへの参照なしでサイトを格納できます。
@Tony Andrewsは、各ページに 2 つの列と を格納し、CHECK 制約を追加して、これらのうちの 1 つだけが非 NULL であることを確認することを提案しています。これは/オプションよりも優れているように見えますが、それでも、すべてのサイトにエラー ページと Not Found ページが必要であるという強制はありません。site_id
site_node_id
parent_id
parent_type