복붙노트

[SQL] 다중 열 외래 키 제약 조건

SQL

다중 열 외래 키 제약 조건

나는 다음과 같은 시나리오에 대한 설치 테이블 제약으로 원하고 나는 그것을 할 방법을 잘 모르겠어요하거나 SQL Server 2005의 경우에도 가능합니다.

나는 세 개의 테이블 A, B, C가있다. C는 B를 B의 자식 (null도 가능) 성능상의 이유로 A를 참조 나는 또한 테이블 C의 제약이 C해야 테이블 A에 같은 외래 키 참조를 가지고 테이블 C를 원하는 옵션 외래 키를 것입니다 부모 (B)을 참조하고 또한, 부모와 같은 동일한 외부 키 참조를 가져야한다.

누군가는이 작업을 수행하는 방법에 대한 생각을?

해결법

  1. ==============================

    1.그러나, 당신이 물어 않았다 - 일반적으로 나는이 작업을 수행하려면 특정 이유가 표시되지 않습니다.

    그러나, 당신이 물어 않았다 - 일반적으로 나는이 작업을 수행하려면 특정 이유가 표시되지 않습니다.

    이해하는 것은 관계형 모델은 OO 모델을 따를 필요가 없다는 것입니다. 이는 현재 고객 주문-되고 광고 항목 표준 방법입니다. 이와 아무것도 잘못.

    나는 고객에 속하는 모든 라인 항목을 찾으려면, 나는 OO 도트 점 표기법 (Customer.Order.LineItem)과 유사한 주문 테이블을 통해 가입해야합니다.

    select * 
    from Customer as c
    join Order    as o on o.CustomerId = c.CustomerId
    join LineItem as i on i.OrderId    = o.OrderId
    where CustomerID = 7 ;
    

    내가 좋아하는, 키를 조금 수정한다고 가정하자 :

    CustomerOrderId 각 고객 (1,2,3 ...)에 대한 주문 순서 번호와 CustomerOrderItemId은 고객의 주문 (1,2,3 ...)의 각 라인 항목의 일련 번호입니다. 각 하나 같이 발생하기 쉽다

    -- next CustomerOrderId
    select coalesce(max(CustomerOrderId), 0) + 1
    from  Order
    where CustomerId = specific_customer_id;
    
    -- next CustomerOrderItemId
    select coalesce(max(CustomerOrderItemId), 0) + 1
    from  LineItem
    where CustomerId      = specific_customer_id
      and CustomerOrderId = specific_customer_order_id;
    

    나는 고객 (일부 고객 데이터)에 속하는 라인 항목을 찾으려면 지금, 나는 주문 테이블을 건너 뛸 수 있습니다.

    select * 
    from Customer as c
    join LineItem as i on i.CustomerId = c.CustomerId
    where CustomerID = 7 ;
    

    나는 고객 테이블에서 특정 데이터를 필요로하지 않는 경우 그리고, 필요가 전혀 참여 없습니다. 첫 번째 예와 비교해 - 라인 항목을 얻는 것이 목적 이었다는 것을 기억한다.

    select * 
    from LineItem
    where CustomerID = 7 ;
    

    그래서, 관계형 모델 (자연) 키를 전파함으로써, 당신은 조인의 "관계 경로를 따라 각 역에서 정지"항상 필요가 없습니다.

    어떤게 더 좋아? 당신이 구하는 자 따라 달라집니다.

    당신이 당신의 예에 기본 원칙을 번역 할 수있을 것입니다 희망 - 나는 일반 (A, B, C)에서 작동하도록 하드를 찾을 수 있습니다.

  2. ==============================

    2.단순히 A에 B를 C에서 체인을 따라 명시 적으로 A로 C에서의 관계를 시행 할 필요가 표시되지 않습니다

    단순히 A에 B를 C에서 체인을 따라 명시 적으로 A로 C에서의 관계를 시행 할 필요가 표시되지 않습니다

  3. ==============================

    3.성능 향상의 목적을 위해 비정규은 증거의 가치를 보여주는이 특히 매우 일반적입니다. 난 당신이 내가 그것을 해결하지 않도록, 그렇게 좋은 이유가 가정합니다.

    성능 향상의 목적을 위해 비정규은 증거의 가치를 보여주는이 특히 매우 일반적입니다. 난 당신이 내가 그것을 해결하지 않도록, 그렇게 좋은 이유가 가정합니다.

    당신은 단순히 테이블 B의 조회에 따라 열 참조하는 테이블 A를 설정 C에 삽입 트리거를 가지고 생각 했습니까? 당신은 또한 항상 동기화 확인하기 위해 C와 B에 업데이트 트리거를해야 할 수도 있습니다. 이것은 실제 제약에 의해 "강제"되지 않은 경우에도, 참조 테이블 A는 항상 올바른 테이블 C의 열을 확인합니다.

  4. ==============================

    4.당신은 테이블 B 이중 기본 키가 있습니다 (A의 키를 누른 다음 정체성 말), 다음 그래도 B에 널 외래 키 참조가 허용하지 않습니다 C.이 링크에 그것을 사용할 수 있지만, 외래 키 널 (null) 어쨌든이 될 수 없습니다.

    당신은 테이블 B 이중 기본 키가 있습니다 (A의 키를 누른 다음 정체성 말), 다음 그래도 B에 널 외래 키 참조가 허용하지 않습니다 C.이 링크에 그것을 사용할 수 있지만, 외래 키 널 (null) 어쨌든이 될 수 없습니다.

    제대로 등 폭넓게 인덱스가 정말 있다면, C와 A의 키 A의 키 (거의 없음 등) 성능 저하의 정도되지 않습니다 얻기 위해 테이블 ​​B에 가입 밀어 진정한 필요가 없습니다있다.

  5. ==============================

    5.당신이 키를 가지고 다음과 같은 쿼리를 빠르게해야하는 경우 C.에서의 모든 일치하는 행을해야 할 것입니다에 대한 일반적인 사용 사례처럼 보인다 :

    당신이 키를 가지고 다음과 같은 쿼리를 빠르게해야하는 경우 C.에서의 모든 일치하는 행을해야 할 것입니다에 대한 일반적인 사용 사례처럼 보인다 :

    select C.* 
    from B
    join C on C.Bid = B.Bid
    where C.Aid = <value>
    

    그들은 모두 C 테이블에 그 결과를 결합하여 다음 인덱스 스캔을 필요로하기 때문에 당신이 C에 원조를 가지고있는 것처럼 적절한 인덱스 이것은 단지 빨리해야한다.

  6. from https://stackoverflow.com/questions/4520289/multiple-column-foreign-key-contraints by cc-by-sa and MIT license