항상 자동 증분 정수 기본 키를 사용하는 것이 좋습니다?


191

내 데이터베이스에서는 id특정 행에 대해 고유 한 조회를 할 수 있도록 모든 테이블 의 이름으로 자동 증가 정수 기본 키를 사용하는 습관을들이는 경향이 있습니다.

이것은 나쁜 생각으로 간주됩니까? 이런 식으로하는 데 단점이 있습니까? 때로는 고유 식별자가있는 id, profile_id, subscriptions위치 , 테이블 외부 에 대한 링크 등과 같은 여러 인덱스 id가 있습니다 .profile_ididProfile

또는 그러한 필드를 추가하지 않으려는 시나리오가 있습니까?


61
일반 자동 증분 식별자가 문제 가되는 예를 보려면 독일 탱크 문제 를 살펴보십시오 . 물론 이것은 공개적으로 ID를 사용하는 경우에만 중요합니다.
Bergi

24
@ArukaJ 요점은 시스템에 대한 정보가 유출된다는 것입니다. 예를 들어, 데이터베이스에 사용자 작성 게시물이 있고 각 게시물에 순차적 인 ID가 있다고 가정하십시오. 각각 오전 4시 (20), 오전 5시 (25), 오후 8시 (100) 및 오후 9시 (200)의 ID를받는 4 개의 게시물을 작성한다고 가정 해 보겠습니다. ID를 보면 오전 4시와 오전 5시 사이에 5 개의 게시물 만 추가되고 오후 8시와 오후 9시 사이에는 100 개의 게시물이 추가 된 것을 알 수 있습니다. 서비스 거부 공격을위한 시간을 선택하려는 경우 유용한 정보가 될 수 있습니다.
Joshua Taylor

29
"독일어 탱크 문제"에 대해 불평하는 모든 사람에게 .... 누군가가 데이터에 액세스하지 못하도록 막는 유일한 방법이 URL의 핵심 요소 인 경우 GUID 대 Auto INT보다 큰 문제가 있습니다.
Matthew Whited

11
@MatthewWhited URL에서 매개 변수를 바꾸는 것만이 아닙니다. 사이트를 사용하고 시간에 자산 100을 작성하고 시간 t에 자산 120 을 작성한다고 가정하십시오 t + 60. 이러한 ID (100 및 120)를 난독 처리 된 형태로 볼 수 있다면, 현재 존재하는 총 자산 수와 생성 속도와 대략 같은 비율을 알 수 있습니다. 정보 유출입니다. 이것은 순전히 가설이 아닙니다.
Chris Hayes

15
" 항상 좋은 습관입니까? "
brian_o

답변:


137

고유 한 행 식별자를 보장하는 것은 결코 나쁜 생각이 아닙니다. 절대 말하지 말아야 할 것 같지만 압도적 인 대다수의 사람들과 함께 가자 좋은 생각입니다.

이론적 인 잠재적 단점은 유지 관리를위한 추가 색인 및 사용 된 추가 저장 공간을 포함합니다. 그것은 내가 그것을 사용하지 않을 이유가 충분하지 않았습니다.


11
그게 내가하는 일이야. 대부분의 사람들은 'id'또는 'tablename_id'(예 : user_id)를 사용합니다. 인수는 일반적으로 열이 필요한 경우가 아니라 열의 이름을 지정하는 방법입니다.
GrandmasterB

103
개인적으로 나는 테이블 이름이 나머지를 암시해야한다고 생각합니다. TableName.id그 반대 TableName.TableName_id는 무엇 id을 의미합니까? 테이블에 다른 ID 필드가 있으면 다른 테이블을 참조하는 경우 테이블 이름 앞에 접두사를 추가합니다.
AJJ

10
@ArukaJ는 SQLite를 사용한다고 언급했습니다. 그것은 항상 그런 열을 '후드 아래'로 만들기 때문에 실제로는 약간 특별한 경우입니다. 그래서 당신은 당신이 그것을 원하든 원하지 않든 여분의 공간을 사용하지 않습니다. 또한 SQLite의 rowid는 항상 64 비트 정수입니다. 내 이해가 정확하면 자동 증가 행을 정의하면 내부 rowid의 별칭이됩니다. 그래서 당신은 항상 잘했을 것입니다! 참조 sqlite.org/autoinc.html
GrandmasterB

9
내가 생각할 수있는 한 가지 예외는 다른 방법으로 생성 된 고유 식별자가있는 경우입니다.이 경우 기본 키이어야하고 자동 증가 ID는 중복됩니다.
HamHamJ

4
@GrandmasterB : 현재 버전의 SQLite를 사용 하면 최적화로 WITHOUT ROWID테이블을 명시 적으로 만들 수 있습니다 PRIMARY KEY. 그러나 그렇지 않으면 INTEGER PRIMARY KEY열은 rowid의 별칭입니다.
dan04

92

나는 모든 대답에 동의하지 않습니다. 모든 테이블에 자동 증분 필드를 추가하는 것이 좋지 않은 이유는 여러 가지가 있습니다.

명백한 키가없는 테이블이 있으면 자동 증가 필드가 좋은 생각 인 것 같습니다. 결국, 당신은 원하지 않습니다 select * from blog where body = '[10000 character string]'. 당신은 오히려 select * from blog where id = 42. 나는 대부분의 경우에, 당신이 정말로 원하는 것은 유일한 식별자라고 주장합니다. 순차 고유 식별자가 아닙니다. 대신 보편적으로 고유 한 식별자를 사용하고 싶을 것입니다.

대부분의 데이터베이스에는 임의의 고유 식별자 ( uuidmysql, postgres. newid의 mssql) 를 생성하는 기능이 있습니다 . 이를 통해 네트워크 연결없이 언제든지 다른 머신에서 여러 데이터베이스로 데이터를 생성 할 수 있으며 충돌없이 데이터를 병합 할 수 있습니다. 이를 통해 마이크로 서비스와 같은 여러 서버 및 데이터 센터를보다 쉽게 ​​설정할 수 있습니다.

또한 공격자가 액세스해서는 안되는 페이지의 URL을 추측하지 않아도됩니다. 이 있다면 https://example.com/user/1263아마도있을 것입니다 https://example.com/user/1262. 이를 통해 사용자 프로필 페이지에서 보안 취약점을 자동화 할 수 있습니다.

UUID 컬럼이 쓸모 없거나 심지어 유해한 경우도 많습니다. 소셜 네트워크가 있다고 가정 해 봅시다. 이 users테이블과 friends테이블. friends 테이블에는 두 개의 사용자 ID 열과 자동 증가 필드가 있습니다. 의 3친구가 5되고 싶으 므로 3,5데이터베이스에 삽입 하십시오. 데이터베이스는 자동 증가 ID를 추가하고를 저장 1,3,5합니다. 어떻게 든 사용자 3는 "친구 추가"버튼을 다시 클릭합니다. 3,5데이터베이스에 다시 삽입 하면 데이터베이스가 자동 증분 ID를 추가하고을 삽입합니다 2,3,5. 하지만 지금 35두 번 서로 친구가 있습니다! 그것은 공간 낭비이며, 생각해 보면 자동 증가 열도 마찬가지입니다. a그리고 당신이 볼 필요가있는 모든b두 친구가있는 행에 대해 친구를 선택해야합니다. 이들은 고유 한 행 식별자입니다. (당신은 아마 확인하는 몇 가지 논리를 작성하고 싶은 것 3,5하고 5,3중복 제거됩니다.)

url-shortener를 만들 때와 같이 순차 ID가 유용 할 수있는 경우가 여전히 있지만 대부분 URL url shortener를 사용하면 임의로 생성 된 고유 ID가 대신 실제로 사용하려는 것입니다.

TL; DR : 각 행을 식별하는 고유 한 방법이없는 경우 자동 증가 대신 UUID를 사용하십시오.


26
UUID의 문제점은 대부분의 테이블에 대해 너무 많은 공간을 차지한다는 것입니다. 각 테이블에 올바른 고유 식별자를 사용하십시오.
Stephen

49
고유성에 대한 전체 단락은 무례합니다. 기본 키를 사용하거나 사용하지 않고 고유성을 적용 할 수 있습니다. 게다가 UUID는 이론 상으로는 더 좋지만 DBA 작업을 디버깅 / 수행하거나 "공격에 저항하지 않는"작업을 수행 할 때는 사용하기가 끔찍합니다.

11
UUID가 더 좋은 또 다른 시나리오 : dem 등원 (Idempotent) PUT 조작을 구현하여 중복 행을 도입하지 않고 요청을 안전하게 재 시도 할 수 있습니다.
yurez

21
"URL 추측"지점에서 고유 한 ID (순차적 또는 다른 방식)를 가졌다 고해서 해당 ID가 애플리케이션 사용자에게 노출되는 것은 아닙니다.
Dave Sherohman

7
순전히 데이터베이스 관점에서 볼 때이 답변은 완전히 잘못되었습니다. 자동 증가 정수 대신 UUID를 사용하면 인덱스가 너무 빨리 증가하여 성능 및 메모리 소비에 악영향을 미칩니다. 웹 서비스 또는 웹 앱의 관점에서 이야기하는 경우 데이터베이스와 프론트 엔드 사이에 계층이 있어야합니다. 다른 것은 나쁜 디자인입니다. 데이터를 기본 키로 사용하는 것이 훨씬 더 나쁩니다. 기본 키는 다른 곳에서는 데이터 계층에서만 사용해야합니다.
Drunken Code Monkey

60

자동 키는 대부분 장점이 있습니다.

그러나 몇 가지 가능한 단점은 다음과 같습니다.

  • 비즈니스 키가있는 경우 비즈니스 규칙을 시행하려면 해당 열에 고유 인덱스도 추가해야합니다.
  • 두 데이터베이스간에 데이터를 전송할 때, 특히 데이터가 둘 이상의 테이블 (예 : 마스터 / 세부 정보)에있는 경우 데이터베이스간에 시퀀스가 ​​동기화되지 않기 때문에 간단하지 않으며 먼저 데이터를 사용하여 동등성 테이블을 작성해야합니다. 원본 데이터베이스의 어떤 ID가 대상 데이터베이스의 어떤 ID와 일치하는지 알기위한 비즈니스 키. 그러나 격리 된 테이블에서 데이터를 전송할 때 문제가되지는 않습니다.
  • 많은 기업에 임시 그래픽, 포인트 앤 클릭, 드래그 앤 드롭보고 도구가 있습니다. 자동 증분 ID는 의미가 없으므로이 유형의 사용자는 "앱"외부의 데이터를 이해하기 어렵습니다.
  • 실수로 비즈니스 키를 수정하면 더 이상 사람이 식별 할 수있는 것이 없기 때문에 해당 행을 복구하지 못할 가능성이 있습니다. 이로 인해 BitCoin 플랫폼에서 한 번 오류가 발생했습니다 .
  • PK를 단순히 두 개의 외부 ID로 구성해야하는 일부 디자이너는 두 테이블 사이의 조인 테이블에 ID를 추가합니다. 분명히 조인 테이블이 세 개 이상의 테이블 사이에 있으면 자동 증분 ID가 의미가 있지만 비즈니스 규칙을 적용하기 위해 FK 조합에 적용 할 때 고유 키를 추가해야합니다.

서로 게이트 키의 단점에 대한 Wikipedia 기사 섹션이 있습니다.


13
서로 게이트 키의 mt.gox 결함을 비난하는 것은 다소 모호한 것 같습니다. 문제는 복합 키의 모든 필드를 포함 하고 심지어 변경 가능하거나 가변적 인 필드 까지 포함했다는 것 입니다.
코드 InChaos

6
자동 증분 키를 사용할 때의 "사회적"단점은 때때로 "비즈니스"는 틈이 없어야하며 삽입 실패 (트랜잭션 롤백)가 발생할 때 누락 된 행에 어떤 일이 발생했는지 알아야한다는 가정입니다.
Rick Ryker

4
또 다른 단점은 시스템이 너무 커져 데이터베이스를 분할해야하는 경우 더 이상 자동 증가를 사용하여 전역 적으로 고유 한 키를 생성 할 수 없다는 것입니다. 그 시점에 도달하면 해당 가정에 의존하는 많은 코드가있을 수 있습니다. 데이터베이스가 샤딩 된 경우 계속 작동하는 고유 식별자를 생성하는 다른 방법이 있습니다.
kasperd

1
@Voo 선택한 데이터베이스가이를 지원한다는 보장은 없습니다. 또한 데이터베이스 자체보다 높은 계층을 구현하려고하면 SQL이 제공하는 보장 중 일부를 잃게됩니다. 마지막으로 중앙 집중식 ID 할당은 분산 시스템을 사용하는 경우 대기 시간을 증가시킵니다.
kasperd

1
@Voo 물론 시스템의 규모에 관계없이 자동 증가 ID의 특성에 대해 너무 많은 가정을해서는 안됩니다. 데이터베이스가 하나 뿐인 경우에는 순서대로 할당되지만 순서대로 커밋된다는 보장은 없습니다. 모든 트랜잭션이 커밋되지 않기 때문에 시퀀스에 차이가있을 수 있습니다.
kasperd

20

반대로, 아니요, 항상 숫자 AutoInc PK를 가질 필요는 없습니다.

데이터를주의 깊게 분석하면 데이터에서 자연 키를 식별하는 경우가 많습니다. 데이터가 비즈니스에 본질적인 의미를 갖는 경우가 종종 있습니다. 때때로 PK는 비즈니스 사용자가 시스템의 속성을 설명하기 위해 제 2 언어로 사용하는 고대 시스템의 인공물입니다. 차량 관리 시스템에서 차량 VIN 번호가 차량 관리 시스템의 "차량"테이블의 기본 키로 사용되는 것을 보았습니다.

그러나 고유 식별자가 이미있는 경우이를 사용하십시오. 두 번째 의미없는 기본 키를 만들지 마십시오. 낭비이며 오류가 발생할 수 있습니다.

경우에 따라 AutoInc PK를 사용하여 고객에게 의미있는 가치 (예 : 정책 번호)를 생성 할 수 있습니다. 시작 가치를 현명한 것으로 설정하고 선행 제로 등에 관한 비즈니스 규칙 적용

비교적 정적 인 값이 적은 경우 시스템 사용자에게 적합한 값을 사용하십시오. L, C, H를 사용할 수있을 때 왜 1,2,3을 사용합니까? L, H 및 C는 보험 "정책 유형"컨텍스트에서 생명, 자동차 및 가정을 나타내거나 VIN 예제로 돌아 가면 "TO "도요타에게? 모든 Toyata 차량에는 "TO"로 시작하는 VIN이 있습니다. 사용자가 기억해야 할 것이 적고 프로그래밍 및 사용자 오류가 발생할 가능성이 적으며 관리 보고서에 대한 자세한 설명을 위해 유용한 대리자 일 수도 있습니다. 작성하고 더 빨리 생성 할 수 있습니다.

이것의 추가 개발은 아마도 "너무 먼 다리"일 것입니다. 나는 일반적으로 그것을 추천하지는 않지만 완전성을 위해 그것을 포함하고 있으며 그것을 잘 사용할 수 있습니다. 즉, 설명을 기본 키로 사용하십시오. 빠르게 변화하는 데이터의 경우 이것은 혐오입니다. 내용은 매우 에보고되는 정적 데이터 의 모든 시간 , 아마. 그것을 언급하기 때문에 가능성이 있습니다.

저는 AutoInc PK를 사용하고 단지 뇌에 관여하고 더 나은 대안을 먼저 찾습니다. 데이터베이스 설계 기술은 빠르게 쿼리 할 수있는 의미있는 것을 만들고 있습니다. 조인이 너무 많으면 방해가됩니다.

편집 자동 생성 된 PK가 필요하지 않은 또 하나의 중요한 경우는 다른 두 테이블의 교집합을 나타내는 테이블의 경우입니다. 자동차 비유를 고수하기 위해 자동차에는 0..n 액세서리가 있으며 각 액세서리는 많은 자동차에서 찾을 수 있습니다. 이를 나타 내기 위해 자동차 및 액세서리의 PK 및 링크 날짜 등에 대한 기타 관련 정보를 포함하는 Car_Accessory 테이블을 작성합니다.

당신이 (보통) 필요하지 않은 것은이 테이블에있는 AutoInc PK입니다. "자동차에있는 액세서리가 무엇인지 알려주십시오"또는 액세서리 "자동차가이 액세서리를 가지고있는 것을 말해주세요"를 통해서만 액세스 할 수 있습니다


4
> 모든 Toyata 차량에는 "TO"로 시작하는 VIN이 있습니다. 그건 사실이 아닙니다. 일본에서 만든 경우 "JT"로 시작합니다. 미국산 도요타는 완전히 다른 VIN을 가지고 있습니다. en.wikibooks.org/wiki/…
Monty Harder

17
Don't create a second, meaningless primary key; it's wasteful and may cause errors.그러나 레코드의 고유성을 설정하는 방법이 6 개의 열 조합이면 6 개 모두에서 조인하면 항상 오류가 발생하기 쉽습니다. 데이터에는 자연스럽게 PK가 있지만 id열과 6 개의 열에 대한 고유 한 제약 조건을 사용하는 것이 좋습니다 .
Brad

14
나는 이러한 제안 중 일부가 나에게 조금 멀다는 것을 인정한다. 그렇습니다. 실용적이기는하지만 도메인의 일부 속성이 며칠 동안 고유하게 유지 될 것이라는 first 아들의 삶을 얼마나 자주 맹세 했는지는 알 수 없습니다 . 글쎄, 그것은 일반적으로 첫 복제본이 나타 났을 때 라이브 후 두 번째 주까지 잘 작동했습니다. ;) "설명"을 PK로 사용하는 것은 멀리 있습니다.
AnoE

2
@Monty, 내 나쁜, 네 말이 맞아. 오류 메모리, 차량 관리 시스템을 설계 한 지 20 년이 지났습니다. VIN은 기본 키가 아니 었습니다. :) 내가 잊어 버린 AutoInc Asset_ID IIRC를 사용했습니다. 자동차와 액세서리 (예 : 선 루프)를 연결하는 다 대다 관계에 대한 링커 인 테이블 많은 자동차에는 많은 액세서리가 있으므로 Car_ID 및 Accessory_ID를 포함하지만 "Car_Accesory_ID"는 반드시 필요하지 않은 "Car_Accessory"테이블이 필요합니다. AutoInc PK.
mcottle

7
TRULY 불변의 "자연 키"가 몇 개인 지 정말 놀랍습니다. SSN? 아니, 그들은 바꿀 수 있습니다. 드물지만 일어날 수 있습니다. 아이디? 아니. 결국 누군가는 유효한 사업상의 이유를 갖게 될 것입니다. VIN은 종종 교과서의 예이지만 다른 것은 많지 않습니다. 거리 이름 변경에 따라 집 주소도 변경 될 수 있습니다.
Erik Funkenbusch

12

많은 테이블에 이미 고유 한 고유 ID가 있습니다. 이 테이블에 다른 고유 ID 열 (자동 증가 또는 기타)을 추가하지 마십시오. 대신 고유 한 고유 ID를 사용하십시오. 다른 고유 ID를 추가하면 본질적으로 데이터에 중복 (중복 또는 종속성)이 있습니다. 이것은 정규화 원칙에 위배됩니다. 하나의 고유 ID는 정확성을 위해 다른 ID에 의존합니다. 이것은 그들이에서 동기화 완벽하게 유지해야 함을 의미 모든 시간모든 시스템 이 행을 관리합니다. 데이터 무결성의 또 다른 취약성으로 인해 실제로 장기간 관리하고 유효성을 검사하지 않아도됩니다.

요즘 대부분의 테이블에는 추가로 고유 한 id 열이주는 성능 향상이 필요하지 않습니다 (때로는 성능이 저하 될 수도 있음). IT의 일반적인 원칙으로 전염병 과 같은 중복성을 피하십시오 ! 그것이 당신에게 제안되는 모든 곳에서 그것을 저항하십시오. 아타 테마입니다. 그리고 인용문에 유의하십시오. 모든 것이 가능한 한 단순해야하지만 더 단순해서는 안됩니다. 자연스럽지 않은 것처럼 보이지만 두 가지 고유 한 ID로 충분하지 않습니다.


3
절대 "절대"ID가 절대 변경되지 않는다고 보장되면 기본 키로 만 사용해서는 안됩니까? 예를 들어, 운전 면허 번호를 기본 키로 사용하면 안됩니다. 사람이 새 운전 면허를 받으면 해당 테이블뿐만 아니라이를 참조하는 외래 키가있는 테이블도 업데이트해야하기 때문입니다!
ekolis

1
운전 면허 번호가 고유 한 고유 ID가 아닌 몇 가지 이유가 있습니다. 먼저 그들 중 일부는 생년월일 및 이름과 같은 다른 데이터에서 파생됩니다. 주마다 고유성을 보장하지는 않습니다. 그리고 예를 들어, 사람이 같은 번호로 연장 된 라이센스를 재발급했을 때 유효 기간이 연장 된 경우 어떻게됩니까? 동일한 번호의 다른 라이센스가 있습니다. 자연 ID는 여전히 기본 키의 기본 속성을 충족해야합니다. 운전 면허증 번호 (적어도 미국에서는)에는 이와 관련하여 몇 가지 단점이 있습니다.
브래드 토마스

1
좋아, 나는 자연 ID의 정의를 잘못 이해했다고 생각한다. 나는 그것이 불변이라고 보장되는지 여부에 관계없이 비즈니스 규칙에 의해 정의 된 ID 일뿐이라고 생각했습니다.
ekolis

10

더 큰 시스템에서 ID는 일관성 향상 요소이며 거의 모든 곳에서 사용하십시오 . 이와 관련하여 개별 기본 키는 권장되지 않으며 결론적으로 비쌉니다 (이유를 읽으십시오).

모든 규칙에는 예외가 있으므로 내보내기 / 가져 오기에 사용되는 스테이징 테이블 및 유사한 단방향 테이블 또는 임시 테이블에 정수 자동 증가 ID가 필요하지 않을 수 있습니다. 분산 시스템에서는 ID 대신 GUID를 선호합니다.

여기에 많은 답변이 기존 고유 키를 가져와야한다고 제안합니다. 150 자라도 가능합니까? 나는 그렇게 생각하지 않습니다.

이제 내 요점은 다음과 같습니다.

자동 증가 정수 ID의 반대자는 최대 20 개의 테이블이있는 작은 데이터베이스에 대해 말하고 있습니다. 거기에서 그들은 각 테이블에 개별적으로 접근 할 수 있습니다.

그러나 400 이상의 테이블이있는 ERP를 가지고 있으면 정수 자동 증가 ID가 어디서나 (위에 언급 된 경우 제외) 갖는 것이 좋습니다. 다른 고유 필드가 존재하고 고유성을 위해 확보 된 경우에도 의존하지 않습니다.

  • 보편적 인 시간 절약, 노력 절약, 기억하기 쉬운 컨벤션의 혜택을 누릴 수 있습니다.
  • 대부분의 경우 JOIN키가 무엇인지 확인할 필요없이 테이블을 만듭니다.
  • 정수 자동 증가 열로 작업하는 범용 코드 루틴을 가질 수 있습니다.
  • 기존 테이블의 ID를 참조하기 만하면 예상치 못한 새로운 테이블 또는 사용자 플러그인으로 시스템을 확장 할 수 있습니다. 그들은 처음부터 이미 거기에 있으며 추가 비용이 들지 않습니다.

더 큰 시스템에서는 개별 기본 키의 작은 이점을 무시하고 대부분의 경우 정수 자동 증가 ID를 지속적으로 사용하는 것이 좋습니다. 기존의 고유 필드를 기본 키로 사용하면 레코드 당 일부 바이트를 절약 할 수 있지만 오늘날 데이터베이스 엔진 에서는 추가 스토리지 또는 인덱싱 시간이 문제되지 않습니다 . 실제로 개발자 / 유지 업체의 낭비 된 시간에 훨씬 더 많은 돈과 자원을 잃고 있습니다. 오늘날의 소프트웨어는 프로그래머의 시간과 노력에 맞게 최적화되어야합니다. 일관된 ID로 접근하는 것이 훨씬 더 좋습니다.


개인적인 경험으로, 나는 당신의 답의 후반부에 전적으로 동의합니다. 빠르고 컴팩트 한 인덱스가 필요한 것보다 훨씬 적은 빈도로 전역 적으로 고유 한 키가 필요합니다. 필요한 경우 자동 생성 된 ID와 UUID 열이있는 GlobalEntities 테이블을 작성하십시오. 그런 다음 ExGlobalEntityId 외래 키를 Customers 테이블에 추가하십시오. 또는 일부 값의 해시를 사용하십시오.
Drunken Code Monkey

8

불필요한 디자인은 좋은 습관이 아닙니다. 즉, 필요하지 않은 경우 항상 자동 증분 int 기본 키를 갖는 것이 좋지 않습니다.

필요하지 않은 예를 보자.

기사 테이블이 있습니다. 여기에는 int 기본 키 id와 이름이 varchar 열이 title있습니다.

또한 기사 카테고리 ( idint 기본 키 varchar)로 가득 찬 테이블이 있습니다 name.

기사 테이블의 한 행 id에는 5가 있고 title "버터로 거위를 요리하는 방법"이 있습니다. 카테고리 테이블의 "Fowl"( id : 20), "Goose"( id : 12), "Cooking"( id : 2), "Butter"(id : 9) 행과 해당 기사를 연결하려고합니다. .

이제 기사와 카테고리의 2 가지 테이블이 있습니다. 둘 사이의 관계를 어떻게 만드나요?

id (기본 키), article_id (외부 키), category_id (외부 키)의 3 개 열이있는 테이블이있을 수 있습니다. 그러나 이제 다음과 같은 것이 있습니다.

| 아이디 | a_id | c_id |
| 1 | 5 | 20 |
| 2 | 5 | 12 |
| 3 | 5 | 2 |

더 나은 솔루션은 2 개의 열로 구성된 기본 키를 갖는 것입니다.

| a_id | c_id |
| 5 | 20 |
| 5 | 12 |
| 5 | 2 |

다음을 수행하여 수행 할 수 있습니다.

create table articles_categories (
  article_id bigint,
  category_id bigint,
  primary key (article_id, category_id)
) engine=InnoDB;

자동 증분 정수를 사용하지 않는 또 다른 이유는 기본 키에 UUID를 사용하는 경우입니다.

UUID는 고유 한 정의에 따라 고유 정수를 사용하는 것과 동일한 기능을 수행합니다. 또한 정수보다 장점과 단점이 있습니다. 예를 들어 UUID를 사용하면 참조하는 고유 문자열이 특정 데이터 레코드를 가리키는 것입니다. 이 기능은 중앙 데이터베이스가 1 개가 아니거나 응용 프로그램에서 데이터 레코드를 오프라인으로 생성 한 다음 나중에 데이터베이스에 업로드 할 수있는 경우에 유용합니다.

결국 기본 키에 대해 생각할 필요가 없습니다. 그것들을 그들이 수행하는 기능으로 생각해야합니다. 기본 키가 왜 필요한가요? 향후 변경되지 않을 필드를 사용하여 테이블에서 특정 데이터 세트를 고유하게 식별 할 수 있습니다. id이를 수행하기 위해 호출 된 특정 열이 필요 합니까, 아니면 다른 (불변의) 데이터에서이 고유 식별을 기반으로 할 수 있습니까?


7

또는 그러한 필드를 추가하지 않으려는 시나리오가 있습니까?

확실한.

우선, 자동 증분이없는 데이터베이스가 있습니다 (예 : Oracle, 확실히 가장 작은 경쟁자 중 하나는 아닙니다). 이것은 모든 사람이 좋아하거나 필요하지는 않다는 첫 징후입니다.

더 중요한 것은, ID가 실제로 무엇을 생각 입니다 - 그것은 당신의 데이터에 대한 기본 키입니다. 기본 키가 다른 테이블이 있으면 ID가 필요하지 않으며 ID가 없어야합니다. 예를 들어, 테이블 (EMPLOYEE_ID, TEAM_ID)(각 직원이 여러 팀에 동시에있을 수 있는) 테이블 에는이 두 ID로 구성된 기본 키가 명확하게 정의되어 있습니다. ID이 테이블의 기본 키인 자동 증분 열을 추가하면 전혀 의미가 없습니다. 이제 두 개의 기본 키를 사용하고 있으며 "기본 키"의 첫 번째 단어에는 실제로 하나만 있어야한다는 힌트가 표시됩니다.


9
(Oracle 사용자는 질문을 용서하지 않지만) Oracle은 다른 사람이 자동 증분 / ID를 사용하는 것과 같은 방식으로 시퀀스를 사용하지 않습니까? 오라클은 Autoincrement 데이터 유형이 실제로는 단순한 주장이 아니라고 말하는가?
Brad

글쎄, 그것은 작은 지점에 불과했습니다. 주요 부분은 실행중인 ID가 모든 테이블에 적합하지 않으므로 모든 단일 테이블에서 자동 ID를 때리는 데 익숙하지 않은 것이 가장 현명하지 않을 수 있습니다.
AnoE

기본 키는 두 개가 없으며 기본 키는 하나 뿐이며 나머지는 기본 키 역할을 할 수있는 경우 후보 키라고합니다.
rahul tyagi

7

"장기"데이터에 대한 새 테이블을 정의 할 때 일반적으로 "식별"열 (자동 발생 정수)을 사용합니다 (비트 필드를 설정하여 한 번 삽입하고 "논리적으로 삭제"된 경우에도 무기한으로 유지됩니다. ).

내가 사용하고 싶지 않을 때 생각할 수있는 몇 가지 상황이 있습니다. 대부분의 경우 DB의 한 인스턴스에서 하나의 테이블이 새 ID 값의 권위있는 소스가 될 수없는 시나리오로 요약됩니다.

  • 증분 ID가 잠재적 공격자에게 너무 많은 정보 인 경우 "공개 직면"데이터 서비스에 식별 열을 사용하면 "독일 탱크 문제"에 취약합니다. 레코드 ID 10234가 존재하면 레코드 10233, 10232 등이 존재하고 적어도 레코드 10001로 돌아가는 이유가되며 ID 100이 시작된 위치를 찾기 위해 레코드 1001, 101 및 1을 쉽게 점검 할 수 있습니다. 주로 임의의 데이터로 구성된 V4 GUID는 의도적으로이 증분 동작을 중단하므로 GUID가 하나만 존재하기 때문에 GUID 바이트를 늘리거나 줄여 생성 한 GUID가 반드시 존재하지 않아도되므로 공격자가 의도 한 서비스를 사용하기가 더 어려워집니다. 덤프 도구로 단일 레코드 검색 액세스를 더 잘 제한 할 수있는 다른 보안 조치가 있지만 도움이됩니다.
  • M : M 상호 참조 테이블에서. 이건 일종의 gimme이지만 이전에 본 적이 있습니다. 데이터베이스의 두 테이블간에 다 대다 관계가있는 경우 이동 솔루션은 각 테이블의 PK를 참조하는 외래 키 열을 포함하는 상호 참조 테이블입니다. 이 테이블의 PK는 내장 인덱스 동작을 얻고 참조의 고유성을 보장하기 위해 사실상 항상 두 개의 외래 키의 복합 키 여야합니다.
  • 이 테이블에서 대량으로 삽입 및 삭제를 계획 할 때 많이 있습니다. ID 열의 가장 큰 단점은 원래 테이블의 키 값을 유지하려는 다른 테이블이나 쿼리에서 행을 삽입 할 때 수행해야하는 추가 hoopla 일 것입니다. "ID 삽입"을 켜고 (단, DBMS에서 수행 한 경우) 삽입하는 키가 고유한지 수동으로 확인한 다음 가져 오기를 마치면 ID 카운터를 설정해야합니다. 테이블의 메타 데이터를 최대 값으로 표시합니다. 이 작업이이 테이블에서 많이 발생하면 다른 PK 체계를 고려하십시오.
  • 분산 테이블의 경우.ID 열은 단일 인스턴스 데이터베이스, 장애 조치 쌍 및 한 데이터베이스 인스턴스가 주어진 시간에 전체 데이터 스키마에 대한 유일한 권한 인 기타 시나리오에 적합합니다. 그러나 당신이 갈 수있는 크기는 너무 커서 여전히 하나의 컴퓨터가 충분히 빠릅니다. 복제 또는 트랜잭션 로그 전달을 통해 추가 읽기 전용 복사본을 얻을 수 있지만 해당 솔루션의 규모에도 제한이 있습니다. 조만간 데이터 삽입을 처리 한 다음 서로 동기화하는 둘 이상의 서버 인스턴스가 필요합니다. 이러한 상황이 발생하면 대부분의 DBMS는 인스턴스 별 식별자로 생성 된 GUID의 일부를 사용하도록 미리 구성된 후 나머지 식별자를 임의로 생성하므로 증분 필드 대신 GUID 필드가 필요합니다. 또는 증분. 두 경우 모두
  • DB의 여러 테이블에서 고유성을 적용해야하는 경우예를 들어, 회계 시스템에서는 일반적으로 1 년을 나타내는 일련의 테이블로 총계정 원장 (모든 계정의 각 신용 또는 직불에 대한 행을 포함하여 매우 빠르게 커짐)을 관리하는 것이 일반적입니다. 년. 그런 다음보고를 위해 뷰를 함께 연결하여 뷰를 만들 수 있습니다. 논리적으로, 이것은 모두 하나의 매우 큰 테이블이지만, 테이블을 잘라 내면 DB의 유지 관리 작업이 쉬워집니다. 그러나 중복 키로 끝나지 않고 여러 테이블에 대한 삽입을 관리하는 방법 (다음 달에 트랜잭션 로깅을 시작하면서 마지막 달을 닫을 수 있음)의 문제가 있습니다. 다시 말하지만, IDMS 열 대신 GUID는 DBMS가 고유 한 방식으로 열을 생성하도록 설계되었으므로

내가 바라는 것처럼 이러한 상황에서 ID 열을 사용할 수있는 해결 방법이 있지만 대부분의 경우 ID 정수 열에서 GUID로 업그레이드하는 것이 더 간단하고 문제를 더 완벽하게 해결합니다.


1
ID, ID_M, ID_NM : N 관계의 인스턴스에 특성을 첨부하기 때문에 M : N 테이블에서 열을 사용하여 ID가 ​​여전히 필요한 경우가 있습니다 .
miroxlav

V4 GUIDS는 암호화 적으로 강력한 PNRG를 사용한다고 보장하지 않으므로 첫 번째 예제 imo에 의존해서는 안됩니다 (db 엔진이 더 강력한 약속을하더라도 괜찮을 수는 있지만 다소 이식성이 없습니다). 그렇지 않으면 잘 추리 된 게시물입니다.
Voo

1
@miroxlav-테이블에 두 FK 외부의 별도 PK가 좋은 아이디어라는 관계와 관련하여 충분한 추가 메타 데이터가있는 경우 더 이상 상호 참조 테이블이 아니라고 주장합니다. 다른 두 사람을 참조하는 것은 그 자체의 실체입니다.
KeithS

@Voo-맞습니다. V4 GUID는 암호화 방식으로 무작위로 보장되지 않으며 모든 GUID와 마찬가지로 고유합니다. 그러나 미국 제트 전투기의 꼬리 수는 암호로 무작위 시드 데이터 / 알고리즘에서 생성되지 않습니다. 당신이 정말로 찾고있는 것은 드문 인구가 많은 도메인입니다. V4 GUID에는 112 바이트의 무작위 데이터가 있으며 5e33 레코드를 고유하게 식별 할 수 있습니다.
KeithS

이 숫자를 고려하면, 지구상의 모든 남녀 (70 억 명)는 각각 데이터베이스에 741 조 개의 개별적으로 카탈로그되고 ID 된 데이터 포인트를 가질 수 있으며 , 여전히 10 억 개의 GUID 값만 사용할 수 있습니다. 글로벌 산업으로서의 빅 데이터는이 정도의 지식에 가깝지 않습니다. GUID 생성에 패턴이 주어 지더라도 데이터가 시스템에 입력되고 GUID가 할당되는 순서와 같은 다른 엔트로피 소스가 있습니다.
KeithS

7

자동 증분 (ID) 기본 키는 데이터베이스 컨텍스트와 해당 데이터베이스의 직접 클라이언트 외부에서는 의미가 없다는 점을 제외하고는 좋은 아이디어입니다. 예를 들어, 일부 데이터를 다른 데이터베이스에 전송하고 저장 한 다음 두 데이터베이스 테이블에 다른 데이터를 쓰면 ID가 분산됩니다. 즉, 한 데이터베이스에서 ID가 42 인 데이터가 반드시 데이터와 일치하지는 않습니다. 다른 ID는 42입니다.

이를 감안할 때 데이터베이스 외부에서 행을 고유하게 식별 할 수 있어야하는 경우 (그리고 빈번한 경우),이 목적을 위해 다른 키가 있어야합니다. 신중하게 선택된 비즈니스 키가 필요하지만, 고유성을 보장하는 데 필요한 많은 수의 열 위치에있게됩니다. 또 다른 기술은 ID 열을 자동 증분 클러스터 된 기본 키로, 또 다른 고유 식별자 (guid) 열을 비 클러스터 된 고유 키로 만들어 세계 어디에서나 행을 고유하게 식별하는 것입니다. 이 경우 여전히 자동 증가 키가있는 이유는 자동 증가 키를 guid와 동일하게 수행하는 것보다 자동 증가 키를 클러스터링하고 색인화하는 것이 더 효율적이기 때문입니다.

자동 증가 키를 원하지 않는 경우는 기본 키가 다른 두 테이블의 ID 열의 복합 인 다 대다 테이블입니다 (여기서 자동 증가 키를 가질 수는 있지만 I 요점을 보지 마십시오).

다른 질문 중 하나는 자동 증분 키의 데이터 유형입니다. Int32를 사용하면 값은 크지 만 상대적으로 제한적인 범위를 제공합니다. 개인적으로 나는 값이 부족 할까 걱정할 필요가 없도록 종종 ID에 bigint 열을 사용합니다.


6

다른 사람들이 증가하는 기본 키에 대한 사례를 만들었으므로 GUID에 대해 만들 것입니다.

  • 독특하다는 것이 보장됩니다
  • 응용 프로그램의 데이터를 위해 데이터베이스를 한 번 덜 여행 할 수 있습니다. 예를 들어 유형 테이블의 경우 응용 프로그램에 GUID를 저장하고 레코드를 검색하는 데 사용할 수 있습니다. ID를 사용하는 경우 이름으로 데이터베이스를 쿼리해야하며 PK를 얻기 위해이 작업을 수행하는 많은 응용 프로그램을 보았습니다. 나중에 자세한 내용을 보려면 다시 쿼리하십시오.
  • 데이터를 숨기는 데 유용합니다. www.domain.com/Article/2 두 개의 기사 만있는 반면 www.domain.com/article/b08a91c5-67fc-449f-8a50-ffdf2403444a는 아무 것도 알려주지 않습니다.
  • 다른 데이터베이스의 레코드를 쉽게 병합 할 수 있습니다.
  • MSFT는 ID를 위해 GUIDS를 사용합니다.

편집 : 포인트 복제


5
-1. GUID / UUID는 고유하다고 보장되지 않으며 100 % 고유하지 않습니다. GUID는 여전히 유한 길이이므로 어느 시점에서는 복제 가능성이 높지 않지만 중복 될 위험이 있습니다. 데이터베이스로의 여행 횟수가 줄어든 것에 대한 요점도 유효하지 않습니다. GUID 키를 사용하여 기본 ID를 애플리케이션에 저장할 수없는 이유는 무엇입니까?
Niklas H

2
제프 애트우드는 내가 할 수있는 것보다 훨씬 더 잘 말합니다. blog.codinghorror.com/primary-keys-ids-versus-guids
3 가지 가치 논리

왜 애플리케이션에 기본 ID를 저장할 수 없습니까? 데이터베이스가 작성하기 때문입니다. 빈 데이터베이스에서 시드를 실행하면 ID가 1이라고 가정 할 수 있습니다. 데이터베이스에 데이터가있는 동일한 스크립트를 실행하면 어떻게됩니까? ID는 1이되지 않습니다.
Three Value Logic

당신은 응용 프로그램에서 ID를 만드는 것에 대해 아무 말도하지 않았습니다-당신은 방금 "저장"을 썼습니다. 그러나 데이터베이스 외부에서 ID를 작성해야하는 경우 GUID가 답이 될 수 있습니다.
Niklas H

2
나는 그들이 더 나은 확장을 추가 할 것입니다. Cassandra와 같은 빅 데이터 NoSQL 데이터베이스는 자동 증분 키도 지원하지 않습니다.
Karl Bielefeldt

2

우수한 설계 원칙으로 모든 테이블은 행을 고유하게 식별 할 수있는 안정적인 방법을 가져야합니다. 이것이 기본 키의 목적이지만 항상 기본 키가 필요한 것은 아닙니다. 모든 테이블에 기본 키를 추가하는 것은 고유 한 행 식별을 제공하기 때문에 나쁜 습관은 아니지만 불필요 할 수 있습니다.

둘 이상의 테이블 행 사이의 안정적인 관계를 유지하려면 외래 키를 통해 관계를 유지해야하므로 적어도 일부 테이블에는 기본 키가 필요합니다. 모든 테이블에 기본 키를 추가하면 기존 테이블에 새로운 테이블이나 관계를 추가 할 때 데이터베이스 디자인을보다 쉽게 ​​확장 할 수 있습니다. 미리 계획하는 것은 항상 좋은 일입니다.

기본 원칙 (하드 규칙 일 수도 있음)으로서 기본 키의 가치는 행 수명 동안 변하지 않아야합니다. 한 행에있는 모든 비즈니스 데이터는 수명 기간 동안 변경 될 수 있으므로 모든 비즈니스 데이터는 기본 키의 열악한 후보가 될 것입니다. 이것이 자동 증가 정수와 같은 추상적 인 것이 종종 좋은 생각 인 이유입니다. 그러나 자동 증분 정수에는 제한이 있습니다.

데이터가 데이터베이스 내에서 수명 만있는 경우 자동 증분 정수가 좋습니다. 그러나 다른 답변에서 언급했듯이 데이터 공유, 동기화 또는 데이터베이스 외부의 수명을 원한다면 자동 증가 정수는 기본 키를 열악하게 만듭니다. 더 좋은 선택은 guid (일명 uuid "universally unique id")입니다.


2

질문과 많은 대답은 각 테이블의 모든 자연 키 가 데이터베이스 의 논리적 스키마 에만 있고 각 테이블의 모든 대리 키 는 데이터베이스 의 실제 스키마 에만 있다는 중요한 요점을 놓치고 있습니다. 다른 답변은 대리 키가 올바르게 사용되는 이유와시기를 논의하지 않고 정수 대 GUID 대리 키의 상대적인 이점에 대해서만 논의합니다.

BTW : 잘못 정의되고 부정확 한 기본 키 사용을 피하십시오 . 이는 관계형 모델에 먼저 (비현실적으로) 채택 된 다음 다양한 RDBMS 공급 업체가 물리적 도메인으로 다시 채택한 사전 관계형 데이터 모델의 인공물입니다. 그것의 사용은 의미를 혼동시키는 역할을한다.

로부터 참고 관계형 모델 데이터베이스에 대한 순서, 논리적 스키마 에있을 제 1 정규형 , 모든 테이블이 있어야합니다 로 알려진 분야의 사용자가 볼 수있는 세트 자연 키, 고유 테이블의 각 행을 식별합니다. 대부분의 경우 이러한 자연 키는 쉽게 식별 할 수 있지만 경우에 따라 타이 브레이커 필드 또는 기타 로 구성해야합니다 . 그러나 이러한 생성 된 키는 항상 사용자가 볼 수 있으므로 항상 데이터베이스 의 논리적 스키마 에 있습니다.

반대로 테이블의 대리 키 는 데이터베이스 의 실제 스키마 에 상주 하므로 보안상의 이유와 데이터베이스 무결성을 유지하기 위해 데이터베이스 사용자에게는 항상 보이지 않아야합니다. 대리 키 를 도입 한 유일한 이유 는 DB 의 물리적 유지 관리 및 사용 에서 성능 문제를 해결하기위한 입니다. 조인, 복제, 데이터의 여러 하드웨어 소스 또는 기타 여부

대리 키를 도입 한 유일한 이유는 성능이므로 성능을 원한다고 가정합니다. 현재 성능 문제가 조인이라면 대리 키를 가능한 한 좁게 만들어야합니다 (하드웨어를 방해하지 않고 짧은 정수와 바이트가 일반적으로 없음). 결합 성능은 최소 인덱스 높이에 의존하므로 4 바이트 정수는 자연스러운 솔루션입니다. 성능 문제가 삽입 속도 인 경우 4 바이트 정수도 RDBMS 내부에 따라 자연스러운 솔루션 일 수 있습니다. 테이블의 성능 문제가 다른 대리 키 기술 보다 복제 또는 여러 데이터 소스 인 경우 GUID 또는 두 부분 키 (호스트 ID + 정수)가 더 적합 할 수 있습니다. 나는 개인적으로 GUID를 좋아하지 않지만 편리합니다.

요약하면 모든 테이블에 대리 키 (모든 유형) 가 필요한 것은 아닙니다 . 고려중인 테이블의 성능에 필요한 것으로 간주되는 경우에만 사용해야합니다. 어떤 일반적인 대리 핵심 기술을 선호 하든 선택하기 전에 테이블의 실제 요구 사항을 신중하게 고려하십시오. 테이블에 대한 대리 핵심 기술 선택을 변경하면 많은 노력이 필요합니다. 후임자가 선택한 사항을 이해할 수 있도록 테이블의 주요 성능 지표를 문서화하십시오.

특수한 상황들

  1. 비즈니스 요구 사항이 해당 필드 이외의 감사 (또는 기타) 목적으로 순차적 인 트랜잭션 번호 지정을 요구 하는 경우 대리 키 가 아닙니다 . 추가 가 필요한 자연 키 입니다. 문서에서 자동 증가 정수는 서로 게이트 키만 생성하므로이를 생성하는 다른 메커니즘을 찾으십시오. 분명히 어떤 종류의 모니터가 필요하며, 여러 사이트에서 트랜잭션을 소싱 하는 경우 모니터 의 지정된 호스트 사이트 이기 때문에 하나의 사이트가 특별 합니다.

  2. 테이블이 약 백 행을 넘지 않으면 인덱스 높이는 관련이 없습니다. 모든 액세스는 테이블 스캔으로 이루어집니다. 그러나 긴 문자열의 문자열 비교는 여전히 4 바이트 정수 비교보다 훨씬 비싸고 GUID 비교보다 비쌉니다.

  3. char (4) 코드 필드로 키가 지정된 코드 값 테이블은 4 바이트 정수를 가진 테이블만큼 성능이 좋아야합니다. 나는 이것에 대한 증거가 없지만 가정을 자주 사용하고 그것을 추론 할 이유가 없었습니다.


-1

실용적이지 않을뿐만 아니라 Bill Karwin의 SQL Antipatterns 책에서 안티 패턴으로 설명되어 있습니다.

모든 테이블에 의사 키 (임의의 값이 아닌 기본 키인 모델)가 필요한 것은 아니며 항상 호출 할 이유가 없습니다 id.


이것은 이전의 9 가지 답변에서 제시되고 설명 된 포인트를 넘어서는 실질적인 내용을 제공하지 않는 것 같습니다
gnat

2
왜 이것이 중요 할 수 있습니까?
gnat

3
@gnat 질문을 직접 다루는 모범 사례에 관한 책이기 때문입니다. 분명하지 않습니까?
Pedro Werneck

3
조금도 아닙니다. "book sql best practice"에 대한 Google 검색에서 약 900K 개의 링크가 표시됩니다.이 링크가 특히 가치가있는 이유
gnat

1
@gnat 나는 하루 종일 논쟁하지 않을 것입니다. 당신은 답이 마음에 들지 않습니다.
Pedro Werneck

-2

이것은 매우 보편적입니다. 그렇지 않으면 키가 실제로 고유한지 확인해야합니다. 다른 모든 키를 살펴보면 시간이 많이 걸릴 것입니다. 레코드 번호가 키 오버플로 값에 가까워지면서 증분 키를 갖는 것은 비용이 많이 듭니다.

필자는 일반적으로 포인터를보다 분명한 필드 이름과 같 ref_{table}거나 유사한 아이디어로 만듭니다.

외부 적으로 레코드를 가리킬 필요가 없으면 ID가 필요하지 않습니다.


키 롤오버 값?
AJJ

부호없는 정수는 1을 추가하기 전에 최대 값이 4294967295이며 0으로 롤오버됩니다. 레코드를 추가 한 후 삭제하면 카운터가 계속 증가합니다. unsigned int필드 유형에 사용하십시오. 그렇지 않으면 한계는 해당 숫자의 절반입니다.
Johnny V


2
많은 행을 추가 / 제거하면 자동 증분 카운터가 결국 오버플로됩니다.
Johnny V

1
사람들은 롤오버를 어떻게 처리합니까? 삭제되지 않은 ID가 낮은 레코드가 있지만 일부 ID가 4294967295의 상단에있는 끝 부분에 도달하기 시작하면 어떻게됩니까? "인덱싱"을 수행 할 수 있습니까?
AJJ

-2

나는 그것이 항상 이루어져야 한다고 말하지 않을 것입니다. 여기에 고유 키가없는 테이블이 있으며 필요하지 않습니다. 감사 로그입니다. 업데이트는 없으며 쿼리는 기록되는 내용에 대한 모든 변경 사항을 반환하지만 사람이 잘못된 변경을 정의하는 데 합리적으로 수행 할 수있는 최선의 방법입니다. (코드가 가능하다면 처음에는 코드를 허용하지 않았을 것입니다!)


-3

기본 키의 자동 증분 카운터는 좋지 않습니다. 데이터를 삽입하기 전에 다음 키를 찾아 하나씩 키를 늘리려면 데이터베이스로 돌아 가야하기 때문입니다.

나는 일반적으로 데이터베이스가 기본 키에 제공 할 수있는 모든 것을 응용 프로그램의 일부로 사용하는 대신 사용합니다.

데이터베이스가 기본적으로 데이터베이스를 제공하도록하여 필요한 고유 한 키를 보장 할 수 있습니다.

물론 모든 데이터베이스가이를 지원하는 것은 아닙니다. 어떤 경우에는 일반적으로 키 버킷을 저장하고 응용 프로그램에서 관리되는 높고 낮은 범위를 사용하는 테이블을 사용합니다. 이것은 10000 숫자의 범위를 얻고 응용 프로그램 인스턴스에서 자동으로 증가시키기 때문에 내가 찾은 가장 성능이 좋은 솔루션입니다. 다른 응용 프로그램 인스턴스는 다른 숫자 버킷을 사용하여 작업 할 수 있습니다. 64 비트 길이와 같이 충분히 큰 기본 키 기본 요소가 필요합니다.

UUID 키를 만들고 저장하는 비용이 긴 값을 1 씩 늘리는 것보다 훨씬 높기 때문에 기본 키로 사용하지 않습니다. UUID는 이론적으로 중복이 발생할 수 있다는 점에서 생일 역설을 처리합니다.


3
아니요. 자동 증분 키는 데이터베이스에서 키 증분이 자동으로 수행됨을 의미합니다. 때로는 그렇게 할 시퀀스 + 트리거 조합을 필요로 (나는!, 당신 오라클을 찾고 있어요),하지만 당신은 결코 그것을 사용, 1을 추가 키의 이전에 삽입 된 값을 검색 할 필요가 없습니다.
SQB

JPA와 같은 일부 지속성 프레임 워크에서 키 값을 호출자에게 다시 리턴하려면 키를 보려면 레코드를로드해야합니다.
Archimedes Trajano
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.