문제

대리 및 자연 키 사이에는 건강한 논쟁이 있습니다.

그래서 게시물 1

그래서 2

대다수와 일치하는 것처럼 보이는 내 의견은 (다수가 얇다) 자연스러운 키가 완전히 명백하지 않고 변경되지 않으면 대리 키를 사용해야한다는 것입니다. 그러면 자연의 열쇠에 대한 독창성을 시행해야합니다. 이는 거의 항상 대리 키를 의미합니다.

회사 테이블로 시작하여 두 가지 접근 방식의 예 :

1 : 대리 키 : 테이블에는 PK (및 ID) 인 ID 필드가 있습니다. 회사 이름은 상태별로 고유해야하므로 고유 한 제약이 있습니다.

2 : 자연 키 : 테이블은 CompanyName과 상태를 PK로 사용합니다. PK와 독창성을 모두 만족시킵니다.

회사 PK가 10 개의 다른 테이블에 사용된다고 가정 해 봅시다. 숫자를 뒷받침 할 숫자가없는 나의 가설은 대리 키 접근 방식이 훨씬 더 빠를 것이라는 것입니다.

내가 Natural Key에서 본 유일한 설득력있는 주장은 두 개의 외국 키를 자연 키로 사용하는 많은 테이블에서 많은 것입니다. 나는 그 경우에 그것이 의미가 있다고 생각합니다. 그러나 리팩터가 필요하다면 곤경에 빠질 수 있습니다. 그것은 내가 생각하는이 게시물의 범위를 벗어났습니다.

누구든지 비교하는 기사를 본 사람이 있습니까? 성능 차이 사용하는 테이블 세트 대리 키 vs. 사용하는 동일한 테이블 세트 자연 키? So와 Google을 둘러 보는 것은 가치있는 일이 없었으며 많은 이론을 만들어 냈습니다.


중요한 업데이트: 나는 만들기 시작했다 테스트 테이블 세트 이 질문에 대답합니다. 다음과 같이 보입니다.

  • Partnatural- 고유 한 파트너를 PK로 사용하는 부품 테이블
  • Parturrogate- ID (int, Identity)를 PK로 사용하고 파트너 맨에 고유 한 색인을 사용하는 부품 테이블
  • plant -id (int, Identity) pk
  • 엔지니어 -ID (int, Identity) AS PK

모든 부분은 공장에 결합되며 플랜트의 모든 인스턴스는 엔지니어와 결합됩니다. 이 테스트 베드에 문제가있는 사람이라면 이제 시간입니다.

도움이 되었습니까?

해결책

둘 다 사용하십시오! 자연 키는 데이터베이스 손상을 방지합니다 (불일치가 더 나은 단어 일 수 있음). "오른쪽"자연 키 (중복 행을 제거하기 위해)가 성능 목적으로 길이 또는 관련 열의 수로 인해 잘못 수행되는 경우, 대리 키를 추가하여 다른 테이블에서 외래 키로 사용할 수 있습니다. 자연 키 ... 그러나 자연 키는 데이터 손상 및 Enforece 데이터베이스 일관성을 방지하기 위해 대체 키 또는 고유 인덱스로 유지되어야합니다 ...

Hoohah의 대부분 (이 문제에 대한 "토론"에서)은 잘못된 가정에 의한 것일 수 있습니다. 기본 키 다른 테이블의 조인 및 외국 키. 이것은 거짓입니다. 당신은 사용할 수 있습니다 열쇠 다른 테이블의 외국 키의 대상으로. 기본 키, 대체 키 또는 고유 한 인덱스 또는 고유 한 제약 조건이 될 수 있습니다. 그리고 조인의 경우, 조인 조건에 대해 전혀 사용할 수 있습니다. 키, IDEX 또는 독특한 일 필요조차 없습니다 !! (독특하지 않다면 직교 제품에서 여러 행을 생성 할 수 있습니다).

다른 팁

천연 키는 유형이 아닌 대리 키와 다릅니다.

모든 유형은 대리 키에 사용할 수 있습니다. VARCHAR 시스템 생성 slug 또는 다른 것.

그러나 대리 키에 가장 많이 사용되는 유형은 다음과 같습니다 INTEGER 그리고 RAW(16) (또는 어떤 유형이든 RDBMS 사용합니다 GUID'에스),

대리 정수와 천연 정수 비교 (예 : SSN) 정확히 같은 시간이 걸립니다.

비교 VARCHARS는 채택을 고려하고 일반적으로 정수보다 길어 효율성이 떨어집니다.

두 세트를 비교합니다 INTEGER 아마도 단일을 비교하는 것보다 덜 효율적일 것입니다 INTEGER.

크기가 작은 데이터 유형 에서이 차이는 아마도일 것입니다 퍼센트의 퍼센트 페이지, 트래버스 인덱스, 획득 데이터베이스 래치 등을 가져 오는 데 필요한 시간 중

그리고 여기 숫자가 있습니다 (in MySQL):

CREATE TABLE aint (id INT NOT NULL PRIMARY KEY, value VARCHAR(100));
CREATE TABLE adouble (id1 INT NOT NULL, id2 INT NOT NULL, value VARCHAR(100), PRIMARY KEY (id1, id2));
CREATE TABLE bint (id INT NOT NULL PRIMARY KEY, aid INT NOT NULL);
CREATE TABLE bdouble (id INT NOT NULL PRIMARY KEY, aid1 INT NOT NULL, aid2 INT NOT NULL);

INSERT
INTO    aint
SELECT  id, RPAD('', FLOOR(RAND(20090804) * 100), '*')
FROM    t_source;

INSERT
INTO    bint
SELECT  id, id
FROM    aint;

INSERT
INTO    adouble
SELECT  id, id, value
FROM    aint;

INSERT
INTO    bdouble
SELECT  id, id, id
FROM    aint;

SELECT  SUM(LENGTH(value))
FROM    bint b
JOIN    aint a
ON      a.id = b.aid;

SELECT  SUM(LENGTH(value))
FROM    bdouble b
JOIN    adouble a
ON      (a.id1, a.id2) = (b.aid1, b.aid2);

t_source 단지 더미 테이블입니다 1,000,000 줄.

aint 그리고 adouble, bint 그리고 bdouble 그것을 제외하고는 정확히 동일한 데이터를 포함합니다 aint 정수가 있습니다 PRIMARY KEY, 동안 adouble 두 개의 동일한 정수가 있습니다.

내 컴퓨터에서 두 쿼리는 14.5 초 동안 실행됩니다. +/- 0.1 초

성능 차이가있는 경우 변동 범위 내에 있습니다.

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