基本設計、初回データベース設計に関するアドバイス


8

私はJava開発者になるためのコースを取っています。

コースにはデータベースの使用が含まれますが、残念ながら実際に設計することはありません。

ほとんどの場合、事前に作成されたデータベースを取得し、データを挿入、更新、読み取り、または削除するためのコードを実装する必要があります。

しかし、私の最終テストが来るとき、私はデータベースを含む何かを作ることになる可能性が高いので、良いデータベース設計は多くの違いを生むことに気付いたので、設計のこつを得るためにいくつかの小さいものを設計してみたいと思います使用するコードを記述します。

これらの種類の質問がここで許可されていて、広すぎないことを願っています。


これは私が何かのように簡単なために作られた小さなデザインであるclubsmembersしてaddressesphonenumbers

  • 複数のクラブがあります。
  • 各クラブには複数のメンバーがいます(自明)
  • 会員は複数のクラブに所属することはできません
  • メンバーは複数の電話番号とメールアドレスを持つことができます
  • メンバーは1つのアドレスしか持てません
  • アドレスは異なるメンバー(カップルまたは兄弟)に属することができます

私の最大の混乱:

  • Club所有者を説明する列を追加したい場合、誰がメンバーにもなりますが、同じメンバーを2回リストしない場合の最善の方法は何ですか?

  • すべてのテーブルをIDの自動インクリメントに配置する必要がありますか、それとも悪い考えですか?(メリット/デメリット?)

  • [外部キー]タブで外部キーを追加すると、これらは自動的に正しいテーブルに対応しますか、それとも列に追加する必要がありますか?(写真2を参照)

  • そして、すべての私はおそらくnoobiest質問...ドゥ私はの外部キー置くphonenumberemailPERSON_IDにリンクし、それぞれのテーブル内のか、私は人のテーブルににphoneNumberやメール同上のを置く必要がありますか?

(写真の言語が英語ではないことをお詫びします。これがそれほど問題にならないことを願っています)

設計

外部キー

回答:


11

個々の質問への回答

Club所有者を説明する列を追加したい場合、誰がメンバーにもなりますが、同じメンバーを2回リストしない場合の最善の方法は何ですか?

仕様a Person can be a Member of only one Clubに記載されているように、このデータを単純にtrueまたはfalseとして保存したい場合、1つのオプションとして、テーブルにBIT(1)またはBOOLEANTINYINT)列を追加し、Personこの列を呼び出すことができますIsClubOwner。このようにして、決定した人物クラブ所有であるという事実を1回だけ登録できます。それとは別に、この方法は、同じクラブの出来事の所有者として数を保持する可能性も可能にします。図1に、このアプローチの論理レベルの描写を示します

しかし、あなたは最良のアプローチを探しており、私の経験によれば、そのようなアプローチははるかに拡張可能で用途の広い構造の開発を伴います。この点については、「残りの仕様のカバー」、「複数のクラブのメンバーとしての個人」、および「個別のエンティティタイプとしてのメンバーと所有者」というタイトルのセクションで、これらおよびその他のポイントのモデリング演習の進行に従ってください。

すべてのテーブルを自動的にインクリメントするid必要がありますか、それとも悪い考えですか?(メリット/デメリット?)

そのような特性の列を持つテーブルの定義を示す明示的な要件に直面し、その列がコンテキストに有効な意味を持っているか、幅広い自然PRIMARY KEY(PK)の代理のような特定の目的を果たしている場合、はい、その方法で進めるべきです。

そうでなければ、上記の要件がない場合は、無意味な追加の列と(おそらく?)データベースに追加のINDEXも格納および管理する必要があるため、不要だと思います。

いつものように、続行する方法を決定するために、各ケースとその全体的な影響を分析する必要があります。

[外部キー]タブで外部キーを追加すると、これらは自動的に正しいテーブルに対応しますか、それとも列に追加する必要がありますか?

この点について、私のアドバイスは、データベース構造を手動で作成しDDL、主題をしっかりと理解するまで独自のステートメントをコーディングすることです。そうすれば、グラフィカルツールが「内部」で実行しているプロセスを理解しやすくなります。

たとえば、次のようなステートメントを作成します。

CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)

GUIツールを使用してこの種のタスクを実行するよりもはるかに有益です。特に、最初のデザインを構築しているためです。

そして、私のすべてのおそらく最もnoobiest質問...ドゥ私はの外部キー置くphone_numberemailにリンクして、それぞれのテーブル内のperson_idか、私が入れなければならないphone_numberemail ids人テーブルで?

個人的には、これと他のすべての質問は完全に有効あり、文脈化されていると思います。

私たちに関係する技術的側面に戻ると、この正確な調査は、次の2つの主張を検討する良い機会を提供します。

  • A Person can be reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber can be used to reach one-to-many People

だから、1は間の多対多の関係があることを結論付けることができますPersonし、PhoneNumberそれゆえ、私はの創設を提案、連想テーブルという名前のPersonPhoneNumberデータベースに言っ関係を表現するために。このテーブルのPKは、(をPersonId指すFOREIGN KEY [FK] Person.PersonId)とPhoneNumber(を参照するFK )の2つの異なる列で構成される必要がありますPhoneNumber.Number。上記のすべての論理レベルの説明については、図1を参照してください。

一方、次の2つの命題を調べてみましょう。

  • A Person can be contacted via zero-one-or-many EmailAddresses
  • An EmailAddress can be used to contact exactly one Person

次に、はい、テーブルPersonから参照するFKを設定するEmailAddress必要があります。このテーブルにも、列PersonIdとで構成される複合PKが必要Addressです。このように、あなたは、同じ組み合わせのことを確実にすることができるEmailAddress.PersonIdとはEmailAddress.Address一度だけ挿入することができます。

特定EmailAddres.Addressの行を1つの行に格納できるようにしたい場合は、この列にUNIQUE CONSTRAINTを設定するだけです。

提案された論理データモデル

私の提案をより明確に示すために、図1図2図3、および図4に示す4つの異なるIDEF1X [1]論理モデルを含めました。それぞれに表示される最も関連性の高い機能について、対応するセクションで説明します。議論中の要素の大部分を単一のモデルに統合するPDFをDropboxからダウンロードすることもできます

残りの仕様をカバー

人と住所の関連付け

住所に関連する次の2つの(少し言い換えた)アサーションを調べてみましょう。

  • A Person can only have one Address
  • An Address can belong to different People (couples or siblings)

したがって、これらの制限に対処するために、図1示すようなデータモデルを実装することを選択できます。

図1.クラブとメンバーのデータモデル-最初の仕様

参照モデルを考慮に入れて、次の手順に従う必要があります。

  1. 呼ばれるテーブル作成PersonAddressの間の関係の固定PersonとをAddress。列PersonIdAddressId、この表の複合PKとして設定します。

  2. PersonAddress.PersonId列のUNIQUE CONSTRAINTを構成して、特定の値を上記のテーブルの多くても1行に挿入できるようにします。論理レベルでは、この状況PersonAddress.PersonIdは、が代替キー[2]になったことを意味します。

  3. AddressId決定されたPersonAddress挿入試行の値がまだ保存されていない場合は、挿入を続行します。そうでない場合は、そのような値がすでに行に存在する場合は、(a)PersonId登録者が登録済みであることを確認する必要AddressIdがあります。が男性のMarriage.WifeId場合PersonId(を介して派生したデータムPerson.GenreCodeまたは(b)PersonIdMarriage.HusbandId場合PersonIdは、女性の場合(Person.GenreCode同様にによって派生)です。適切な状況でこれらの条件のいずれかが満たされた場合は、INSERTを続行する必要があります。

  4. 上記の条件が満たされていない場合でも、PersonAddress挿入が成功する可能性があります。PersonId上記の挿入に含まれる値が、すでにを登録しているProgeny.ParentIdと少なくとも1つ共有していることを確認する必要があります。この条件が満たされている場合、データベースと同じように格納されているため、このINSERTは成功する必要があります。PersonIdPersonAddress.AddressIdSiblings

リレーショナルデータベースの実装と同様に、DML操作しているデータの整合性一貫を保護できるように、ACIDトランザクション内で操作を実行することを真剣に検討する必要があります。

コメントに追加した要件に参加する:クラブと人々に等しく役立つ住所と電話番号

住所電話番号人々クラブの両方に役立つ機会を与えたいという条件で、スーパータイプとサブタイプの関係を利用できます。ここに答えている私は、あなたが興味を持っている場合、構造体のこの種のより詳細な治療を与えているが。

現在のシナリオでは、あなたが定義することができPerson、およびClub新しいエンティティのサブタイプが指定されたとしてParty、一般的に法曹界で使用される用語は、(a)は、人または(b)(で述べたように人のグループのために立っていない感覚。6)。この方法で、関係Addresses(またはPhoneNumbers)とPeopleし、Clubsによって定義されるPartyスーパータイプ、。この提案の描写については、図2を参照してください。

図2.クラブとメンバーのデータモデル-2番目の仕様

パーティーと住所

したがって、この新しいモデルで次のことを読み取ることができます。

  • A Party keeps zero-one-or-many Addresses
  • An Address is kept by one-to-many Parties

したがって、多対多の関係がPartyあり、AddressそれはPartyAddressエンティティーによって表現されます。

パーティーと電話番号

さらに、次のように解釈できます。

  • A Party is reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber is used by one-to-many Parties

そのためPartyPhoneNumberPartyPhoneNumberエンティティタイプの間で有効になる多対多の関連付けを記述するエンティティを追加しました。

パーティーとクラブまたは人

次に、それを読むこともできます:

  • A Party is either a Club or a Person

したがって、Party供給接続いずれか Clubs 、または PeopleへのAddresses(又はPhoneNumbers)。

複数のクラブの会員としての人物

以下のよう@aldwinaldwinあなたがのための機能を提供したい場合は彼の答えでmentiones、人をするメンバーの複数のクラブ、あなたはテーブルと呼ばれる含むことができ、ClubMember当然、それは、他の多対多のrelaltionshipとして、この時間を働くことになります、相互接続PersonおよびClub

上記に加えて、この表は、すでに説明したブール列を含めることにより、複数のクラブの所有として具体的な人物を保存する場合にも役立ちます。実際、この新しいテーブルは、それ自体が一体型エンティティタイプの表現であると言えます。IsClubOwner

示されているように、図3は、このようなテーブルは、複合PKは列で構成必要ClubIdMemberIdロール名[3]に与えられるPersonIdと、対応して)、及びこれらの列は、ポインティングFKSとしても定義されなければならないClubPerson

図3.クラブとメンバーのデータモデル-複数のクラブのメンバーとしての人物

より適応性の高い構造

この設定を採用すると、最初のルールに準拠することもできますがa Person can be a member of only one ClubMemberId列にUNIQUE CONSTRAINTを追加するだけで、特定の値を1回だけ入力できます。したがって、お気づきのように、この構造は図1に示したものよりもはるかに適応性があります。一意の制約(またはINDEX)を削除すると、前述の機能を開き、個人が別のクラブのメンバーになることを許可します。同時。

別個のエンティティタイプとしてのメンバーと所有者

ご存じのように、クラブの所有としてのが果たす役割についてのいくつかの事実を保存することは、真または偽の属性の単なる存在に加えて、非常に有利です。たとえば、あなたが残しておきたいことがあり効果的な日付明確する人がなった 所有者クラブ、それゆえあなたはと呼ばれる別のエンティティタイプを導入することで、この状況を管理することができますに提示して、図4にClubOwner

図4.クラブとメンバーのデータモデル-別個のエンティティタイプとしてのメンバーと所有者

あなたは、この新しいエンティティタイプに基づいてテーブルを作成したら、専用の際に遊びに来るの特性を表すフィッティング列を追加することができPersonているOwnerのをClub。図示のように、このテーブルは参照FKの列で構成されるPKを開催するPerson.PersonIdClub.ClubId、このように任意の組み合わせをClubOwner.OwnerId(またはClubOwner.PersonId、あなたが好む場合)、ClubOwner.ClubId一つだけの機会に挿入することができます。

もちろん、この構成でも、aが特定PersonのものOwnerである場合、trueまたはfalseにClub評価できるスカラー値を返すクエリを使用して、ブール形式で派生できます


ノート

1.情報モデリングの統合定義(IDEF1X)は、1993年12月に米国国立標準技術研究所(NIST)によって標準として定義された、非常に推奨されるデータモデリング手法です。それはしっかりと()に基づいた理論的な論文の一部はによって作成された発信元リレーショナル・モデル、すなわち、博士はEFコッド。(b)PP Chen博士によって開発された実体関係理論。また、(c)Robert G. Brownによって作成された論理データベース設計手法についても説明します。IDEF1Xが一次論理によって形式化されます。

2. ALTERNATE KEYは、エンティティの出現を一意に識別する値を保持する属性(または属性の組み合わせ)ですが、関連するエンティティタイプのPKとして選択されていません。各エンティティタイプは、ゼロ、1つ以上の代替キーを持つことができます。IDEF1Xモデルでは、これらは「AK」とそのそれぞれの番号(AK1、AK2など)として示されます。通常、SQLのDDL構造にUNIQUE CONSTRAINT(またはUNIQUE INDEX)を介して実装されます

3. ロール名は、FK属性に割り当てられた表記(またはエイリアス)であり、それぞれのエンティティのスコープ内でそれらが保持する意味を表します。1970年以来、コッド博士「大規模な共有データバンクのデータのリレーショナルモデル」と題した独創的な論文で推奨されています。一方、IDEF1X(忠実に保つことはリレーショナルプラクティスを尊重する)も役割の命名を提唱しています。


2
  1. 所有者が常に彼のクラブのメンバーである場合。ownerIdをClubテーブルに追加し、所有者であるメンバーのpersonIdをそこに入れます。
  2. IDの自動インクリメントは適切です。あなたは別のフィールド「コード」を追加することができます、そこであなたはそこにクラブカードに会員コードを置きます。
  3. 自動的に問題ないはずです(私は思う)
  4. personIdを電話番号と電子メールテーブルに入れます。

...複数のクラブの会員になることはできませんか?可能であれば、clubIdとpersonIdを使用してClubMemberテーブルを作成します。このようにして、人を複数のクラブに接続できます。


1
私のクラブに電話番号を添えたい場合はどうすればよいですか?私は置けばいいのclubIdaswell PHONENUMBERにし、nullにいずれかのクラブや人物セットを残しますか?
Vahx

私はすべてのオブジェクトを「過剰」に分離しません(データの正規化)。クラブテーブルに電話番号を1つ入れるだけです。正規化は適切ですが、正規化が多すぎると問題が発生する可能性があります。
aldwinaldwin

1
しかし、私がこれをしたいと思いますか?例として住所を取り上げますが、メンバーには住所がありますが、クラブにも住所が必要です
Vahx

1
住所レコードを作成し、addressIdをclubに入れます。クラブには1つの住所があるため、メンバーには1つの住所があります。電話番号の場合、personIdをphonenumber-recordに追加して1対多にする必要があります。.....テーブルpersonPhoneNumber(personId、phonenumberId)+テーブルclubPhoneNumber(clubId、phonenumberId)を作成すると、多対多の関係になります。
aldwinaldwin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.