모든 테이블에 단일 필드 대리 / 인공 기본 키가 있어야합니까?


33

대리 / 인공 키의 일반적인 이점 중 하나는 변경되지 않으며 매우 편리 할 수 ​​있다는 것입니다. 그것들이 '인공적인'것이기 만하더라도 단일 또는 다중 필드이든 마찬가지입니다.

그러나 때때로 자동 증가 정수 필드를 각 테이블의 기본 키로 사용하는 것이 정책의 문제인 것 같습니다. 이것이 항상 단일 필드 키 를 갖는 것이 가장 좋은 아이디어 입니까? 왜 그 이유는 무엇입니까?

분명히,이 질문은 인공 대 자연에 관한 것이 아니라 모든 인공 키가 단일 필드 여야하는지에 관한 것 입니다.


답변:


28

나는 말할거야 더, 항상하지만, 시간 예 대부분. .

다음은 대리 또는 인공 키가 필요하지 않은 상황입니다.

  • 순수한 교차 테이블 . 이없는 경우 에는 외래 키와 경우 목표 인 교차로의 위험이 거의 또는 독립적 인 특성 (FK의 두 부모 테이블 이외 즉, 무언가를) 유치 교차로의 위험은 당신이 조합을 사용하여 멀리 얻을 수 있습니다 공정한 확신을 가지고 PK로서 FK의
  • 정적 비즈니스 키가있는 룩업 테이블 . 당신은 조회가있는 경우
    귀하의 외부에 고정 된 고유 한 비즈니스 키를 사용하여 테이블을
    가지고 사업 적 변화의 제로 기회 어떤을 위해
    다음 수 있습니다 직접 비즈니스 키를 사용하여, 실제적인 목적
    일이 간단합니다. 예를 들어시 /도
    코드 목록 또는 ANSI 표준 번호 목록 등이 있습니다.
  • 여러 개의 독립적 인 소스에서 통합 된 데이터가 포함 된 테이블 . 시스템에 하나의 테이블로 묶어야하는 많은 데이터 소스가있는 경우 (예 : 본사), 때로는 소스 시스템 키 값과 소스 시스템을 나타내는 코드가 포함 된 복합 키가 필요할 수 있습니다.

예전 충실한 단조 증가 정수 대리 키가 이상적이지 않은 상황도 있습니다. 영숫자 대리 키인 키를 가질 수 있습니다. 여기에는 다음이 포함될 수 있습니다.

  • 여러 독립 소스의 데이터를 병합해야하는 상황 키 충돌을 피하기 위해 IDENTITY 키 대신 GUID를 사용할 수 있습니다.
  • 숫자가 아닌 키 표현을 사용해야하는 상황. 자동차 번호판 데이터베이스가 있다고 가정 해 봅시다. 키는 순수한 숫자 대신 영숫자 값이 될 수 있습니다.
  • 일부 외부 요구 사항으로 인해 키 값에 압축을 적용해야하는 상황 int32에 10 자리를 사용하는 대신 6 개의 기본 36 자리를 사용할 수 있습니다.

왜 그렇습니까? 이 질문에 대한 가장 근본적인 대답은 어떤 테이블에서든 기본 키 값을 수정해야 할 경우 순수한 지옥이라는 것입니다. 사용자가 보거나 만질 수있는 거의 모든 것이 어느 시점에서 업데이트 될 수 있기 때문에 , 보이는 키 값을 사용하는 것은 순수한 지옥을 초대합니다. 서로 게이트 키를 사용하면이 트랩에 빠지지 않습니다.

YAGNI가이 개념을 적용 할 여지가 있다는 것을 기억하십시오. 직원 테이블의 남성 성별 기호가 M에서 X로 변경되거나 어리석은 무언가를 결정 해야하는 경우를 대비하여 IDENTITY 키가있는 코드 테이블을 스키마의 구석 구석에 넣을 필요가 없습니다.


"대리 키를 사용하면이 함정에 빠지지 않습니다."문제는 대리 대 자연이 아니라 단일 필드 대 다중 필드 대리에 관한 것입니다.
Jack Douglas

자신의 답변에 대한 의견에서 인정한 바와 같이, 우리는 데이터베이스 설계에 신중한 내용에 대해 "동의하지 않음"영역에 있습니다. 편집 내용을 감안할 때 대리 키와 자연 키를 구분하지 않았으므로 두 번째 글 머리 기호는 뒤늦게 주제가 아닙니다. 고전적 정체성 / 시퀀스 접근법에서 벗어날 수있는시기에 관한 나의 다른 요점은 여전히 ​​유효하다.
Joel Brown

나는 당신이 역사에서 볼 수 있듯이 질문을 변경하지 않았으며, 그것이 탈지 독자들을 도울 것이라고 생각한 부분을 강조했습니다.
Jack Douglas

12

아니.

적어도 외래 키의 목적으로 단일 필드 키가 복합 키보다 열등한 경우가 있다고 분명히 말하고 싶습니다 . 즉, 원하는 경우 단일 필드 대리 키를 가져서는 안된다는 말은 아니지만 기본적으로 외래 키의 대상으로 가장 많이 사용되는 키를 기본 키라고합니다.

다음 예제에서 요점을 설명하려고 시도합니다.

  • brand 예를 들어 포드, 토요타 등
  • dealer 브랜드에 묶여있는 실제 대리점입니다 (예 : Ford 대리점 만 판매하는 Ford 대리점)
  • model Ford Focus, Ford Fiesta 등 자동차의 유형입니다.
  • stock 각 대리점의 현재 앞마당 차량 수입니다.

우리가 하나의 필드 대리 키를 생성하는 경우에 대한 dealer그리고 model다음과 같이 :

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

stockFord dealer를 "Toyota"모델에 연결하는 행을 삽입 할 수 있습니다 . 추가 brand_id references brandstock유일한 문제 악화시킨다. 반면에 외래 키를 기본 키의 일부로 다음과 같이 유지하는 경우 :

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

이제 "포드"딜러가 "포드"자동차 만 재고를 보유 할 수 있다는 규칙이 모델에 의해 자연스럽게 적용됩니다.

'복합 키'예에서 dealer_id선호도에 따라 고유하거나 고유하지 않을 수 있습니다. 고유해야 할 필요는 없지만 (예 : 대체 키) 키를 너무 적게 잃어 버리면 (아마도 약간의 저장 공간), 일반적으로 설정 한 방식과 같이 매우 편리 할 수 ​​있습니다. 예 :

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )

3
모든 각도에서 완벽하지는 않지만 예제에 대한 일반적인 조항을 고려할 때 이러한 유형의 디자인은 특히 취약합니다. DRI를 사용하여 비즈니스 규칙을 적용 할 수있는 방법을 찾는 것이 만족 스럽지만 변경 사항에 대응할 수있는 능력도 일부 제거됩니다. Toyota가 Ford를 구입하거나 Ford 딜러가 중고 Toyota를 판매하기로 결정한 경우에도 DRI 중심 비즈니스 규칙에 따라 유지 관리 문제가 발생합니다.
Joel Brown

1
따라서 "비즈니스 규칙이 변경 될 수 있습니다". 이는 모든 비즈니스 규칙에 해당되며 항상 리모델링하기가 어려울 수 있습니다. 나는 일반적으로 얻을 말했다 비즈니스 규칙이 무엇인지 - 나는 나 자신을 위해이를 결정하지 않습니다.
잭 더글러스

1
비즈니스 규칙을 시행하기 위해 DRI를 전혀 사용해서는 안된다는 말입니까? 그것이 DRI가하는 유일한 일이 아닙니까? -간단한 외래 키조차도 DRI에서 시행하는 비즈니스 규칙입니다.
Jack Douglas

4
물론 DRI는 비즈니스 규칙을 시행합니다. 코드에서 적용 할 규칙과 스키마에서 어떤 규칙을 적용할지 결정해야합니다. 스키마 변경은 코드 변경보다 거의 항상 어렵습니다. 데이터 모델에는 두 가지 종류의 비즈니스 규칙이 있습니다. 하나는 거기에 속하고 하나는 그렇지 않습니다. 비즈니스에 중요한 데이터의 기본 특성은 크게 변하지 않습니다. 해당 데이터를 조작하는 구체적인 방법은 훨씬 더 변동 적 입니다. 자동차와 같은 규칙은 제조업체가 데이터 모델에 속합니다. 딜러와 같은 규칙은 절대 두 가지 브랜드의 자동차를 판매하지 않습니다.
Joel Brown

4
"스키마 변경은 거의 항상 코드 변경보다 어렵습니다."IMO 반대의 경우도 마찬가지입니다. 실제로 나는 당신이 방금 말한 모든 것에 동의하지 않지만 당신과 함께 던지기를 주장하는 요점이 있는지 의심 스럽습니다.
Jack Douglas

12

"의존한다"

예 : 대리 IDENTITY / AUTONUMBER 필드는 자연 키가 넓고 숫자가 아닌 경우에 적합합니다. 참고 : 이것은 SQL Server 및 Sybase 등에서 기본적으로 발생하는 "PK"와 클러스터형 인덱스의 통합을 가정합니다.

아니오 : 2 개의 상위 키로 충분할 때 많은 / 많은 테이블. 또는 자연 키가 짧고 고정 된 길이 인 경우 (예 : 통화 코드)

물론 브레인 데드 ORM (읽기 : (n) 최대 절전 모드)이이 규칙보다 우선 할 수 있습니다.

편집 : 질문 다시 읽기

2 개의 대리 상위 키가있는 다수 / 많은 테이블에는 다중 열 PK가 있습니다.
그러나 다른 대리 열이 필요하지 않습니다.

테이블에 서로 게이트 (IDENTITY 등) 키가 있으면 여러 열일 필요는 없습니다.

대리가 포함 된 수퍼 키를 가질 수 있지만 다른 규칙 (예 : 하위 유형 ) 을 시행하는 것입니다.

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