다 대다 (정션) 테이블에 고유 ID 열이 필요합니까?


22

EF로 몇 가지 프로젝트를 시작했지만 조인 테이블 및 키 등에 대해 몇 가지 질문이있었습니다. 응용 프로그램 테이블과 권한 테이블이 있다고 가정하겠습니다. 응용 프로그램에는 많은 권한이 있으며 각 권한은 많은 응용 프로그램에 속할 수 있습니다 (다 대다).

이제 응용 프로그램 및 권한 테이블이 쉽습니다.

Applications
--------------
PK  ApplicationID
    Name

Permissions
--------------
PK  PermissionID
    Name

그러나 조인 테이블을 수행하는 가장 좋은 방법은 무엇입니까? 이 두 가지 옵션이 있습니다.

ApplicationPermissions
-----------------------
PK  ApplicationPermissionID
CU  ApplicationID
CU  PermissionID

또는

ApplicationPermissions
-----------------------
CPK ApplicationID
CPK PermissionID

PK = Primary Key
CPK = Composite Primary Key
CU = Composite Unique Index

다른 방법으로 불에 태워 본 적이 있습니까? 엄격하게 선호합니까? 많은 "차이"가 저의 리포지토리 패턴에 의해 추상화 될 것입니다. 무언가), 그러나 나는 어떤 방식 으로든 공포 이야기를 찾고 있다고 생각합니다.

답변:


20

"join"테이블이 아니라 "junction"테이블을 의미한다고 생각합니다.

접합 테이블에 고유 한 ID 필드가있을 필요는 없습니다. 그러한 ID를 결합하거나 필터링 할 필요는 없습니다. 매핑하려는 테이블의 ID 만 조인하거나 필터링합니다. 정션 테이블의 ID는 디스크 공간 낭비입니다.

따라서 "최상의"옵션은 ID를 피하는 것입니다. 일반적으로 접합 테이블에는 2 개의 커버링 인덱스가 있습니다. 각각의 맵핑 색인은 1 차 정렬 필드로 맵핑 된 ID 중 하나를 사용합니다.

그러나 "최고"는 멀지 않습니다. 중복 ID 필드를 갖는 것은 매우 사소한 문제입니다. 소량의 낭비되는 디스크에 대한 공포 이야기는 없습니다. 어쨌든 매핑 된 콤보에서 클러스터링하지 않기 때문에 ID는 클러스터 된 인덱스를 "훔치지"않습니다.

프레임 워크가 모든 테이블에 ID를 갖기를 원하면 계속하십시오. 팀의 데이터베이스 표준이 지시하는 경우 모든 테이블에 ID가 있어야합니다. 그렇지 않으면 피하십시오.


2
글쎄, 당신은 이미 ID를 추가하는 것이 작은 혜택이며, 잠재적 이점으로 쉽게 극복 할 수 있다고 언급 했으므로 모든 테이블에서 고유 ID를 갖는 것이 대부분의 DBMS 및 ORM에서 모범 사례가되는 것처럼 보입니다. ID 가없는 것이 아니라 "최고"또는 "기본"옵션으로 ID갖는 것을 권장 합니다.
Robert Harvey

4
"이러한 ID에 가입하거나 쿼리 할 필요가 없습니다."-기술 상황에서 "절대"라고 말하면 바로 그런 일이 일어나게됩니다. 그 말하고, 거기에 있는 결합 된 실체가 사실 A의 때문에 네 번째 테이블 아직까지 테이블에 가입하면 가입 할 시간 (예, 나는 그것이 더 "접합"테이블보다는 테이블을 "결합"이라 들었습니다) 자신의 비즈니스 목표.
Jesse C. Slicer 2016 년

4
@RobertHarvey. 엔터티에는 ID를 사용하는 것이 좋습니다. 그러나 정션은 많은 관계에 대한 구현 세부 사항이며 그 자체로는 엔티티가 아닙니다. 그러나 Jesse C. 슬라이더가 지적했듯이 접점이 사업체로 간주 될 수있는 경우가 있습니다.
mike30

1
"디스크 공간 낭비." -일부 엔진 (InnoDB?)은 직접 만들지 않으면 (내부) 기본 키를 생성한다고 생각합니다. 따라서 실제로 디스크 공간이 없어도 디스크 공간이 확보되지 않을 수 있습니다.
Alex

@ 알렉스. 매핑 된 ID에 복합 PK를 넣습니다.
mike30

11

수년에 걸쳐 나는 각 테이블 "TableName"에 자동 생성 된 기본 키 "TableNameID"를 예외없이, 접합 테이블에도 제공하는 습관을 들이게되었습니다. "모든 테이블"또는 "일부 테이블"또는 "여러 다른 테이블의 많은 행"에 대해 무언가를 수행하는 일반 코드를 작성할 때 많은 일을 더 쉽게하기 때문에 결코 후회할 수 없다고 말할 수 있습니다.

예를 들어, 누군가가 다른 테이블의 행 (또는 그에 대한 참조)을 파일이나 메모리에 저장하도록 요청하는 경우 (예 : 로깅 목적으로), 정확히 하나만 저장해야한다는 것을 미리 알고있을 때 매우 유용합니다. 테이블 이름 및 정확히 하나의 정수 ID이며 "특수 사례"를 다룰 필요가 없습니다.

또 다른 방법은 결합 된 PK로 시작하면 나중에 외래 키 결합이 필요할 수 있습니다 ( ApplicationPermissions테이블에 FK 참조를 추가하려는 시점이 될 수 있음 ). 다음 요구 사항은이 FK가 다른 속성 또는 외래 키와 함께 고유해야하므로 전체적으로 복잡성이 증가 할 수 있습니다. 물론 대부분의 최신 DB 시스템에서는 처리 할 수 ​​없지만 균일 한 솔루션으로 프로그래머의 삶이 훨씬 편해집니다.

마지막으로 같은 명령문 SELECT ... FROM TABLE WHERE TableNameID IN (id1,id2,...)은 단일 키를 기본 키로 사용하는 것이 좋지만 지금까지 SQL 키를 사용하여 결합 키로이 작업을 수행 할 수는 없었습니다. 미리 이와 같은 쿼리가 필요하지 않다는 것을 미리 알고 있지만 내일 이러한 종류의 SQL로 가장 쉽게 해결할 수있는 요구 사항이있을 경우 놀라지 마십시오.

물론 ApplicationPermissions테이블에 수억 개의 행이 있을 것으로 예상되면 ApplicationPermissionsID. 와 같은 것을 피하는 것이 좋습니다.


나는 당신의 대답을 선택하지 않았습니다. 나는 그것의 측면을 좋아한다. 의견을 보내 주셔서 감사합니다 (공감).
solidau

6

Mike의 답변은 좋지만 다음은 별도의 ID 필드를 추가하거나 추가하지 않는 이유입니다.

  1. 정션 / 조인 테이블 에 ID 이외의 필드가 포함 된 경우 별도의 ID 필드를 사용하십시오 . 이것은 그것이 일류 실체라는 것을 나타내는 경향이 있습니다.

  2. API 또는 기존 로직이 엔티티 검색 / 편집에 단일 필드를 사용하는 경향이있는 경우 별도의 ID 필드를 사용하십시오. 다른 사람들이 더 큰 프로젝트의 맥락에서 코드를 따르는 데 도움이 될 수 있습니다.

  3. 특정 혜택 (KISS) 이없는 경우 사용하지 마십시오 . EF는이 유형의 테이블을 처리하는 방법을 알고 있으며 다른 사람들이이 유형의 관계를 이해하려고 할 때 복합 고유 제한 조건이 누락 될 수 있습니다. 또한 정규화 할 때 튜플을 고유하게 정의하는 가장 작은 키 를 사용하려고합니다 . 두 번째 예에서는 2 개의 개별 후보 기본 키가 효과적으로 있습니다.


-5
table Person
   Id int identity(1,1) not null primary key
   ...other fields go here...
table Address
   Id int identity(1,1) not null primary key
   ...other fields go here...
table PersonAddress
   Id int identity(1,1) not null primary key
   PersonId int not null
   AddressId int not null

모두 인덱스 및 외래 키 만들기 위해 기억 PersonIdAddressId.

다른 사람들이 "더 나은"또는 "해야 할 것"이라고 생각하는 방식에 관계없이 데이터베이스가 올바르게 작동 할 수있는 가장 간단하고 쉬운 방법입니다.


1
이 접근법의 한 가지 문제는 스키마 PersonAddress가 동일 PersonId하고 AddressId값이있는 두 행을 허용한다는 것 입니다.
Sam
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.