[sql] 여러 테이블에서 기본 키를 참조하는 외래 키?

직원 데이터베이스 아래에 두 개의 테이블, 즉 employee_ce 및 employee_sn이 있습니다.

둘 다 고유 한 기본 키 열이 있습니다.

deductions라는 또 다른 테이블이 있는데, 그 외래 키 열은 employee_ce 및 employee_sn의 기본 키를 참조합니다. 이게 가능해?

예를 들면

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

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

이것이 가능합니까?

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



답변

내가 귀하의 시나리오를 올바르게 이해했다고 가정하면 이것이 올바른 방법 이라고 부를 것입니다 .

데이터베이스에 대한 높은 수준의 설명에서 시작하십시오! 직원이 있고 직원은 “ce”직원과 “sn”직원이 될 수 있습니다. 객체 지향 용어로 “employee”클래스가 있으며 “ce employee”와 “sn employee”라는 두 개의 하위 클래스가 있습니다.

그런 다음이 상위 수준 설명을 employees, employees_ceemployees_sn:의 세 테이블로 변환합니다 .

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

모든 직원이 직원이기 때문에 (duh!) 모든 직원은 employees테이블에 행이 있습니다 . “ce”직원도 employees_ce테이블에 행이 있고 “sn”직원도 employees_sn테이블에 행이 있습니다. employees_ce.id에 외래 키 employees.id것처럼 employees_sn.id입니다.

모든 종류의 직원 (ce 또는 sn)을 참조하려면 employees표를 참조하십시오 . 즉, 문제가 발생한 외래 키는 해당 테이블을 참조해야합니다!


답변

두 개의 외래 키 제약 조건을 추가 할 수 있지만 (솔직히 시도해 본 적이 없습니다) 두 테이블에 부모 행이 존재한다고 주장합니다.

대신 두 종업원 하위 유형에 대한 상위 유형을 만든 다음 대신 외래 키를 가리킬 수 있습니다. (물론 두 가지 유형의 직원을 분할해야하는 타당한 이유가 있다고 가정합니다.)

                 employee
employees_ce     ————————       employees_sn
————————————     type           ————————————
empid —————————> empid <——————— empid
name               /|\          name
                    |
                    |
      deductions    |
      ——————————    |
      empid ————————+
      name

type직원 테이블에서 ce또는 sn.


답변

사실 제가 직접합니다. 3 개의 다른 테이블에있는 레코드에 대한 주석이 포함 된 ‘Comments’라는 테이블이 있습니다. 두 솔루션 모두 실제로 원하는 모든 것을 처리하지 않습니다. 귀하의 경우 다음을 수행합니다.

해결책 1 :

  1. 각각의 테이블에서 다른 기본값을 가진 tinyint 필드를 employee_ce 및 employee_sn에 추가합니다 (이 필드는 ‘테이블 식별자’를 나타내므로이를 tid_ce 및 tid_sn이라고합니다).

  2. 테이블의 PK 및 테이블 ID 필드를 사용하여 각 테이블에 고유 인덱스를 만듭니다.

  3. ‘Deductions’테이블에 tinyint 필드를 추가하여 외래 키 (테이블 ID)의 후반부를 저장합니다.

  4. ‘공제’테이블에 외래 키 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. ‘Deductions’테이블에 두 번째 외래 키 필드를 만들고 두 외래 키 모두에 Null 값을 허용하고 일반 외래 키를 만듭니다.

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

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

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

무결성은 열이 널이 아닌 경우에만 확인되므로 참조 무결성을 유지할 수 있습니다.


답변

나는 이것이 오랫동안 정체 된 주제라는 것을 알고 있지만 여기에서 검색하는 사람은 다중 테이블 외래 키를 다루는 방법입니다. 이 기술을 사용하면 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


답변

기술적으로 가능합니다. 공제에서 employee_ce를 참조하고 employee_sn을 참조하십시오. 하지만 employee_sn과 employee_ce를 병합하지 않는 이유는 무엇입니까? 나는 당신이 두 개의 테이블을 가진 이유를 알지 못합니다. 일대 다 관계가 없습니다. 그리고 (이 예에서는 아님) 많은 열.

한 열에 대해 두 개의 참조를 수행하는 경우 직원 두 테이블 모두에 항목이 있어야합니다 .


답변

예, 가능합니다. 세 번째 테이블에 대해 2 개의 FK를 정의해야합니다. 한 테이블의 필수 필드를 가리키는 각 FK (즉, 외부 테이블 당 1 FK).


답변

어떤 이유로 두 직원 유형에 대해 두 개의 테이블이 있어야한다고 가정하면 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에서 지원되지 않으므로 앱이 제약 조건을 적절하게 관리하는지 확인해야합니다 (동일한 데이터베이스에 여러 앱 / 서비스가있는 경우 더 번거 로움).