2

私は数日間いじり続けてきたトリッキーな問題を抱えており、最適な解決策を見つけることができません。

これらは私のテーブルです:

  • サイト
  • site_node
  • ページ

サイトノードテーブルには、階層を表すノードのリストが含まれています(ネストされたセットを使用)。各ノードには、1つ以上の関連ページが必要です。各サイトには、1つの関連するエラーページと1つの見つからないページが必要です。

したがって、ページはノードに属しているか、エラーまたは見つからないページとしてサイトに属している必要があります。私が現在試している解決策は次のとおりです。

  1. ページテーブルのparentTypeフィールドとparentIdフィールド。タイプは「node」、「site_error」、「site_notFound」のいずれかで、idはサイトまたはノードID(タイプに関連する方)になります。
  2. nullになる可能性のあるページテーブルのnodeIdフィールド、次にサイトテーブルのerrorPageIdフィールドとnotFoundPageIdフィールド。

オプション#1は、各ページが1つだけの他のエンティティに属することを保証しますが、parentIdフィールドは複数の場所を指すことができるため、関係を実際に適用することはできません。

オプション#2の方がクリーンですが、基本的には、サイトが2つのエラーに「属している」と言っており、ページが見つかりません。これはおそらく悪い習慣です。

何か考えや提案はありますか?
ありがとう、
ジャック

4

5 に答える 5

3

エラーまたは見つからないページのダミーサイトノードを作成します。最初のオプションに従って、それらを特定のタイプのノードとしてマークできます。これにより、汎用ハンドラーメカニズムの作成が容易になります。また、結合が簡単になり、データベースクエリのパフォーマンスが向上します。さらに、データベーススキーマを変更せずに、より多くの種類の「特別な」ページ(おそらくログイン画面)を追加したり、これを構成可能にしたりすることができます。

于 2009-02-11T17:02:56.630 に答える
2

オプション #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_idsite_node_idparent_idparent_type

于 2009-02-11T17:27:46.880 に答える
0

オプション 2 はより理にかなっており、後でさらに複雑な問題が発生した場合に脳を救うことができます。サイトとエラー/notfound ページの 1 対 1 の関係は、外部キー制約に最適です。

于 2009-02-11T17:37:48.043 に答える
0

別のオプションは、次のように site_id と site_node_id の 2 つの列を持つことです。

create table pages
 ( page_id ... primary key
 , site_id references sites
 , site_node_id references site_nodes
 , ...
 , constraint site_or_node check (  site_id is null and site_node_id is not null
                                 or site_id is not null and site_node_id is null
                                 )
 );

参照整合性を使用して、すべてのページがサイトまたはノードの両方ではなくいずれかに属していることを確認できるようになりました。

于 2009-02-11T17:16:30.073 に答える
0

オプション 1 の修正。

ParentNodeID と ParentSiteID の 2 つの個別の列を含めます。場合に応じて、これら 2 つの列のいずれかを NULL のままにします。今でも、各外部キーに対して外部キー (参照) 制約を宣言できます。

SiteNotFound のケースがよくわかりません。この場合、両方の外部キーを NULL のままにできますか?

結合と検索がより簡単になります。また、1NF を遵守することになります。これは偶然ではありません。

オプション 1 では、異なるドメインから取得した値を 1 つのフィールドに結合します。これは不適切なフィールド設計であり、IIRC は 1NF に違反しています。

于 2009-02-11T18:22:06.547 に答える