문제

내 데이터베이스에는 다대다 관계가 있는 다음 테이블이 있습니다. 이는 각 기본 테이블의 기본 키에 대한 외래 키가 있는 연결 테이블로 표현됩니다.

  • 위젯:WidgetID(PK), 제목, 가격
  • 사용자:사용자 ID(PK), 이름, 성

각 사용자 위젯 조합은 고유하다고 가정합니다.데이터 관계를 정의하는 연결 테이블을 구성하는 방법에 대한 두 가지 옵션을 볼 수 있습니다.

  1. 사용자 위젯1:UserWidgetID(PK), WidgetID(FK), UserID(FK)
  2. 사용자 위젯2:WidgetID(PK, FK), UserID(PK, FK)

옵션 1에는 기본 키에 대한 단일 열이 있습니다.그러나 테이블에 저장되는 유일한 데이터는 두 기본 테이블 간의 관계이고 이 관계 자체가 고유 키를 형성할 수 있으므로 이는 불필요해 보입니다.따라서 2열 기본 키가 있지만 옵션 1에 있는 1열 고유 식별자가 손실되는 옵션 2로 이어집니다.선택적으로 첫 번째 테이블에 2열 고유 인덱스(WidgetID, UserID)를 추가할 수도 있습니다.

성능 측면에서 두 가지 사이에 실제 차이점이 있습니까? 아니면 UserWidgets 다대다 테이블을 구성하기 위해 다른 접근 방식보다 한 접근 방식을 선호하는 이유가 있습니까?

도움이 되었습니까?

해결책

두 경우 모두 기본 키는 하나만 있습니다.두 번째는 복합 키(compound key)라고 불리는 것입니다.새로운 칼럼을 소개할 이유가 없습니다.실제로는 모든 후보 키에 대해 고유 인덱스를 유지해야 합니다.새 열을 추가하면 유지 관리 오버헤드만 발생합니다.

옵션 2로 가세요.

다른 팁

개인적으로 나는 ~일 것이다 다음과 같은 이유로 다대다 테이블에 합성/대리 키 열이 있습니다.

  • 엔터티 테이블에 숫자 합성 키를 사용한 경우 관계 테이블에 동일한 키를 사용하면 디자인 및 명명 규칙의 일관성이 유지됩니다.
  • 미래에는 다대다 테이블 자체가 개별 행에 대한 고유한 참조가 필요한 하위 엔터티의 상위 엔터티가 되는 경우가 있을 수 있습니다.
  • 실제로 그렇게 많은 추가 디스크 공간을 사용하지는 않습니다.

합성 키는 자연/복합 키를 대체하지 않으며 PRIMARY KEY 해당 테이블은 테이블의 첫 번째 열이기 때문에 Josh Berkus 기사에 부분적으로 동의합니다.그러나 나는 자연 키가 항상 좋은 후보라는 점에 동의하지 않습니다. PRIMARY KEY's 다른 테이블에서 외래 키로 사용하려는 경우에는 사용해서는 안 됩니다.

옵션 2는 간단한 복합 키를 사용하고, 옵션 1은 대리 키.옵션 2는 대부분의 시나리오에서 선호되며 좋은 후보 키라는 점에서 논리적 모델에 가깝습니다.

대리 키를 사용하려는 상황이 있습니다(옵션 1).

  1. 시간이 지남에 따라 복합 키가 좋은 후보 키가 되는 것은 아닙니다.특히 시간 데이터(시간에 따라 변경되는 데이터)의 경우.동일한 UserId 및 WidgetId를 사용하여 UserWidget 테이블에 다른 행을 추가하려면 어떻게 해야 합니까?고용(EmployeeId,EmployeeId)을 생각해 보십시오. 누군가가 나중에 동일한 고용주를 위해 다시 일하게 되는 경우를 제외하고는 대부분의 경우에 작동합니다.
  2. 통합에 사용하기 더 쉬운 키가 필요한 메시지/비즈니스 트랜잭션 또는 이와 유사한 것을 생성하는 경우.어쩌면 복제?
  3. 자신만의 감사 메커니즘(또는 유사한 메커니즘)을 만들고 키가 너무 길어지는 것을 원하지 않는 경우.

경험상 데이터를 모델링할 때 대부분의 연관 엔터티(다대다)가 이벤트의 결과라는 것을 알 수 있습니다.사람이 취업하고 품목이 장바구니에 추가됩니다.대부분의 이벤트는 날짜나 시간이 관련된 이벤트에 대한 시간적 종속성을 가지며, 이 경우 대리 키가 최선의 대안이 될 수 있습니다.

따라서 옵션 2를 선택하되 완전한 모델이 있는지 확인하십시오.

이전 답변에 동의하지만 추가할 말이 하나 있습니다.관계에 더 많은 정보를 추가하고 동일한 두 엔터티 간에 더 많은 관계를 허용하려면 옵션 1이 필요합니다.

예를 들어 사용자 1이 userwidget 테이블에서 위젯 664를 사용한 모든 시간을 추적하려는 경우 userid와 widgetid는 더 이상 고유하지 않습니다.

이 시나리오에서 기본 키의 이점은 무엇입니까?기본 키가 없는 옵션을 고려하세요.사용자 위젯3:위젯ID(FK), 사용자ID(FK)

고유성을 원하면 복합 키(UserWidgets2) 또는 고유성 제약 조건을 사용하세요.

기본 키를 갖는 일반적인 성능 이점은 기본 키로 테이블을 쿼리하는 경우가 많다는 것입니다. 이는 속도가 빠릅니다.다대다 테이블의 경우 일반적으로 기본 키로 쿼리하지 않으므로 성능 이점이 없습니다.다대다 테이블은 외래 키로 쿼리되므로 WidgetID 및 UserID에 인덱스를 추가하는 것을 고려해야 합니다.

옵션 2가 정답입니다. 단, 대리 숫자 키를 추가해야 할 타당한 이유가 있는 경우는 예외입니다(옵션 1에서 수행함).

대리 숫자 키 열은 '기본 키'가 아닙니다.기본 키는 기술적으로 테이블 내의 레코드를 고유하게 식별하는 열 조합 중 하나입니다.

데이터베이스를 구축하는 사람은 누구나 이 기사를 읽어야 합니다. http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 Josh Berkus가 대리 숫자 키 열과 기본 키의 차이점을 이해합니다.

내 경험에 따르면 테이블에 대리 숫자 키를 추가하는 유일한 실제 이유는 기본 키가 복합 키이고 다른 테이블에서 외래 키 참조로 사용해야 하는 경우입니다.그런 다음에야 테이블에 추가 열을 추가하는 것을 고려해야 합니다.

모든 테이블에 'id' 열이 있는 데이터베이스 구조를 볼 때마다 관계형 모델을 이해하지 못하는 사람이 설계했을 가능성이 있으며 Josh의 기사에서 확인된 하나 이상의 문제가 변함없이 표시됩니다.

나는 둘 다와 함께 갈 것입니다.

내 말을 들어보세요:

복합 키는 데이터의 의미를 반영하는 한 훌륭하고 올바른 방법입니다.질문 없음.

하지만:생성된 단일 기본 키(대리 키)를 사용하지 않는 한 최대 절전 모드가 제대로 작동하도록 하는 데 온갖 종류의 문제가 있었습니다.

그래서 저는 논리적이고 물리적인 데이터를 사용하겠습니다. 모델.논리적 키에는 복합 키가 있습니다.논리적 모델을 구현하는 물리적 모델에는 대리 키와 외래 키가 있습니다.

각 사용자-위젯 조합은 고유하므로, 조합을 고유하게 만들어 테이블에 이를 표시해야 합니다.즉, 옵션 2를 선택하세요.그렇지 않으면 위젯과 사용자 ID는 동일하지만 사용자 위젯 ID가 다른 두 개의 항목이 있을 수 있습니다.

첫 번째 테이블의 userwidgetid는 필요하지 않습니다. 말씀하신 것처럼 고유성은 widgetid와 userid의 조합에서 비롯됩니다.

나는 두 번째 테이블을 사용하고, 외래 키를 유지하고 widgetid와 userid에 고유 인덱스를 추가할 것입니다.

그래서:

userwidgets( widgetid(fk), userid(fk),
             unique_index(widgetid, userid)
)

데이터베이스가 키에 대한 인덱스를 계산할 필요가 없으므로 추가 기본 키가 없으면 성능이 약간 향상됩니다.위 모델에서는 이 인덱스(unique_index를 통해)가 여전히 계산되지만 이것이 이해하기 더 쉽다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top