SQL-다 대다 테이블 기본 키


125

이 질문은이 질문에 대한 주석을 읽은 후에 나타납니다.

데이터베이스 디자인

다 대다 테이블을 생성 할 때 두 개의 외래 키 열에 복합 기본 키를 생성하거나 자동 증가 대리 "ID"기본 키를 생성하고 두 개의 FK 열에 인덱스를 추가해야합니다. 고유 한 제약)? 각 경우에 새 레코드 삽입 / 재 인덱싱 성능에 미치는 영향은 무엇입니까?

기본적으로 이것은 :

PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)

대 이것 :

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)

댓글 작성자는 다음과 같이 말합니다.

두 ID를 PK로 만드는 것은 테이블이 디스크에서 해당 순서로 물리적으로 정렬됨을 의미합니다. 따라서 (Part1 / Device1), (Part1 / Device2), (Part2 / Device3), (Part 1 / Device3)를 삽입하면 데이터베이스는 테이블을 분리하고 항목 2와 3 사이에 마지막 테이블을 삽입해야합니다. 많은 레코드를 추가 할 때마다 수백, 수천 또는 수백만 개의 레코드를 섞는 작업이 포함되므로 매우 문제가됩니다. 반대로 자동 증가 PK를 사용하면 새 레코드를 끝까지 붙일 수 있습니다.

내가 묻는 이유는 항상 대리 자동 증가 열없이 복합 기본 키를 수행하는 경향이 있었지만 대리 키가 실제로 더 성능이 좋은지 확실하지 않기 때문입니다.


여기에 게시 된 silimar 질문이 있습니다 : stackoverflow.com/questions/344068/…
Tony

(이것을 내 이전 댓글에 추가하려고했지만 할 수 없음) 삽입 횟수에 따라 정기적으로 색인을 다시 작성하여 결과를 빠르게 반환 할 수 있습니다. SQL Server에서 인덱스의 FILLFACTOR를 조정하여 데이터를 이동하기 전에 삽입을위한 충분한 공간을 제공 할 수도 있습니다.
Tony

1
이에 대한 답은 어떤 DBMS를 사용 하느냐에 달려 있지 않습니까? 나는 MySQL이 약간 등 다른 방법으로이 경우, SQL-Server의 방식으로 작동합니다 의심
라두 Murzea

주의 사항 : 특정 데이터베이스 태그가 없으면 여기에서 말하는 내용의 대부분이 의심 스럽습니다. 다른 엔진은 다르게 작동합니다!
Rick James

답변:


85

간단한 2 열 다 대다 매핑으로는 대리 키를 갖는 것의 실질적인 이점이 없다고 생각합니다. 기본 키를 설정 (col1,col2)하면 고유 한 것으로 보장 되며 (참조 된 테이블 의 col1col2값이 고유하다고 가정 ) 별도의 인덱스를 설정 (col2,col1)하면 반대 순서가 더 빠르게 실행되는 경우를 포착 할 수 있습니다. 대리자는 공간 낭비입니다.

테이블은 참조 된 두 테이블을 함께 조인하는 데만 사용해야하므로 개별 열에 대한 인덱스가 필요하지 않습니다.

질문에서 언급 한 그 의견은 제 생각에 그것이 사용하는 전자의 가치가 없습니다. 저자는 테이블이 매우 고성능의 균형 잡힌 다 방향 트리 구조가 아니라 배열에 저장되어 있다고 생각하는 것처럼 들립니다.

처음에는 정렬 된 테이블 을 저장하거나 가져올 필요가 없으며 인덱스 만 있으면됩니다 . 인덱스는 순차적으로 저장 되지 않고 빠르게 검색 할 수 있도록 효율적인 방식으로 저장됩니다.

또한 대부분의 데이터베이스 테이블은 작성된 것보다 훨씬 더 자주 읽습니다 . 따라서 선택면에서 수행하는 작업은 삽입면에서 수행하는 작업보다 훨씬 더 관련성이 높습니다.


마지막 요점은 좋은 일반화가 아닙니다. "대부분의 데이터베이스 테이블이 쓰여진 것보다 훨씬 더 자주 읽 힙니다". 고객을 주문에 연결하는 테이블과 같이 매우 자주 작성해야하는 연관 테이블의 많은 예를 찾습니다.
사용자

5
@buffer, 나는 그 주석을지지 할 것이다 (기술적으로, "모든 테이블", "대부분 다수"는 경험을 기반으로하는 경우에만 일반화). 또한 주문이 한 번 생성되는 경우 (가끔 업데이트 될 수 있지만 키 / 인덱스 정보가 변경되지 않을 수 있으며 주문 상태와 같은 항목에 더 많이 적용됩니다. 그러나 이러한 업데이트 및 선택 사항은 송장을 인쇄하거나 관리 보고서를 생성하면 원래 삽입물보다 더 큽니다
paxdiablo 2013-08-26

Amazon을 생각해보십시오. 매시간 수천 개의 주문이 생성됩니다.
사용자

9
@buffer, 예,하지만 다시 말씀 드리지만 각 주문은 패키징, 청구, 상태 업데이트, 비즈니스 분석 등을 수행하기 위해 거의 확실히 여러 번 쿼리 됩니다. 생성의 절대 수는 생성과 읽기 간의 비율 보다 덜 중요합니다 .
paxdiablo

1
내 요점은 insert시간당 수천 번 수행되면 중요 할 것입니다. insertto 의 비율 select이 1 미만 이기 때문에 단순히 무시할 수 없습니다 .이 경우 고객은 주문하는 데 걸리는 시간에 관심이 있습니다.
사용자

19

링크 테이블에는 서로 게이트 키가 필요하지 않습니다.

하나의 PK (col1, col2)와 다른 고유 인덱스 (col2, col1) 만 있으면됩니다.

DB 설계에 대처할 수없고 지시 할 수있는 ORM을 사용하지 않는 한 ...

편집 : 여기에 같은 대답을했습니다. SQL : 다 다양 테이블에 대해 자동 증분 기본 키가 필요합니까?


3
(col2, col1)의 고유 인덱스 대신 col2의 dups 인덱스로 괜찮을 수 있습니다. 2 열 인덱스의 장점은 col2 단독 또는 col1과 col2 모두에 대한 인덱스 전용 스캔을 허용한다는 것입니다 (다른 인덱스 on (col1, col2)도 '둘 다'케이스를 처리하지만). 단점은 추가 컬럼에 필요한 추가 스토리지입니다. 이것은 일반적으로 중요하지 않으므로 조언은 끔찍하지 않습니다. 그럼에도 불구하고 col1과 col2가 크거나 크기가 매우 다른 경우 더 짧은 열에 만 두 번째 인덱스를 사용하도록 선택하여 성능을 손상시키지 않고 약간의 공간을 절약 할 수 있습니다.
Jonathan Leffler

@gbn : (col2, col1)의 두 번째 인덱스는 고유 할 필요가 없습니다.
사용자

1
이미 PK가 된 후에 고유 인덱스를 (col1, col2)에 추가하는 것은 완전히 중복됩니다.
Don Cheadle 2014

@mmcrae : 우리는 어디에서 그것을하고 있습니까?
gbn 2014

2
@mmcrae : 귀하의 의견은 "(col1, col2) ..에 고유 색인을 넣습니다."입니다. 인덱스의 열 순서가 중요합니다. (col2, col1)이 아닙니다 (col1, col2). 의 PK는 (col1, col2)모든 쿼리에 적합하지 않을 수 있으며 스캔을 생성하므로 그 반대를 사용하면 col2가 더 좋은 위치를 찾을 수 있으므로 성능이 향상됩니다. 예를 들어 col2가있는 테이블에 삭제가있는 경우 FK 유효성 검사가 있습니다. 자식 테이블 smuts 확인
gbn

12

테이블이 참조되는 경우 증분 기본 키가 필요할 수 있습니다. 증분 기본 키를 사용하여 다른 테이블에서 가져와야하는 다 대다 테이블에 세부 정보가있을 수 있습니다.

예를 들면

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Other Details

PartDevice.ID를 FK로 사용하여 '기타 세부 정보'를 쉽게 가져올 수 있습니다. 따라서 증분 기본 키를 사용해야합니다.


1
감사! 나는 당신이 설명한 거의 동일한 시나리오를 찾고 있었을 때 답을 얻었습니다. 그러나 "기타 세부 사항"을 추가하여 첫 번째 문장에서 벗어났습니다. 다 대다 매핑 테이블이있는 경우 다른 테이블에서 참조해야합니까? 의미, 다 대다 매핑 테이블에 다른 정보가 저장되어 있지 않습니다 ... 어쨌든 추가 ID 열이 의미가 있습니까? 그렇지 않은 경우 매핑 테이블의 한 레코드를 대신 참조하는 방법은 무엇입니까?
misanthrop

여기에는 두 가지 옵션이 있습니다. 참조 테이블에서 복합 키를 외래 키로 사용하거나 (이렇게하면 새 테이블에 추가 열이 추가됨) 매핑 테이블에 ID 열을 만들고 원래 복합에 고유 제약 조건을 설정할 수 있습니다. 새 ID 열은 기본 키가됩니다.
Vočko

6

질문에 대답 할 수있는 가장 짧고 직접적인 방법은 연결하는 두 테이블에 순차 기본 키가없는 경우 성능에 영향을 미칠 것이라고 말하는 것입니다. 언급 / 인용했듯이 링크 테이블의 인덱스는 조각화되거나 링크 테이블에 자체 순차 기본 키가없는 경우 DBMS가 레코드를 삽입하기 위해 더 열심히 작업합니다. 이것이 대부분의 사람들이 링크 테이블에 순차적으로 증가하는 기본 키를 넣는 이유입니다.


2

따라서 유일한 작업이 두 테이블을 연결하는 것 같다면 최상의 PK는 이중 열 PK 일 것입니다.

그러나 다른 용도로 사용되는 경우 외래 키와 두 번째 고유 색인이있는 PK로 다른 NDX를 추가합니다.

인덱스 또는 PK는 중복이 없는지 확인하는 가장 좋은 방법입니다. PK를 사용하면 Microsoft Management Studio와 같은 도구가 일부 작업 (보기 생성)을 수행 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.