기본 키가 마음에 드십니까? [닫은]


88

우리 팀의 상당히 활발한 토론에서 나는 대부분의 사람들이 기본 키로 좋아하는 것을 생각하도록 만들어졌습니다. 우리는 다음 그룹을 가졌습니다.

  1. 자동 증가가 충분한 기본 키인 Int / BigInt.
  2. 기본 키를 구성하는 열이 3 개 이상 있어야합니다.
  3. ID, GUID 및 사람이 읽을 수있는 행 식별자는 모두 다르게 처리되어야합니다.

PK에 대한 최선의 접근 방식은 무엇입니까? 당신의 의견을 정당화 할 수 있다면 멋질 것입니다. 위의 방법보다 더 나은 방법이 있습니까?

편집 : 누구나 잘 확장되는 행에 대해 사람이 읽을 수있는 식별자를 생성하는 간단한 샘플 / 알고리즘이 있습니까?


1
이것은 주관적이므로 커뮤니티 위키 여야합니다
John Sheehan

2
"기본 키를 구성하는 열이 3 개 이상 있어야합니다"? 이것은 무엇을 의미 하는가? 추가 정의를 제공 할 수 있습니까? 아니면 이것이 # 3의 일부입니까?
S.Lott

@ S.Lott PK(NEWID(),NEWID(),NEWID());-)

@pst : 왜 이것이 요구 사항입니까? PK에 3 개의 열이 있어야하는 이유는 무엇입니까? 왜 하나 또는 네 개입니까?
S.Lott

3 개의 열 PK가 다음과 같이 보일 수 있습니다. LocalID (Auto increment int), GlobalID (GUID), ForeignId (RolesType과 같은 외래 키) 등. LocalID + ForiegnId는 복합 키 조합 일 수 있습니다. Guid는 다른 웹 사이트 / 서비스에 사용됩니다. 개인적으로 저는 이것을하지 않고 Guid + ForiegnId를 사용합니다.
Jerad

답변:


77

가끔 연결되는 앱을 사용하여 데이터베이스간에 동기화를 수행하려는 경우 기본 키에 GUID를 사용해야합니다. 디버깅에는 일종의 고통이므로 그 경우를 제외하고는 자동 증가를 사용하는 int를 고수하는 경향이 있습니다.

Autoincrement int는 기본값 이어야하며 사용 하지 않는 것이 정당해야합니다.


3
GUID는 필요하지 않습니다. 단계를 10 또는 20으로 변경하거나 나중에 동기화해야 할 많은 서버로 변경하십시오.
Robert C. Barth

44
최소한 90 %의 경우 GUID가 필요하지 않으며 공간이 낭비됩니다.
Jonathan Leffler

8
GUID가 과잉이라고 진지하게 생각합니다. 아직까지는 GUID를 기본 키로 사용할 필요가 없었습니다.
Cyril Gupta

7
또는 공간을 낭비하고 GUID와 충돌 할 위험이있는 대신 원본 기본 키와 작은 식별자의 복합 키를 만드십시오. 여기서 작은 식별자는 각 동기화 소스마다 다릅니다.
L̳o̳̳n̳̳g̳̳p̳o̳̳k̳̳e̳̳

5
ISO 국가 또는 언어 코드와 같은 공용 식별자를 사용할 수있는 경우에도 모든 작업에 GUID를 사용하기 위해 일한 상점입니다. 부울 또는 CHAR(1)충분 했을 때도 sex. 말할 필요도없이 함께 일하는 것은 악몽이었습니다.
Lumi

56

나는 정말로 근본적인 요점 (내가 생각하는 것)을 지적하는 대답을 보지 못했다. 데이터베이스에서 모델링 됨). 이 관찰은 기본 키에 대해 좋은 것과 나쁜 선택을 설정하는 데 도움이됩니다.

예를 들어, (미국) 주 이름 및 코드 테이블에서 이름 또는 코드는 기본 키가 될 수 있습니다. 두 개의 서로 다른 후보 키를 구성하고 그중 하나 (일반적으로 더 짧은 코드)가 기본 키. 기능적 종속성 (및 조인 종속성 (1NF ~ 5NF)의 이론에서 기본 키가 아니라 중요한 후보 키입니다.

반례의 경우 사람 이름은 일반적으로 기본 키에 대해 잘못된 선택을합니다. "John Smith"라는 이름이나 다른 유사한 이름을 사용하는 사람들이 많이 있습니다. 중간 이름을 고려하더라도 (기억하십시오 : 모든 사람이 이름을 가지고있는 것은 아닙니다. 예를 들어, 저는 그렇지 않습니다) 중복의 범위가 충분합니다. 결과적으로 사람들은 이름을 기본 키로 사용하지 않습니다. 사회 보장 번호 (SSN) 또는 직원 번호와 같은 인공 키를 만들어 개인을 지정하는 데 사용합니다.

이상적인 기본 키는 짧고 독특하고 기억에 남는 자연스러운 것입니다. 이러한 특성 중 고유성은 필수입니다. 나머지는 실제 데이터의 제약 조건에 따라 유연해야합니다.

따라서 주어진 테이블의 기본 키를 결정할 때 해당 테이블이 무엇을 나타내는 지 살펴 봐야합니다. 테이블의 어떤 열 값 세트가 테이블의 각 행을 고유하게 식별합니까? 이것이 후보 키입니다. 이제 각 후보 키가 4 개 또는 5 개의 열로 구성되어있는 경우 이러한 열이 너무 어색해서 좋은 기본 키를 만들 수 없다고 결정할 수 있습니다 (주로 부족한 이유 때문). 이러한 상황에서는 인위적으로 생성 된 번호 인 대리 키를 도입 할 수 있습니다. 매우 자주 (항상 그런 것은 아님) 대리 키에 간단한 32 비트 정수이면 충분합니다. 그런 다음이 대리 키를 기본 키로 지정합니다.

그러나 다른 후보 키 (대리 키도 후보 키일뿐만 아니라 선택한 기본 키인 경우)가 모두 고유 식별자로 유지되는지 확인 해야합니다. 일반적으로 해당 열 집합에 고유 제약 조건을 적용합니다.

때때로 사람들은 행을 고유하게 만드는 것이 무엇인지 식별하기가 어렵지만 그렇게해야 할 일이 있어야합니다. 단순히 정보를 반복한다고해서 더 이상 사실이되는 것은 아니기 때문입니다. 주의하지 않고 동일한 정보를 저장하는 행이 두 개 (또는 그 이상) 인 경우 정보를 업데이트해야하는 경우 한 행만 업데이트 할 위험이 있습니다 (특히 커서를 사용하는 경우). 모든 행이 아니라 행이 동기화되지 않았고 어느 행에 올바른 정보가 있는지 아무도 모릅니다.

이것은 어떤면에서 꽤 강경 한 견해입니다.

GUID가 필요할 때 사용하는 데 특별한 문제는 없지만, 크기 경향이 있고 (16-64 바이트) 너무 자주 사용됩니다. 아주 자주 완벽하게 좋은 4 바이트 값으로 충분합니다. 4 바이트 값으로 충분한 GUID를 사용하면 디스크 공간이 낭비되고 인덱스 페이지 당 값이 적기 때문에 데이터에 대한 인덱스 액세스 속도도 느려집니다. 따라서 인덱스는 더 깊어지고 더 많은 페이지를 읽어야합니다. 정보.


10
미국 주 이름을 가진 샘플과 관련하여 코드가 제어 할 수없는 것이기 때문에 별도의 대리 키를 선호합니다. 어떤 이유로 든 변경해야하는 경우 문제가 발생합니다.
Dirk Vollmar

1
(계속) 예를 들어, 독일은 통일 이후 1990 년대에 4 자리 우편 번호 체계를 5 자리 체계로 대체했습니다.
Dirk Vollmar

@divo : 저는 인공 / 대리 키를 강력하게 옹호하지만 4 자리에서 5 자리로의 우편 번호 변경이 좋은 예라고 생각하지 않습니다. 우편 번호는 일반적으로 키로 사용되지 않습니다. (마지막으로 해당 코드에 대한 정보를 찾기 위해 PostalCode 테이블을 쿼리해야했던 때가 언제입니까? 아니요, 다른 테이블에서 참조되지 않고 주소의 일부로 거의 독점적으로 사용됩니다. 귀하의 제안은 using 주소 자체에 대한 대리 키.)
ErikE 2010

@Emtucifor : 예, 아마도 ZIP은 그다지 실용적인 예는 아니지만, 내 요점은 대리 키의 일부가 제어 할 수없고 어떤 이유로 든 변경되면 문제가 있다는 것입니다. 새로운 사회 보장 번호 체계, 새로운 ISSN 체계를 만드는 사람, 또는 더 현실적으로 합병 후 새 제품 ID 시스템을 만들기로 결정한 회사, 성장을 조정하기 위해 직원에게 새 직원 번호 할당 등을 생각해보십시오. 모두 허구의 예일 뿐이지 만 ZIP을 사용한 이전 예에서 볼 수 있듯이 때로는 잘 구축 된 시스템이 변경 될 수 있습니다.
Dirk Vollmar

2
첫 번째 요점이 맞습니다. 이 제약에 대한 이름이 있습니다. 이를 "엔티티 무결성"이라고합니다. EI는 모든 법인이 고유 한 신원을 갖도록 요구합니다. 기본 키는 자동 번호가 사용되는 경우를 제외하고 종종이 요구 사항을 충족합니다. 자동 번호를 사용하면 자동 번호를 제외하고 동일한 두 행을 얻을 수 있습니다. 이것은 일반적으로 엔티티 무결성을 위반합니다.
Walter Mitty 2011 년

26

사람들이 보편적 인 정답을 추구하기 때문에 이것은 종교적인 문제 일뿐입니다. 귀하의 팀과이 SO 스레드 모두 서로 다른 상황에서 설명하는 모든 솔루션을 사용해야하는 좋은 이유가 있다는 단서가되어야합니다.

  • 서로 게이트 키는 테이블의 다른 속성이나 속성 집합이 행을 고유하게 식별하는 데 적합하지 않을 때 유용합니다.
  • 가능한 경우 테이블을 사람이 더 쉽게 읽을 수 있도록 자연 키를 사용하는 것이 좋습니다. 또한 자연 키를 사용하면 종속 테이블의 외래 키가 대리 ID 대신 실제 값을 포함 할 수 있습니다. 예를 들어 state(CA, TX, NY) 를 저장해야 할 때 char(2)int 대신 자연 키를 사용할 수도 있습니다 .
  • 적절한 경우 복합 기본 키를 사용하십시오. id완벽하게 좋은 복합 키가있을 때 불필요하게 " "대리 키를 추가하지 마십시오 (특히 다 대다 테이블에서 해당됨). 모든 테이블에서 3 열 키에 대한 명령은 절대적으로 말도 안됩니다.
  • GUID는 여러 사이트에서 고유성을 유지해야하는 경우 솔루션입니다. 기본 키의 값이 고유하지만 순서가 없거나 연속적이지 않은 경우에도 유용합니다.
  • INT 대 BIGINT : 테이블 에 기본 키에 대해 64 비트 범위 가 필요한 것은 일반적이지 않지만 64 비트 하드웨어의 가용성이 증가함에 따라 부담이되지 않으며 오버플로가 발생하지 않을 것이라는 더 많은 보증을 제공합니다. INT는 물론 더 작기 때문에 공간이 부족하면 약간의 이점을 줄 수 있습니다.

7
나는 사람이 할 수있는 한 동의하지 않는다. 자연적인 열쇠는 끔찍합니다. 데이터를 변경하려면 어떻게해야합니까? 오, 할 수 없습니다. 복합 자연 키에 조인을 작성하는 것은 고통입니다. 복합 키를 모든 관련 테이블에 전달하는 것은 낭비입니다.
Robert C. Barth

2
@Robert : "ON UPDATE CASCADE"에 대해 읽어보십시오. 그러나 나는 당신이 말하는 것을 알고 있으며, 속성은 변경 될 수 있고 고유하지 않기 때문에 대부분의 경우 대리 키를 사용하는 것이 가장 좋습니다.
Bill Karwin

2
기본 키는 변경 불가능해야합니다. 캐스케이드 업데이트는이 경우 잘못된 설계 결정에 대한 추악한 해킹 일뿐입니다. 자연 키는 절대 선호되지 않습니다. 복합 키와 동일하며 전염병처럼 퍼졌습니다. 3 개월 이상의 데이터베이스 개발 경험이있는 사람이라면 누구나 이것을 알 것입니다.
FDCastel

7
@FD : 저는 당신의 명백한 진술에 동의하지 않습니다. 그리고 저는 1992 년부터 SQL 데이터베이스로 개발해 왔습니다. 그러나 확실히 대리 키가 불변으로 남아있을 수 있다는 것은 사실입니다.
Bill Karwin

20

나는 이런 종류의 정보에 대한 소스로 데이터베이스 프로그래머 블로그 를 좋아 합니다.

기본 키에 대한 열 3 개? 열에는 비즈니스 규칙이 요구하는대로 적절한 고유 제약 조건이 있어야하지만 여전히 별도의 대리 키가 있습니다. 복합 키는 비즈니스 로직이 키에 입력됨을 의미합니다. 논리가 변경되면 전체 스키마가 망가집니다.


2
그들은 링크를 변경했습니다. 여기에 업데이트 된 북마크가 있습니다. database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

이와 같은 프로젝트를 상속 받았습니다. 그리고 그들이 원했던 첫 번째 일은 스키마를 폭파 시켰습니다. 대리 키 FTW. DB FTL의 비즈니스 로직.
Jason


11

약간 주제에서 벗어 났지만, 차임에 차를 몰고 가야한다고 느낍니다 ...

기본 키가 GUID 인 경우 클러스터형 인덱스로 만들지 마십시오 . GUID는 비 순차적이므로 거의 모든 삽입 중에 데이터가 디스크에 다시 정렬됩니다. (네.) GUID를 기본 키로 사용하는 경우 클러스터되지 않은 인덱스 여야합니다.


1
아주 좋은 점- 기본 키 의 논리적 개념 (특히 복제가 관련된 경우 GUID를 사용하는 것이 유효 할 수 있음)과 클러스터링 키 의 물리적 개념 을 구별 해야합니다.이 개념은 GUID 가 아니 어야 합니다. 과도한 인덱스 조각화로 이어집니다
marc_s

3
사실 이것은 정확하지 않습니다. 데이터는 순서대로 삽입되므로 GUID의 임의 특성이 테이블 전체에 위치 할 수 있습니다. 여지가없는 경우 페이지 분할이 발생하지만 "삽입 할 때마다 디스크에서 다시 정렬"하지 않을 수도 있습니다.
Ralph Shillington

@Ralph, 당신 말이 맞습니다. 모든 삽입물은 아니지만 20 배의 성능 저하를 유발하기에 충분합니다. sql-server-performance.com/articles/per/…
Portman

SQL Server 함수 newsequentialid ()는 GUID의 인덱스 조각화 문제를 해결합니다 (전역 고유성이 절대적으로 필요하지 않은 경우 24 바이트는 여전히 약간 과도합니다). msdn.microsoft.com/en-us/library/ms189786.aspx를 참조하십시오.
ErikE 2010

10

나는 항상 대리 키를 가지고 간다. 서로 게이트 키 (일반적으로 ID 열, 자동 증가 또는 GUID)는 데이터 자체에 키가없는 키입니다. 반면에 자연 키는 자체적으로 행을 고유하게 식별하는 키입니다. 내가 인생에서 말할 수있는 한, 실제 자연적인 열쇠 는 거의 없습니다 . 미국의 사회 보장 번호 (SSN) 같은 것조차 자연스러운 열쇠는 아닙니다. 복합 기본 키는 발생하기를 기다리는 재난입니다. 해당 데이터를 편집 할 수는 없지만 (복합 여부에 관계없이 모든 자연 키의 주요 단점), 더 나쁜 것은 복합 키를 사용하는 경우 이제 해당 키 데이터를 모든 관련 테이블에 영속화해야한다는 것입니다. 엄청난 낭비입니다.

이제 대리 키를 선택하기 위해 ID 열을 사용합니다 (대부분 MS SQL Server에서 작업 함). GUID의 너무 큰 마이크로 소프트는 권고 에 대해 PK로를 사용하여. 서버가 여러 개인 경우 10 또는 20을 늘리거나 동기화 / 확장해야하는 최대 서버 수를 늘리고 각 후속 서버의 각 테이블에 대한 시드를 추가하기 만하면됩니다. , 데이터 충돌이 발생하지 않습니다.

물론 증분 때문에 식별 열을 BigInt (또는 long [64 비트]라고 함)로 만듭니다.

약간의 수학을 수행하면 100 씩 증가하더라도 테이블에 92,233,720,368,547,758 (> 92 조) 행이있을 수 있습니다.


9

"Primary"Key라는 문구에서 "Primary"라는 단어를 사용하는 것은 실제 의미에서 오해의 소지가 있다고 생각합니다.

먼저 "키"가 테이블 내에서 고유해야하는 속성 또는 속성 집합이라는 정의를 사용합니다.

그런 다음 키를 갖는 것은 종종 상호 일관성이없는 여러 가지 목적으로 사용됩니다.

  1. 이 상위 테이블과 관계가있는 하위 테이블의 하나 이상의 레코드에 대한 조인 조건으로 사용합니다. (해당 하위 테이블에서 외래 키를 명시 적 또는 암시 적으로 정의)
  2. (관련) 하위 레코드에 상위 탭에 상위 레코드가 있어야 함 e (하위 테이블 FK는 상위 테이블의 키로 존재해야 함)
  3. 테이블에서 특정 레코드 / 행을 빠르게 찾아야하는 쿼리의 성능을 향상시킵니다.

  4. 동일한 논리 엔티티를 나타내는 중복 행이 테이블에 삽입되지 않도록 방지하여 데이터 일관성을 보장합니다. (이것은 종종 "내츄럴"키라고 불리며 상대적으로 변하지 않는 테이블 (엔티티) 속성으로 구성되어야합니다.)

분명히, GUID 또는 자동 생성 된 정수와 같은 의미없는 완전하고 자연스럽지 않은 키는 # 4를 완전히 충족 할 수 없습니다.

그러나 종종 많은 (대부분의) 테이블에서 # 4를 제공 할 수있는 완전히 자연스러운 키는 종종 여러 속성으로 구성되고 지나치게 넓거나 너무 넓어서 # 1, # 2 또는 # 3 목적으로 사용하면 허용되지 않습니다. 성능 결과

대답은 간단합니다. 둘 다 사용하십시오. 다른 하위 테이블의 모든 조인 및 FK에 대해 간단한 자동 생성 통합 키를 사용하지만 데이터 일관성이 필요한 모든 테이블 (매우 적은 테이블이 필요하지 않음)에 일관성없는 데이터 행 삽입을 방지하는 대체 고유 고유 키가 있는지 확인합니다. .. 게다가, 만약 당신이 항상 둘 다 가지고 있다면, 당신이 그것을 위해 그것을 사용하지 않기 때문에, 자연 키 사용에 대한 모든 반대 (바꾸면 어떨까요? FK로 참조되는 모든 위치를 변경해야합니다)는 논쟁이됩니다. .. 일관성없는 중복 데이터를 방지하기 위해 PK 인 하나의 테이블에서만 사용하고 있습니다.

GUID에 관해서는 인덱스에서 guid를 사용하면 인덱스 조각화가 발생할 수 있으므로 매우주의해야합니다. 이를 생성하는 데 사용되는 가장 일반적인 알고리즘은 guid의 "무작위"부분을 가장 중요한 비트 위치에 배치합니다. 이렇게하면 새 행이 추가 될 때 일반 인덱스 조각 모음 / 재 인덱싱에 대한 요구 사항이 증가합니다.


SQL Server 함수 newsequentialid ()는 GUID의 인덱스 조각화 문제를 해결합니다 (전역 고유성이 절대적으로 필요하지 않은 경우 24 바이트는 여전히 약간 과도합니다). msdn.microsoft.com/en-us/library/ms189786.aspx를 참조하십시오.
ErikE 2010

죄송합니다. 16 바이트를 말하려고했습니다.
ErikE

8

절대하지 말아야 할 한 가지는 스마트 키를 사용하는 것입니다. 그것은 레코드에 대한 정보가 키 자체에 코딩되는 키이며 결국에는 당신을 물릴 것입니다.

저는 한 곳에서 일했는데, 기본 키는 문자와 숫자의 조합 인 계정 ID였습니다. 구체적인 사항은 기억 나지 않지만, 예를 들어 특정 유형의 계정은 600 범위에 있고 다른 유형의 계정은 400으로 시작됩니다. 고객이 두 가지를 모두 요청하기 전까지는 훌륭했습니다. 일의 유형. 또는 그들이 한 일의 유형을 변경했습니다.

다른 곳에서는 트리의 위치를 ​​레코드의 기본 키로 사용했습니다. 따라서 다음과 같은 레코드가 있습니다.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

물론 고객이 가장 먼저 원했던 것은 트리에서 항목을 이동하는 방법이었습니다. 그 전에 전체 소프트웨어 세트가 죽었습니다.

제발, 제발, 제발, 제가 유지해야 할 코드를 작성하고 있다면 스마트 키를 사용하지 마세요!


전적으로 동의합니다. Smartkeys = 바보.
Robert C. Barth

2
그렇다고 자연 키가 멍청하다는 의미는 아닙니다. 하지만 좋은 지적입니다.

4

나는 기본 키로서 자동 증가의 팬입니다. 나는 이것이 cop-out이라는 것을 내 마음 깊이 알고 있지만 데이터가 추가되었을 때 (ORDER BY ID DESC, f'r instance) 데이터를 정렬하기가 매우 쉽습니다.

3 개의 열은 인간적으로 파싱하기에는 매우 가혹하게 들립니다.

이것이 바로 트레이드 오프입니다. 즉,이 표를 사람이 질문 할 수 있도록 여기에서 바로 이해할 수있게 만드는 것과 비교하여 (저장 프로 시저 또는 프로그래밍 방식 인터페이스와 비교하여) 관계형 기능이 얼마나 필요한지 확인하십시오.

자동 증가는 우리 인간을위한 것입니다. :-(


4

일반적으로 상황에 따라 다릅니다.

개인적으로 저는 autoincrement int를 좋아합니다.

하지만 제가 말씀 드릴 수있는 한 가지는 다른 소스의 데이터를 키로 신뢰하지 않는다는 것입니다. 맹세 컨데 내가 할 때마다 날 물기 위해 돌아온다. 글쎄, 다시는!


3

기본 키를 구성하는 열이 3 개 이상 있어야합니다.

나는 이것을 이해하지 못한다.

"이름 및 생년월일"과 같은 "자연스러운 키"에 대해 이야기하고 있습니까? 자연 키가있는 경우 이상적 일 수 있지만 자연 키에 대한 대부분의 후보는 고유하지 않거나 (같은 이름을 가진 여러 사람) 일정하지 않습니다 (누군가 이름을 변경할 수 있음).

자동 증가가 충분한 기본 키인 Int / BigInt.

나는 Guid를 선호합니다. 자동 증가의 잠재적 인 문제는 값 (예 : "주문 ID")이 데이터베이스 인스턴스 (예 : "판매 데이터베이스")에 의해 할당된다는 것입니다. 하나 이상의 데이터베이스 인스턴스에서 생성 된 데이터를 병합해야하는 경우가 있습니다 (예 : 각각 자체 데이터베이스가있는 여러 영업소에서).


기본 키는 고유해야하지만 상수 일 필요는 없습니다. 따라서 "ON UPDATE CASCADE"로 외래 키를 선언합니다. 그러나 기본 키가 일정하다고 가정하면 많은 응용 프로그램을 단순화하는 데 도움이됩니다. 이것은 서로 게이트 키의 이점 중 하나입니다.
Bill Karwin

3

RE GUID

이것이 정말 정말 정말 정말 큰 데이터베이스 가 될지 , 많은 부하와 빠른 액세스 가 될지 조심하세요 .

저의 마지막 직장에서 1 억에서 5 억 개의 레코드가있는 데이터베이스가 있었을 때 데이터베이스 직원들은 GUID와 적절한 크기의 십진수에 대해 강력하게 주장했습니다. 그들은 (Oracle 하에서) 문자열 Guid에 대한 내부 저장소의 크기 차이와 십진수 값이 조회에서 매우 눈에 띄는 차이를 만들 것이라고 생각했습니다. (더 큰 키 = 횡단 할 더 깊은 나무)

또한 GUID의 임의 특성은 인덱스 페이지의 채우기 비율을 크게 줄여 주므로 티어링 및 디스크 I / O가 크게 증가합니다.


"채우기 계수를 줄입니다"? 이것이 의미 할 수있는 것이 무엇인지 확실하지 않습니다. Fill-factor는 인덱스가 작성 될 때 인덱스의 리프 수준에서 요청 된 여유 공간의 백분율로 정의되는 원샷 거래입니다. 채우기 비율이 제공 한 여유 공간에 삽입 할 때 리프 수준의 폭에 걸친 임의의 특성 분포에 따른 GUID 값.
Ralph Shillington

1
GUID는 언제부터 문자열입니까? GUID는 적절한 DBMS에 의해 내부적으로 16 바이트로 저장되어야합니다. 16 진수 표현에 32 바이트로 저장하는 것은 비양심적입니다! (또는 대시가있는 36 개 또는 중괄호가있는 38 개)
ErikE 2010

2

자동 증가 열. 내 코드가 SQL Server 또는 Oracle에서 원활하게 작동하도록 만들 수 있습니다. 하나는 ID를 사용하고 다른 하나는 DAL을 통해 시퀀스를 사용합니다. 동의합니다. 복제를 수행하거나 나중에 처리 할 때 데이터를 받기 위해 데이터를 보내는 경우 GUID가 때때로 필요합니다.


2

저는 항상 'id'라는 자동 증가 정수인 대리 키를 사용했습니다. 다른 옵션이 분명한 경우에도 이렇게해야하는 많은 이유를 볼 수 있습니다.

  • 일관성
  • 데이터 독립적 (고유, 형식 변경으로 인해 파괴되지 않음)
  • 사람이 읽을 수있는

... 그리고 다음을 수행하지 않는 합리적인 이유가 없습니다.

  • 조인의 모호함? -별칭 테이블은 더 나은 방법입니다, IMHO
  • 최적의 테이블? -항목 당 1 바이트 제거는 조기 최적화, IMHO
  • 테이블 별 결정? -더 이상 일관성이 없음
  • 확장 문제? -어? 왜?
  • 계층 적 데이터 구조? -그건 완전히 다른 종교 주제 인 비정규 화입니다. 이론상 몇 가지 상황에서 내가 팬이라고 말하면 충분하지만 실제로는 결코 아닙니다. :)

아직 생각 해보지 못하거나 마주 치지 않은 합리적인 이유는 언제나 환영합니다 ...


1

이것은 고전적인 "의존적"입니다. 모든 프로젝트에 대한 정답은 없습니다. 상황에 따라 다른 것을 좋아합니다. ORM을 사용하는지 여부와 지원하는 항목에 따라 다릅니다. 전체 아키텍처 (분산 여부 등)에 따라 다릅니다. 작동 할 것으로 생각되는 것을 선택하고 탭과 공백에 대한 논쟁으로 넘어갑니다.


그는 여전히 그것이 어떻게 의존하는지 알고 싶어합니다. 이것들을 인식해야만 자신의 선택
Nicholas Leonard

1

나는 크기, 연결하는 사람 수, 다중 데이터베이스 서버 상황인지 여부에 따라 옵션 # 1 또는 # 3을 사용하는 경향이 있습니다.

옵션 # 2는 나에게별로 의미가 없습니다. 세 가지 중 하나가 고유 한 레코드를 식별하기에 충분하지 않은 경우 (추가적인 조작을 거치지 않고) 두 개의 레코드가 세 열 모두에 동일한 값으로 표시 될 수 있습니다. 세 가지 조합에 고유성을 적용하려면 인덱스를 추가하기 만하면됩니다.


1

자동 증가 int 또는 GUID 만 사용했습니다. 99 %의 시간 동안 자동 증가 int를 사용했습니다. 데이터베이스에 대해 처음 배웠을 때 사용하도록 배웠고 데이터베이스를 사용하지 않을 이유가 없었습니다 (GUID가 더 나은 이유는 알고 있지만).

가독성에 도움이되므로 자동 증가 정수를 좋아합니다. 예를 들어 "take a look at record 129383"이라고 말하면 누군가 들어가서 찾기가 매우 쉽습니다. 거의 불가능한 GUID로.


2
왜 그런 말을 해? 많은 사람들이 자동 증가 정수를 사용하는 것 같습니다. 그것이 당신이 필요로하는 것을 잘 작동하고 잘 작동한다면 그것은 그렇게 나쁠 수 없습니다.
dtc

1

기본적인 정의 적 대답을 지나면 좋은 기본 키를 구성하는 것은 주로 종교와 휴게실 논쟁에 남겨집니다. 항상 개별 행에 고유하게 매핑되는 것이 있으면 기본 키로 제대로 작동합니다. 그 이후에는 다른 고려 사항이 있습니다.

  • 기본 키 정의가 지나치게 복잡하지 않습니까? "모범 사례"를 따르기 위해 불필요한 복잡성을 도입하지 않습니까?
  • 데이터베이스가 처리하는 데 더 적은 오버 헤드를 필요로하는 더 나은 가능한 기본 키가 있습니까 (예 : INTEGER 대 VARCHAR 등)?
  • 기본 키의 고유성과 정의 불변성이 변경되지 않을 것이라고 절대적으로 확신합니까?

이 마지막 항목은 주소, 전화 번호, 이름 / 성 등과 같은 항목에 의존하기 때문에 대부분의 사람들이 GUID 또는 자체 증가 정수 열과 같은 것을 사용하도록 유도 할 가능성이 높습니다. 내가 생각할 수있는 유일한 사람들은 사회 보장 번호이지만, 영원히 독특하게 남아있는 사람들에 대해 100 % 확신 할 수도 없습니다.

바라건대 이것은 약간의 명확성을 추가하는 데 도움이되기를 바랍니다.


SSN이 고유하지 않은 몇 가지 역사적 사례가 있습니다.
Bill Karwin

1

내가 기본 키에 접근하는 방식 (그리고 가장 좋다고 생각)은 "기본"접근 방식을 사용하지 않는 것입니다. 즉, 자동 증가하는 정수를 치고 하루를 호출하는 대신 문제를보고 "항상 부적절하고 변경되지 않는 열 또는 열 그룹이 있습니까?"라고 말합니다. 대답이 '예'이면 그 접근 방식을 취합니다.


그것은 당신이 '가능할 때마다 정수 자동 증가를 피하는 것'을 의미합니까? 내 이해는 업계 전문가들은 대규모 데이터베이스에서 최고의 성능이 최소 서명, 색인화 된 증분 단일 열 PK에서 비롯된다고 생각했습니다.
Hardryv

1
저는 항상 전문가들이 작업에 가장 적합한 도구를 사용한다고 생각했습니다
Andrew G. Johnson

1

거의 항상 정수입니다.

그들은 더 작고 / 더 빨리 처리하는 것 외에 다른 좋은 이유가 있습니다. "404040"또는 "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"중 무엇을 적어 두시겠습니까?


후자는 대시가 추가되고 16 진법이 추가 된 정수일 수 있습니다. 그러나 예, 404040은 긴 GUID보다 처리 속도가 빠릅니다. 다시 말하지만, 0은 단일 비트의 데이터가 필요하지 않기 때문에 처리 속도가 훨씬 더 빠릅니다!
strager

1

약간만 관련이 있지만 최근에 작은 분류 테이블 (본질적으로 코드에서 ENUM을 나타내는 테이블)이있을 때 시작한 한 가지는 기본 키를 char (3) 또는 char (4)로 만드는 것입니다. 그런 다음 조회 값을 나타내는 기본 키를 만듭니다.

예를 들어, 내부 판매 에이전트를위한 견적 시스템이 있습니다. 모든 견적 라인 항목에 할당 된 "비용 범주"가 있습니다. 따라서 기본 키가 'MTL', 'SVC', 'TRV', 'TAX'인 'tCostCategories'라는 유형 조회 테이블이 있습니다. 'ODC'. 조회 테이블의 다른 열에는 코드의 일반적인 영어 의미, "재료", "서비스", "여행", "세금", "기타 직접 비용"등과 같은 자세한 내용이 저장됩니다.

이것은 int보다 더 많은 공간을 사용하지 않기 때문에 정말 좋습니다. 그리고 소스 데이터를 볼 때 값이 무엇인지 알기 위해 조회 테이블을 연결할 필요가 없습니다. 예를 들어 따옴표 행은 다음과 같습니다.

1 부품 번호 $ 40 MTL
2 기타 부품 번호 $ 29.99 SVC
3 부품 번호 2 $ 150 TRV

int를 사용하여 카테고리를 표현한 다음 모든 라인에서 1, 2, 3을 연결하는 것이 훨씬 쉽습니다. 바로 앞에 데이터가 있고 성능에 전혀 영향을주지 않는 것 같습니다. 진정으로 테스트했습니다.)

실제 질문에 관한 한 ... 저는 RowGUID uniqueidentifiers를 좋아합니다. 나는 이것에 100 %는 아니지만 어쨌든 모든 행에 내부 RowGuid가있는 것은 아니다 ?? 그렇다면 RowGuid를 사용하면 실제로 int (또는 그 문제에 대한 다른 모든 것)보다 적은 공간을 차지할 것입니다. 제가 아는 것은 GreatPlains에서 M $가 사용하기에 충분하다면 나에게도 충분하다는 것입니다. (내가 엎드려 야하나요 ??)


1

내가 GUID를 사용하는 또 하나의 이유는 계층 적 데이터 구조를 사용한다는 것입니다. 즉, 기본 키가 일치하는 테이블 'Company'와 테이블 'Vendor'가 있습니다. 그러나 또한 Company에서 '상속'하는 'Manufacturer'테이블도 있습니다. 공급 업체 및 제조업체에 공통적 인 필드는 해당 테이블에 나타나지 않고 회사에 나타납니다. 이 설정에서 int를 사용하는 것은 Guids보다 훨씬 고통 스럽습니다. 최소한 ID 기본 키를 사용할 수 없습니다.


1
예, 가능합니다. 하위 유형 테이블이 identity 속성을 갖도록 만들지 않고 대신 상위 유형 테이블 값을 명시 적으로 삽입합니다. stackoverflow.com/questions/2112882/…를
ErikE 2010

1

믿을 수있을 때마다 자연 키를 좋아합니다. 주제 전문가에게 의미있는 키를 사용하기 위해 약간의 성능 가격을 지불 할 의향이 있습니다.

엔터티를 설명하는 테이블의 경우 주제가 사람과 동일한 방식으로 개별 인스턴스를 식별하는 간단한 자연 키가 있어야합니다. 주제에 엔터티 중 하나에 대한 신뢰할 수있는 식별자가없는 경우 대리 키를 사용합니다.

관계를 설명하는 테이블의 경우 각 구성 요소가 관계에 참여하는 엔터티를 참조하므로 엔터티 테이블의 행을 참조하는 복합 키를 사용합니다. 다시 말하지만, 복합 키 사용으로 인한 성능 저하는 일반적으로 최소화됩니다.

다른 사람들이 지적했듯이 "기본 키"라는 용어는 약간 오해의 소지가 있습니다. 관계형 데이터 모델에서 사용되는 용어는 "후보 키"입니다. 단일 테이블에 대해 여러 후보 키가있을 수 있습니다. 논리적으로, 각각은 다른 것만 큼 좋습니다. 그중 하나를 "기본"으로 선택하고 해당 키를 통해 모든 참조를 만드는 것은 단순히 디자이너가 선택할 수있는 선택입니다.


신뢰할 수있는 자연 키 샘플을 설명해주세요.
ErikE 2010

1
"신뢰할 수있는"것은 그 자체로 키의 속성이 아닙니다. 오히려 데이터를 제공하는 사람들의 맥락에서 키와 관련이 있습니다. 실제로 데이터를 관리 할 사람에게 판매 할 앱을 작성하는 경우 클라이언트가 신뢰할 수있는 키를 추측해야합니다. 고객의 다양성을 감안할 때 고객의 일부에 대해 거의 틀림없이 잘못 추측 할 것입니다.
Walter Mitty

위에서 말했듯이, 여기에 우리가 이전에 신뢰했던 키의 예가 있습니다. 코스에 대한 데이터베이스가 있습니다. 여기에는 코스, 예정된 코스 제공, 코스를 가르 칠 자격이있는 강사, 코스 전제 조건, 수업료 등에 관한 교과서 및 기타 코스 자료가 포함되었습니다. 코스 개발이 새로운 코스를 만들었을 때 그들이 한 첫 번째 작업 중 하나는 코스 코드를 할당하는 것이 었습니다. 그들은 코스 코드가 고유하고 코스가 할당 된 후에는 코드를 변경하지 않았는지 확인해야했습니다. 그것은 우리에게 주어진 데이터의 일부였습니다.
Walter Mitty

신뢰할 수있는 자연 키의 또 다른 좋은 예는 VIN (Vehicle Identification Number)입니다. 지난 몇 년 동안 신차로 판매되는 모든 차량에는 VIN이 부착되어 있습니다. 그들은 독특하고 변하지 않는 것으로 신뢰할 수 있습니다.
Walter Mitty

1

Guids.period.

확장해야하거나 기본 키를 다른 방법으로 할당해야하는 경우 해당 사용자가 친구가됩니다. 다른 모든 항목에 대한 색인을 추가 할 수 있습니다.


내 진술을 명확히하기 위해 업데이트하십시오.

저는 다양한 종류의 사이트에서 작업했습니다. 작은 단일 서버 거래에서 여러 DB 및 웹 서버로 지원되는 대형 거래까지. 자동 증분 int를 기본 키로 사용하면 괜찮은 앱이 분명히 있습니다. 그러나 그것들은 내가 일하는 방식에 대한 모델에 맞지 않습니다.

GUID를 사용하면 어디에서나 ID를 생성 할 수 있습니다. 원격 서버, 웹 앱, 데이터베이스 자체 또는 다중 마스터 상황의 여러 데이터베이스 내에서 생성 될 수 있습니다.

반면에 자동 증가 INT는 기본 데이터베이스 내에서만 안전하게 생성 될 수 있습니다. 다시 말하지만,이 하나의 백업 DB 서버에 밀접하게 연결될 애플리케이션이 있고 스케일 아웃이 걱정되는 것이 아니라면 괜찮을 있습니다.

물론 GUID를 사용하면 야간에 다시 인덱싱 프로세스를 수행해야합니다. 그러나 자동 증가 INT 이외의 다른 것을 사용하는 경우 어쨌든 그렇게해야합니다. INT를 기본으로 사용하더라도 조각화를 처리하기 위해 재생성해야하는 다른 인덱스가있을 수 있습니다. 따라서 GUID를 사용한다고해서 다른 문제가 추가되는 것은 아닙니다. 이러한 작업은 상관없이 수행되어야하기 때문입니다.

더 큰 앱을 살펴보면 중요한 것을 알 수 있습니다. 모두 Base64로 인코딩 된 GUID를 키로 사용합니다. 그 이유는 간단합니다. GUID를 사용하면 쉽게 확장 수있는 반면 INT를 확장하려고 할 때 건너 뛸 수있는 많은 문제가있을 수 있습니다.

우리의 최신 앱은 약 한 달 동안 지속되는 무거운 인서트 기간을 거칩니다. 그 후에는 쿼리의 90 % 이상이 모두보고를 위해 선택됩니다. 용량을 늘리기 위해이 큰 삽입 기간 동안 추가 DB 서버를 가져올 수 있습니다. 나중에보고를 위해이를 단일 DB로 쉽게 병합합니다. INT로 그것을 시도하는 것은 절대적인 악몽이 될 것입니다.

솔직히 말해서 데이터베이스를 클러스터링하거나 복제를 설정할 때마다 DB 서버는 어쨌든 테이블에 GUID가 있어야한다고 요구할 것입니다. 따라서 시스템을 확장해야한다고 생각되면 좋은 시스템을 선택하십시오.


인덱스의 채우기 비율을 조사한 적이 있습니까? GUID의 임의의 특성으로 인해 스위스 치즈가 만들어 지므로 효과가 크게 감소합니다.
stephbu

2
"Guids.period": 정말 잘못되었습니다. 적절한 경우 GUID를 사용해야합니다. 다른 주석가가 지적했듯이 프로그래머로서의 삶을 쉽게 만들 수 있지만 DB의 전체 크기와 성능에 영향을 미칩니다.
Mitch Wheat

하루가 끝나면 문제없이 여러 데이터베이스 서버에서 앱을 확장 할 수 있습니다. 하지만 여러분은 작은 사이트에서 일하시는 것 같습니다.
NotMe

3
GUID 는 논리적 기본 키에 적합 수 있지만 절대로 GUID 열을 CLUSTERING 키로 사용하지 마십시오. 인덱스 조각화로 인해 성능 저하로 이어질 것입니다 .....
marc_s

나는 확실히 "Guids.period"를 선포하지 않을 것이다. 이 주제에 대해-사실 '모범 사례'로 가득 찬 업계에서도 기본적으로 (특히 해당 진술과 함께) 불안정한 상황에 처하게합니다. GUID처럼 다루기 힘든 것은 어려운 정당성이 필요하며 JL이 말했듯이 우리 대부분은 이것을 최후의 수단으로 생각할 것이라고 생각합니다. 스레드의 나머지 부분을 읽지 않고 게시 한 것과 같습니다.
Hardryv

0

이것은 당신이 깨달았 든 아니든 복잡한 주제입니다. 이 StackOverflow FAQ의 섹션에 속할 수 있습니다.

여기서 어떤 질문을하면 안 되나요?

주관적이거나 논증 적이거나 긴 토론이 필요한 질문을하지 마십시오. 여기에 답변 할 수있는 질문이 있습니다!

이것은 수년간 논의되어 왔으며 수년간 계속 논의 될 것입니다. 내가 본 합의의 유일한 힌트는 OO 사람 (GUID가 유일한 방법입니다!), 데이터 모델러 (자연 키가 유일한 방법입니다!), 또는 성능 지향 DBA (INT가 유일한 방법입니다!).


나는 토론을 오래 가지 않을 것입니다. 저는 일반적인 합의를보고 싶었습니다.
Perpetualcoder

1
나는 당신이 원하는 어떤 질문이든 물어보세요! 그렇지 않으면이 커뮤니티는 위키피디아처럼 정적이고 과도하게 통제 될 것입니다. 사람들이 무엇을 선택하든 물어 보도록해야 할 때가있는 것 같습니다. 그들을 믿으십시오. 그러면 그들은 스스로를 신뢰하게 될 것입니다!
Nicholas Leonard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.