'거대한'데이터베이스 테이블 PK의 순차적 GUID 또는 bigint


14

이런 유형의 질문이 많이 나온다는 것을 알고 있지만 아직 결정을 내리는 데 도움이되는 강력한 주장을 읽지 않았습니다. 저를 참아주세요!

나는 거대한 데이터베이스를 가지고 있습니다-하루에 약 10,000,000 개의 레코드가 증가합니다. 데이터는 관계형이며 성능상의 이유로 BULK COPY로 테이블을로드합니다. 이러한 이유로 행의 키를 생성해야하며 IDENTITY 열에 의존 할 수 없습니다.

64 비트 정수-bigint는 사용하기에 충분히 넓지 만 고유성을 보장하려면 내 ID를 만들 수있는 중앙 집중식 생성기가 필요합니다. 현재 서비스에서 X 시퀀스 번호를 예약하고 충돌을 보장하지 않는 생성기 서비스가 있습니다. 그러나 이것의 결과는 내가 가진 모든 서비스 가이 하나의 중앙 집중식 발전기에 의존하기 때문에 시스템을 배포 할 수있는 방법이 제한되어 있으며 부과 된 다른 종속성 (예 : 네트워크 액세스 필요)에 만족하지 않습니다 이 디자인으로. 때때로 문제가되었습니다.

이제 순차 GUID를 기본 키 (SQL 외부에서 생성)로 사용하려고합니다. 내 테스트에서 확인할 수있는 한, 이것의 유일한 단점은 더 넓은 데이터 유형의 디스크 공간 오버 헤드 (인덱스에서의 사용으로 인해 악화됨)입니다. bigint 대안에 비해 쿼리 성능이 눈에 띄게 느려지는 것을 목격하지 않았습니다. BULK COPY로 테이블을로드하는 것은 약간 느리지 만 많이는 아닙니다. 순차적 GUID 구현으로 인해 GUID 기반 인덱스가 조각화되지 않습니다.

기본적으로, 내가 간과하고 싶은 다른 고려 사항이 있는지 알고 싶습니다. 현재 나는 도약을 시도하고 GUID를 사용하기 시작했다. 나는 결코 데이터베이스 전문가가 아니므로 어떤 지침도 정말로 감사하겠습니다.


2
"순차 GUID"를 어떻게 생성 하시겠습니까?

그것은 커스텀 구현입니다. 기본적으로 6 바이트가 타임 스탬프 바이트로 교체되고 2 바이트가 타임 스탬프가 동일한 시퀀스 번호를 나타내는 GUID 유형 형식입니다. 완벽한 순차 값을 생성한다고 보장하지는 않지만 인덱스 조각화를 문제가 아닌 것으로 만들 수 있습니다.

따라서이 데이터를 여러 다른 소스에서로드하고 있습니까? 또한 조각화가 걱정되는 인덱스가 클러스터형 인덱스라고 가정합니다.

2
순차 GUID를 사용하는 경우 NEWSEQUENTIALID ()를 봐야합니다. 원하는 것을 수행해야하며 (단일 증가) 사용자 정의 코드에 의존하지 않습니다.

2
예레미야 페 쉬카 (Weremiah Peschka) 게시물 키를 보면 문제를 잘 읽어보십시오.
billinkc

답변:


4

나는 비슷한 상황에 처해있다. 현재 순차적 GUID 접근 방식을 사용하고 있으며 조각화 및 쉬운 키 생성이 없습니다.

나는 bigint로 이주하기 시작한 두 가지 단점을 발견했다.

  1. 공간 사용량 . 인덱스 당 8 바이트 이상. 여기에 10 지수를 곱하면 엄청난 공간 낭비가 발생합니다.
  2. 열 저장소 인덱스는 GUID를 지원하지 않습니다.

(2) 나를 위해 살인자였다.

이제 다음과 같이 키를 생성합니다.

yyMMddHH1234567890

내가 사용하게 될 주요 날짜 및 시간 과 가진 순차적 부분 그 이후를. 따라서 추가 인덱스없이 날짜별로 데이터를 범위 쿼리 할 수 ​​있습니다. 이것은 나에게 좋은 보너스입니다.

나는 분산 되기에 적합한 HiLo 알고리즘을 사용하여 bigint의 순차적 인 부분을 생성 할 것이다 .

이 중 일부가 귀하의 상황으로 이전되기를 바랍니다. bigint를 사용하는 것이 좋습니다.


1
이것이 가장 적합하기 때문에 이것을 '답변'으로 표시하십시오. 공유 시퀀스 생성기 (HiLo 알고리즘 제안과 유사하게 작동)를 사용한다고 생각합니다. 나는 약간의 문제가있는 다른 시스템 에서이 작업을 수행하고 있으며, 여분의 의존성을 참 아야합니다. 오 잘 감사.
Barguast

3

유형이 INT1에서 시작하면 20 억 개가 넘는 행 을 얻을 수 있습니다. 이는 대부분의 경우에 충분해야합니다. 을 사용 BIGINT하면 대략 922 조 (15 개의 922-922'000 십억)를 얻을 수 있습니다.

INT IDENTITY1에서 시작 을 사용하고 매초마다 행을 삽입하는 경우 20 억 한계에 도달하기 전에 66.5 이 필요 합니다 ....

BIGINT IDENTITY1에서 시작 을 사용하고 초당 1000 행을 삽입하는 경우 922 조의 한계에 도달하기 전에 2 억 9,300 만 년이 걸렸어 야합니다.

하루에 천만 행을 사용하면 약 1'844'674'407'370 일 ( 1844 억 일 또는 50 억 년 이상의 진드기 ) 데이터에 충분한 수의 데이터가 필요합니다. ?

MSDN 온라인 설명서 에서 모든 옵션을 통해 이에 대해 자세히 읽어보십시오 .


1
하루 1000 만 행의 삽입 률은 200 일 안에 INT 범위를 소진합니다.
mceda

@ mceda : 예-다른 것을 주장 했습니까? 그것은 BIGINT범위를 빨리 소모하지 않습니다 ....
marc_s

고맙지 만 내 질문에서 말했듯이 데이터베이스로 전송되기 전에 ID가 필요합니다. 데이터는 관계형이므로 대량 복사하기 전에 기본 및 외래 키를 할당해야합니다. 그렇지 않다면 IDENTITY BIGINT가 완벽 할 것입니다.

2
@Barguast : 데이터를 준비 테이블에 (아이덴티티없이) 대량 삽입 한 다음 BIGINT IDENTITY?를 사용하여 실제 데이터 테이블로 옮길 수 없었습니다 .
marc_s

@marc_s : 그렇습니다. 제공된 계산은 다음과 같은 질문과 일치하지 않습니다. "1에서 시작하는 INT IDENTITY를 사용하고 1 초마다 행을 삽입하는 경우 20 억 한도에 도달하기 전에 66.5 년이 필요합니다."
mceda

2

SQL 2012에서 SEQUENCE of BIGINT 데이터 형식을 사용하는 것이 좋습니다. 이것은 cache / nocache와 같은 옵션을 사용하여 IDENTITY보다 훨씬 융통성이 있으며 배치 작업에 대한 시퀀스 범위를 sp_sequence_get_range로 지정할 수도 있습니다.


불행히도 SEQUENCE는 Sql Azure에서 지원되지 않습니다.
Timothy Lee Russell

2

로드하는 별도의 테이블간에 이미 외래 키 관계가 있기 때문에 IDENTITY를 사용할 수없는 이유입니까? 그리고 스테이징 영역에서 생산 영역으로 작업에서 이들을 연결할 수있는 다른 자연 키가 없습니까? 이런 이유로, 대량 복사하기 전에 소스 시스템에서 현재 "연결"되는 방법에 대해 좀 더 알고 싶습니다. 여러 소스 시스템이 단순히 자체 시퀀스를 사용하고 공유 데이터베이스로 가져올 때 시퀀스가 ​​충돌 할 가능성이 있습니까?

COMB ID / 순차 GUID 기술은 내가 잘 알고있는 기술로, 데이터베이스 외부에 할당 된 전역 고유성을 효과적으로 필요할 때 언제든지 사용할 수 있습니다. 실제로 데이터베이스 내부와 외부에서 사용 가능한 행 ID입니다. 이러한 이유로 고도로 분산 된 환경이나 연결이 끊긴 시나리오에서는 괜찮습니다.

실제로 필요하지 않은 경우를 제외하고 는 데이터의 크기가 커지고 이러한 키가 모든 쿼리 및 많은 쿼리에 대한 작업 세트에있을 때 추가 너비 차이가 중요하기 때문에.

또한 생성이 분산 된 상태에서 행이 실제로 GUID 열의 순서로 나오지 않으면 클러스터 된 인덱스 키 (좁은, 정적, 증가)에 이것을 사용하는 문제로 인해 IDENTITY의 클러스터링과 비교하여 일부 조각화가 발생할 수 있습니다 남아있다.


0

일반적으로 command OUTPUTof clause 를 사용 INSERT하여 두 테이블에 데이터를 삽입하고 ID 필드와 관련시킬 수 있습니다.

타임 스탬프를 기반으로하는 식별자는 신뢰할 수있는 것으로 간주되어서는 안됩니다. 하드웨어 클럭에서 시간 동기화 서비스에 이르기까지 시스템 클럭에 따라 달라집니다.

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