2009-03-11 10 views
4

は以下をモデル化するための最良の方法は何ですか...は「1対多」のモデリング質問

は、私は2つのオブジェクトがあるとします。AgencyPublisherを、両方ともEmployeeから1対nの関係を持っています。これは真の1対nの関係です。それぞれEmployeeAgencyまたはPublisherの1つのみで動作します。さらに、1対nの関係を保持する スーパータイプ(たとえばEmployer)を導入できないとします。

AgencyまたはPublisherのプライマリキー(すべてのプライマリキーがデータベース全体で一意の64ビットID)にリンクできる外部キーをEmployeeに配置することをお勧めします。しかし、今度は、Employeeに、AgencyPublisherの関係であるかどうかを示すことなく、双方向の関連付けをマップすることはできません。

私の他の選択肢は、2つのテーブルAgencyEmployeePublisherEmployeeを使用して、従来の1対nの双方向アソシエーションとしてリンクすることができます。

この状況では、どのようなベストプラクティスを検討しますか?

更新:このような短い時間で大きな反応をありがとう!以下の解決策はどう思いますか?EmployeeAgencyPublisherの両方の外部キー(agency_idpublisher_idなど)?

答えて

1

ベストプラクティスはおそらくEmployerクラスを導入することでしょう。

従業員をAgencyEmployeeとPublisherEmployeeに分割すると、Bad Thing™が実行されます。

雇用者を紹介していない場合は、雇用者タイプ(代理店または出版社)を従業員に指定します。

更新の質問に対応:オプションですが、より良いのでemployer_typeある

:あなたはあるでしょう将来

  • に他の雇用者のタイプを追加したい場合があります

    1. Employeesテーブルの各行に空のフィールド。

      シンプルな代替は、単に外部キー制約を強制しないことだろう。

  • +0

    私はベストプラクティスとバッドシングの呼び出しに同意しますが、私は正規化の観点から、PK、EmployerID、EmployerTypeというEmployeeIDを持つ3番目のテーブルが良いと思います。 –

    +0

    @Harper:それは正しいですが、実用的な観点からは、別の結合(および複数列の主キー)を意味します。 –

    0

    このようなサウンドはternary relationshipとしてモデル化できます。このMSDNの記事のアプローチが好きかどうかを確認してください。

    0

    私の個人的な好みは、あなたが明示前提とテーブルを使用(雇用庁のスーパータイプと出版社)することができない持っていることであろう。これは、データ構造に対するすべての変更が、あなたが管理するストアドプロシージャを介して行われている限り、必ずしも問題ではありません。

    私の最終的な好みは、AgencyEmployeesとPublisherEmployeesの1つのテーブルを持つというあなたの提案に似ています。しかし、私はこれをさらに一歩進めて外に出ます...私はこれを行うだろう

    Table1: Agency    (id, name, etc) 
    Table2: Publisher   (id, name, etc) 
    Table3: Employee   (id, name, etc) 
    Table4: AgencyEmployees  (agency_id, employee_id) 
    Table5: PublisherEmployees (publisher_id, employee_id) 
    


    一つの理由は、それがこの時間依存にするために些細になることです。従業員は会社間で出発、離職、移動します。上記を次のようにわずかな修正では、あなたがそれを追跡することができるようになる...

    Table1: Agency    (id, name, etc) 
    Table2: Publisher   (id, name, etc) 
    Table3: Employee   (id, name, etc) 
    Table4: AgencyEmployees  (agency_id, employee_id, start_date, leave_date) 
    Table5: PublisherEmployees (publisher_id, employee_id, start_date, leave_date) 
    

    これは、任意の一時点で従業員一人当たり1人の雇用者を強制しませんが、それはなど、あなたのストアドプロシージャ、GUI、によって強制することができます..私はこのアプローチを使用している

    0

    Employee.EmployerType( 'AGENCY' または 'PUBLISHER')

    Employee.EmployerID(AgencyIDまたは発行者ID)

    それは正常に動作しますが、多くのSQLではcase文が必要です。 ORMを使用している場合は、FK関係を失います。

    ほとんどのコードをn:m関係に移動して、ORMのFKサポートを利用できるようにしています。

    0

    明らかに雇用エンティティが好ましいであろうが、それ以外は... AgencyEmployee & PublisherEmployeeテーブルを持つ

    は、従業員が一つのカテゴリまたは別に属している場合、それを判断するのが難しいことを意味します。

    代わりにEmployersType列をEmployeesテーブルに追加します。それは後続のSQLクエリに少し複雑さを追加しますが、あなたが与えた制約内で動作します。

    なぜ、AgencyEmployee & PublisherEmployeeテーブルを追加できますが、Employerテーブルを追加できないのはなぜですか?ちょうど好奇心...

    0

    A + 1 Can BerkGüder。

    技術的には、雇用者のスーパータイプを導入するということは、雇用者の上位タイプを導入するということは、雇用者のキーを持つAgencySpecific(それを呼び出す方法がわからない)とすべてのAgency固有の属性と雇用主キーを外部キーとして使用し、AgencySpecificとEmployerだけで結合するクエリまたはビューとしてのAgency、同様にPublisherに対するキーです。

    毎回参加する必要がある代理店と出版社のデータを2つのテーブルに分散させるのは少し面倒かもしれませんが、代理店を使用して1回、Publisherを1回使用して、それらの組合を手作りして結果を結合します。 (私は、このような基本的なものを手助けするクエリビルダーを見ていませんでした。)私は "スーパータイプなし"アプローチを使用したプロジェクトでそれをやらなければならず、もう一度やりたくありません。

    BTWの三項関係とn対nの関係でさえ、あなたが私に尋ねると良い設計慣行ではありません。例えば1対nおよび1対1の機能のみを使用する。制約が定式化するのがずっと容易になります。