외래 키-대리 또는 자연 키를 사용하여 연결 하시겠습니까?


14

테이블 간의 외래 키가 자연 키 또는 대리 키에 연결되어야하는지에 대한 모범 사례가 있습니까? 내가 찾은 유일한 토론은 (내 구글 푸가 부족하지 않은 한) 이 질문에 대한 잭 더글러스의 대답 이며, 그의 추론은 나에게 들리는 것 같습니다. 나는 그 규칙이 바뀌는 것 이상의 논의를 알고 있지만, 이것은 어떤 상황에서도 고려해야 할 것입니다.

묻는 주요 이유는 자연 키가있는 FK를 사용하는 레거시 응용 프로그램이 있지만 개발자가 OR / M (우리의 경우 NHibernate)으로 이동해야한다는 강요가 있으며 포크는 이미 일부를 생성했기 때문입니다. 변경 사항을 위반하므로 자연 키를 사용하여 변경 사항을 다시 적용하거나 레거시 앱을 이동하여 FK에 대리 키를 사용하려고합니다. 내 직감은 원래 FK를 복원하라고 말하지만 이것이 실제로 올바른 길인지 확실하지 않습니다.

우리 테이블의 대부분은 이미 고유 한 제약 조건과 PK로 정의 된 대리 키와 자연 키를 모두 가지고 있으므로 추가 열을 추가 해야하는 것은이 통찰력에서 우리에게 중요하지 않습니다. 우리는 SQL Server 2008을 사용하고 있지만 이것이 모든 DB에 대해 일반적인 것이기를 바랍니다.

답변:


15

SQL 또는 관계형 모델은 자연 키를 참조하는 외래 키에 의해 방해받지 않습니다. 실제로, 자연 키를 참조하면 성능이 크게 향상되는 경우가 많습니다. 필요한 정보가 자연 키에 얼마나 자주 포함되어 있는지 놀랄 것입니다. 키를 참조하면 더 넓은 테이블에 대한 조인이 거래되므로 결과적으로 한 페이지에 저장할 수있는 행 수가 줄어 듭니다.

정의에 따라 필요한 정보는 항상 모든 "조회"테이블의 기본 키에 완전히 포함되어 있습니다. ( 룩업 테이블 이라는 용어 는 비공식적입니다. 관계형 모델에서는 모든 테이블이 테이블 일뿐입니다. 미국 우편 번호 테이블에는 {AK, Alaska}, {AL, Alabama}, {AZ, Arizona}와 같은 행이있을 수 있습니다. 대부분의 사람들은이를 룩업 테이블이라고 부릅니다.)

큰 시스템에서 둘 이상의 후보 키가있는 테이블을 찾는 것은 드문 일이 아닙니다. 엔터프라이즈의 한 부분을 제공하는 테이블이 하나의 후보 키를 참조하는 테이블과 엔터프라이즈의 다른 부분을 제공하는 테이블이 다른 후보 키를 참조하는 것도 드문 일이 아닙니다. 이것은 관계형 모델의 장점 중 하나이며 SQL이 지원하는 관계형 모델의 일부입니다.

서로 게이트 키가있는 테이블에서 자연 키를 참조하면 두 가지 문제가 발생합니다.

첫째, 당신은 사람들을 놀라게 할 것입니다. 나는 보통 최소한의 서프라이즈 원칙을 강하게 로비하지만 , 이것은 사람들을 놀라게하지 않는 한 가지 상황이다. 문제는 개발자가 외래 키를 논리적으로 사용하는 것에 놀랐을 때 해결책은 재 설계가 아닌 교육입니다.

둘째, ORM은 일반적으로 관계형 모델을 중심으로 설계되지 않았으며 때로는 모범 사례를 반영하지 않는 가정을 구현합니다. (실제로 이들은 데이터베이스 전문가의 입력 없이도 종종 설계되는 것 같습니다.) 모든 테이블에서 ID 번호를 요구하는 것이 그러한 가정 중 하나입니다. 다른 하나는 ORM 응용 프로그램이 데이터베이스를 "소유"한다고 가정합니다. 따라서 테이블과 열을 생성, 삭제 및 이름을 바꿀 수 있습니다.

저는 30 년 동안 최소한 24 개 이상의 언어로 작성된 수백 개의 응용 프로그램에 데이터를 제공하는 데이터베이스 시스템을 연구했습니다. 해당 데이터베이스는 ORM이 아닌 엔터프라이즈에 속합니다.

주요 변경 사항을 소개하는 포크는 쇼 스토퍼 여야합니다.

내가 일했던 회사에서 자연 키와 대리 키를 모두 사용하여 성능을 측정했습니다. 서로 게이트 키가 자연 키보다 성능이 뛰어 나기 시작하는 팁이 있습니다. ( 파티션, 부분 인덱스, 함수 기반 인덱스, 추가 테이블 스페이스, SSD (Solid-State Disk) 사용 등)와 같은 자연스러운 키 성능을 유지하려는 추가 노력이 없다고 가정하면 해당 회사에 대한 제 추정치에 따르면 그 사이에, 그들은 자연 키로 더 나은 성능을 얻습니다.

다른 관련 답변 : 데이터베이스 스키마 혼동


5

대리 키를 지원하는 주된 이유는 자연 키가 종종 변경 될 수 있기 때문에 모든 관련 테이블을 업데이트해야하기 때문에 서버에 많은 부하를 줄 수 있습니다.

또한 30 년 동안 많은 주제에 대해 다양한 데이터베이스를 사용해 왔지만 실제 자연 키는 종종 매우 드 rare니다. SSN (고유 한 것)은 아닙니다. 특정 시간에 고유 한 것이 나중에 고유하지 않을 수 있으며 이메일 주소 및 전화 번호와 같은 일부는 고유 할 수 있지만 나중에 다른 사람에게 재사용 할 수 있습니다. 데이트. 물론 어떤 것들은 사람과 회사의 이름과 같은 좋은 고유 식별자를 갖지 않습니다.

자연 키를 사용하여 조인을 피할 수 있습니다. 예. 조인이 필요하지 않은 select 문을 가속화 할 수 있지만 int 조인이 일반적으로 빠르기 때문에 조인이 필요한 위치가 느려질 수 있습니다. 또한 삽입 및 삭제 속도가 느려지고 키가 변경 될 때 업데이트에 성능 문제가 발생할 수 있습니다. 복잡한 쿼리 (어쨌든 느린)는 훨씬 느려질 것입니다. 따라서 간단한 쿼리는 빠르지 만보고 및 복잡한 쿼리 및 데이터베이스에 대한 많은 작업이 느려질 수 있습니다. 이는 데이터베이스 조회 방법에 따라 한 방향 또는 다른 방향으로 기울어 질 수있는 밸런싱 행위입니다.

따라서 모든 대답에 맞는 단일 크기는 없습니다. 데이터베이스 및 쿼리 방법 및 데이터베이스에 저장되는 정보 유형에 따라 다릅니다. 자신의 환경에서 가장 적합한 것이 무엇인지 확인하기 위해 몇 가지 테스트를 수행해야 할 수도 있습니다.


1
"... 천연 키는 종종 변경 될 수 있습니다…"-그러면 좋은 키가 아닙니다! 속성이 자주 변경되는 경우 속성을 키로 사용하지 마십시오 (물론 "종종"에 대한 다양한 정의의 경우). 파비안 파스칼 키를 선택하기위한 네 가지 기준, 즉 친숙성, 비 환원성, 안정성 및 단순성이 있다고 주장했다 . 때로는 대리 키의 단순성을 위해 이들을 교환합니다. HLGEM은 "따라서 모든 답에 맞는 단일 크기는 없습니다"라고 말합니다.
Greenstone Walker

1
@ GreenstoneWalker, 나는 당신이 그것을 열쇠로 다루지 말아야한다는 것에 동의 할 것입니다. 고유성이 공동 키인 경우 조인을 가져야 할 때 성능 측면에서 문제가 더 커질 수 있습니다.
HLGEM

-4

답을 모르면 대리자와 함께 가십시오. 이유는 다음과 같습니다. 비즈니스 규칙에 대해 가정하고 해당 가정이 거짓이거나 규칙이 변경되면 데이터가 쓰레기입니다. 예를 들면 다음과 같습니다.

사람, 역할, 사람 역할

현재 비즈니스 규칙에 따르면 개인에게는 하나의 역할이 있습니다. PersonRole (PersonName, PersonBirthDate, PersonMotherMaidenName, ..., RoleCode)이있는 Person 및 Role을 연결하는 테이블을 작성합니다.

이제 내추럴 키와 관련하여 진정한 순수 주의자입니다! 그러나 진지하게, 조직이 개인이 여러 역할을 맡을 수 있다고 결정하면 어떻게 될까요? 비즈니스 요구의 변화를 지원하는 다운 스트림 효과는 무엇입니까?


2
그리고 대리 키에 이러한 문제가 없습니까? 방법을 알려주세요.
Colin 't Hart

4
주어진 예제는 토론과 관련된 것을 보여주지 않는 것 같습니다.
mustaccio
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.