96

データベースemployeesの下にemployees_ceとemployees_snの2つのテーブルが必要です。

どちらにも、それぞれ固有の主キー列があります。

控除と呼ばれる別のテーブルがあります。このテーブルの外部キー列は、employees_ceとemployees_snの主キーを参照します。これは可能ですか?

例えば

employees_ce
--------------
empid   name
khce1   prince

employees_sn
----------------
empid   name
khsn1   princess

だからこれは可能ですか?

deductions
--------------
id      name
khce1   gold
khsn1   silver
4

7 に答える 7

107

私があなたのシナリオを正しく理解していると仮定すると、これは私がこれを行う正しい方法と呼ぶものです:

データベースの上位レベルの説明から始めましょう! あなたには従業員がいて、従業員は「ce」従業員と「sn」従業員になることができます(それらが何であれ)。オブジェクト指向の用語では、「従業員」というクラスがあり、「ce 従業員」と「sn 従業員」と呼ばれる 2 つのサブクラスがあります。

次に、この上位レベルの説明を 、および の 3 つのテーブルに変換employeesemployees_ceますemployees_sn

  • employees(id, name)
  • employees_ce(id, ce-specific stuff)
  • employees_sn(id, sn-specific stuff)

すべての従業員は従業員であるため (当たり前!)、すべての従業員がemployeesテーブルに行を持ちます。「ce」の従業員もemployees_ceテーブルに行があり、「sn」の従業員もemployees_snテーブルに行があります。はそのままemployees_ce.idの外部キーです。employees.idemployees_sn.id

あらゆる種類の従業員 (ce または sn) を参照するには、次のemployees表を参照してください。つまり、問題が発生した外部キ​​ーはそのテーブルを参照する必要があります。

于 2009-03-21T09:13:14.367 に答える
23

おそらく2つの外部キー制約を追加できますが(正直なところ、私は試したことがありません)、親行が両方のテーブルに存在することを要求します。

代わりに、2つの従業員サブタイプのスーパータイプを作成し、代わりに外部キーをそこにポイントすることをお勧めします。(もちろん、2つのタイプの従業員を分割する正当な理由があると仮定します)。

                 employee       
employees_ce     ————————       employees_sn
————————————     type           ————————————
empid —————————&gt; empid <——————— empid
name               /|\          name
                    |  
                    |  
      deductions    |  
      ——————————    |  
      empid ————————+  
      name

type従業員テーブルではceまたはになりsnます。

于 2009-03-21T07:46:38.007 に答える
21

実はこれは自分でやっています。他の 3 つのテーブルのレコードに対するコメントを含む「コメント」というテーブルがあります。どちらのソリューションも、おそらく必要と思われるすべてを実際に処理しません。あなたの場合、これを行います:

解決策 1:

  1. 各テーブルで異なるデフォルト値を持つ tinyint フィールドを employees_ce および employees_sn に追加します (このフィールドは「テーブル識別子」を表すため、tid_ce および tid_sn と呼びます)。

  2. テーブルの PK とテーブル ID フィールドを使用して、各テーブルに一意のインデックスを作成します。

  3. 「Deductions」テーブルに tinyint フィールドを追加して、外部キーの後半 (テーブル ID) を格納します。

  4. 「Deductions」テーブルに 2 つの外部キーを作成します (参照整合性を適用することはできません。どちらか一方のキーが有効になるか、もう一方のキーが有効になるためです...ただし、両方が有効になることはありません。

    ALTER TABLE [dbo].[Deductions]  WITH NOCHECK ADD  CONSTRAINT [FK_Deductions_employees_ce] FOREIGN KEY([id], [fk_tid])
    REFERENCES [dbo].[employees_ce] ([empid], [tid])
    NOT FOR REPLICATION 
    GO
    ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_ce]
    GO
    ALTER TABLE [dbo].[Deductions]  WITH NOCHECK ADD  CONSTRAINT [FK_Deductions_employees_sn] FOREIGN KEY([id], [fk_tid])
    REFERENCES [dbo].[employees_sn] ([empid], [tid])
    NOT FOR REPLICATION 
    GO
    ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_sn]
    GO
    
    employees_ce
    --------------
    empid    name     tid
    khce1   prince    1
    
    employees_sn
    ----------------
    empid    name     tid 
    khsn1   princess  2
    
    deductions
    ----------------------
    id      tid       name  
    khce1   1         gold
    khsn1   2         silver         
    ** id + tid creates a unique index **
    

解決策 2: この解決策により、参照整合性を維持できます。 1. 「控除」テーブルに 2 番目の外部キー フィールドを作成し、両方の外部キーで Null 値を許可し、通常の外部キーを作成します。

    employees_ce
    --------------
    empid   name
    khce1   prince 

    employees_sn
    ----------------
    empid   name     
    khsn1   princess 

    deductions
    ----------------------
    idce    idsn      name  
    khce1   *NULL*    gold
    *NULL*  khsn1     silver         

整合性は、列が null でない場合にのみチェックされるため、参照整合性を維持できます。

于 2012-01-10T16:48:18.480 に答える
6

これは長い停滞したトピックであることは知っていますが、誰かがここで検索した場合に備えて、複数テーブルの外部キーを処理する方法を示します。この手法を使用すると、DBA によって強制されるカスケード操作がまったくないためDELETE、コードで などを処理するようにしてください。

Table 1 Fruit
pk_fruitid, name
1, apple
2, pear

Table 2 Meat
Pk_meatid, name
1, beef
2, chicken

Table 3 Entity's
PK_entityid, anme
1, fruit
2, meat
3, desert

Table 4 Basket (Table using fk_s)
PK_basketid, fk_entityid, pseudo_entityrow
1, 2, 2 (Chicken - entity denotes meat table, pseudokey denotes row in indictaed table)
2, 1, 1 (Apple)
3, 1, 2 (pear)
4, 3, 1 (cheesecake)

SO Op の例は次のようになります

deductions
--------------
type    id      name
1      khce1   gold
2      khsn1   silver

types
---------------------
1 employees_ce
2 employees_sn
于 2016-04-28T18:04:32.050 に答える
2

技術的に可能です。おそらく、控除額とemployees_snでemployees_ceを参照します。しかし、employees_snとemployees_ceをマージしてみませんか?テーブルが2つある理由はわかりません。1対多の関係。そして(この例ではありませんが)多くの列。

1つの列に対して2つの参照を行う場合、従業員は両方のテーブルにエントリを持っている必要があります。

于 2009-03-21T07:42:31.107 に答える
1

はい、可能です。3番目のテーブルに2つのFKを定義する必要があります。1つのテーブルの必須フィールドを指す各FK(つまり、外部テーブルごとに1つのFK)。

于 2009-03-21T07:43:41.400 に答える
0

何らかの理由で 2 つの従業員タイプに対して 2 つのテーブルが必要であると仮定すると、vmarquez の回答を拡張します。

スキーマ:

employees_ce (id, name)
employees_sn (id, name)
deductions (id, parentId, parentType, name)

控除のデータ:

deductions table
id      parentId      parentType      name
1       1             ce              gold
2       1             sn              silver
3       2             sn              wood
...

これにより、演繹がスキーマ内の他のテーブルを指すようにすることができます。この種の関係は、データベース レベルの制約である IIRC ではサポートされていないため、アプリが制約を適切に管理していることを確認する必要があります (複数の異なるアプリ/サービスが同じデータベースにヒットしている場合は、より面倒になります)。

于 2011-05-10T21:42:03.807 に答える