5

それ自体に対して 1 対多の関係を持つことができるエンティティのテーブルをどのように構築しますか? 具体的には、動物の繁殖を追跡するアプリに取り組んでいます。各動物には ID があります。サイアー ID とデイム ID もあります。そのため、種牡馬または貴婦人からその子孫まで、1 対多にすることが可能です。私は次のような傾向があります:

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT 
DAME_ID INT

購入して繁殖用ストックに追加された動物については null 値を記録し、残りについては表に ID を記録します。

そう:

  1. この種の関係のモデリングについて説明している記事/Web ページを教えてもらえますか?
  2. ID は INT またはある種の文字列にする必要がありますか? INT の NULL は、動物がデータベースに親を持たないことを示しますが、特別なフラグ値を持つ文字列を使用して同じことを示すことができます。
  3. これは、2 つのテーブルを使用してモデル化するのが最適でしょうか? 動物用の 1 つのテーブルと、親族関係のみを示す別のテーブルを意味します。

    動物

    ID INT NOT NULL 主キー

    親族関係

    ID INT NOT NULL 主キー 外部キー

    SIRE_ID INT 主キー 外部キー

    DAME_ID INT 主キー 外部キー

上記についてお詫び申し上げます。私の SQL は錆びています。思っていることが少しでも伝われば幸いです。

4

9 に答える 9

6

さて、これは「通常の」1対多の関係であり、あなたが提案する方法はそれを解決するための古典的なものです.

2 つのテーブルが非正規化されていることに注意してください (superkey-is-not-well-should-be-subset-of-other-key-fsck-I-forgot 部分がどこにあるかを正確に指摘することはできませんが、かなり確信していますどこかにある); 直観的な理由は、最初のタプルが 2 番目のタプルに一致するのは多くても 2 番目のタプルに一致するためです。そのため、雄牛 ID と女性 ID が null の動物がたくさんいない限り、これは良い解決策ではありません (パフォーマンスが低下します -- 必要です)。結合 -- ストレージ要件は減りません)。

于 2008-10-01T22:04:42.937 に答える
4

1 つのテーブルだけを使用したレイアウトで問題ないと思います。SIRE_ID と DAME_ID を ID と同じデータ型に保持する必要があります。また、それらを FOREIGN KEY として宣言することもできます (外部キーが同じテーブルを指すようにすることが可能であり、外部キーは null にすることもできます)。

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT REFERENCES TABLENAME (ID)
DAME_ID INT REFERENCES TABLENAME (ID)

このレイアウトを使用すると、親動物を簡単に検索でき、特定の動物の子孫ツリーを構築することもできます (Oracle の場合は CONNECT BY があります)。

于 2008-10-01T22:11:03.170 に答える
3

数か月前に、MySQL Web サイトで同様の質問をしました。このタイプの関係について Peter Brawley から受け取った応答を参照することをお勧めします。http://forums.mysql.com/read.php?135,187196,187196#msg-187196

このトピックをさらに調査したい場合は、ウィキペディアのツリー階層を調べることをお勧めします。

別の提案されたアーキテクチャ (完全に正規化される) は、次のようになります。

表:動物

ID | 名前 | 繁殖

表:血統

animal_id | 親 ID | parentType (種牡馬または貴婦人)

于 2008-10-01T22:06:00.157 に答える
1

動物の繁殖についてはわかりませんが、あなたのSire_IDが父親で、Dame_IDが母親のようですね。問題ない。動物ごとに1行、購入した動物のnull sire_およびdame_IDは、問題はないと予測しています。

[ID],[Sire_ID],[Dame_ID];
0,null,null  (male)
1,null,null  (female)
2,null,null  (female)
3,0,1 (male)
4,0,2 (male)
5,null,null  (female)
6,3,5
7,4,5

などなど。おそらく、whileループでTreeViewまたはXmlNodeListにデータを入力します...

While (myAnimal.HasChildren) {
 Animal[] children = GetChildren(Animal.ID)
 for (int x=0; x<children.length; x++) 
  myAnimal.Children.Add(children[x]);
}

この場合、Animal.Childrenは動物のコレクションです。したがって、myAnimal.Children[0].FatherはmyAnimalを返します。.Parent []は、その2つの親のコレクションである可能性があります。これは、[0]が常に一方の親(父)であり、[1]が常にもう一方(母)である限り機能します。

IDを自動番号PKにし、親のIDを返すことにより、プログラムでSire_IDとDame_IDを割り当てます。本当に必要な場合は、両方の親IDがIDを参照し直すことができますが、外部キーの関係は必要ありません。

于 2008-10-01T22:14:27.813 に答える
1

INT は ID 列に適した選択肢であり、シーケンスを使用して一意の ID を生成する必要がある場合に適しています。

設計を 2 つのテーブルに分割するメリットはありません。

于 2008-10-01T22:05:43.747 に答える
0

木のようなものを作りたいようです。

のようなものはどうですか?:

 ID          Primary Key,
 Parent_ID   Foreing_Key
 ( data )

自分自身との関係を持つテーブルでクエリを実行するためのいくつかの機能があります。Connect Byの構文を参照してください:http ://www.adp-gmbh.ch/ora/sql/connect_by.html

于 2008-10-01T22:13:22.510 に答える
0

SQL で "connect by" 句を使用して、どの階層に従うかを指示します。

于 2008-10-01T22:06:46.537 に答える
0

動物が多くの親を持つことができない限り、それは実際には一対多の関係ではありません。

動物の一意のキー ID、親ごとに 1 つの int フィールド、および動物に関する一般的なメモ (その場合はどこで購入したかなど) に使用するテキスト フィールドを含む単一のテーブルとして残します。

于 2008-10-01T22:07:22.057 に答える
0

動物には 1 頭の父と 1 頭の母親しかいないことは明らかなので、1 つのテーブルを使用するのが最も理にかなっていると思います。私の好みは、行識別子として int または bigint を使用し、関係がないことを示す null 値を使用することです。おそらく、他の方法を使用して動物を一意に識別し、動物がテーブルに 2 回表示されないようにし、その列にも一意のインデックスを作成することをお勧めします。

于 2008-10-01T22:10:51.143 に答える