2009-06-29 4 views
9

많은 텍스트를 저장할 데이터베이스를 계획 중입니다. (블로그 게시물, 뉴스 기사 등) 데이터베이스에는 제목, 내용 (최대 50,000 자), 날짜, 링크 및 언어 필드가 있어야합니다. 하나의 링크에서 동일한 내용이 발생할 수 없습니다. 이전 콘텐츠 (예 : 30 일 이전)가 삭제됩니다.PostgreSQL : 대형 데이터베이스에서 기본 키 정의

이제 문제는 기본 키입니다. 자동 증가 (SERIAL 유형) 필드를 설정하여 기본 키로 사용할 수 있습니다. 그러나 필드가 어떤 목적도 제공하지 않고 기본 키가되기 때문에 디스크 공간 낭비와 어리석은 것처럼 보입니다. (그리고 필드는 결국 부족할 수 있습니다.) 그리고 항상 다른 성능 문제가 있습니다. 삽입 된 각 새 행의 내용에 중복이 있는지 확인해야합니다. 그래서 기본 키에 대한 다른 해결책은 내용 + 링크 값의 sha256 해시를 계산 한 다음이를 새로운 '해시'열에 넣고이를 기본 키로 사용하는 것입니다. 한 돌로 두 마리. 물론 그 문제는 해시 충돌입니다. 큰 위협입니까?

PostgreSQL에 대한 경험이 거의 없으므로 일반적으로 DBMS 사용 경험이 거의 없으므로 고속도로에서 달팽이의 성능 특성 (끔찍한 비교)이있는 데이터베이스를 만들기 전에 두 번째 의견을 생각해보십시오.

대용량 데이터베이스 사용 경험이 있으시면 여기서 도와주십시오. 내 상황에서는 64 자 문자열을 기본 키 필드로 설정하는 것이 좋습니다. (나는 인상이기 때문에 일반적으로이를 방지하기 위해)

답변

9

그냥 오히려 중간 대형 DB (2백기가바이트 +), 매우 큰 차이로 승리 BIGSERIAL이 정확한 테스트를했다. 생성 속도가 빠르며, 참여가 빠르며 코드가 적고 설치 공간이 적습니다. postgres가 저장하는 방식 때문에 bigint는 보통 int에 비해 무시할 수 있습니다. bigint의 오버플로에 대해 걱정할 필요가 없기 오래 전에 콘텐츠의 저장 공간이 부족합니다. 계산 된 해시 대 bigint - surrogate bigint를 끝내야합니다.

+0

테스트에 "다른 성능 문제 : 새로운 행을 삽입 할 때마다 중복 된 내용을 확인해야합니다"라는 내용이 포함 되었습니까? – onedaywhen

2

제안 :

  • 64 비트 기본 키 정수의 디스크 스토리지에 상관없이 당신이 얼마나 많은 콘텐츠를 무시할 수 없다.
  • SHA256을 충돌시키지 않고 고유 ID로 사용하는 것은 좋지 않습니다.

해시 방법에 대한 좋은 점 중 하나는 새로운 기본 키를 생성하는 단일 시퀀스 소스가 없다는 것입니다. 이것은 데이터베이스가 충돌에 대해 걱정할 필요가 없으므로 미래의 확장을 위해 데이터베이스를 어떤 방식 (예 : 지리적 분포)으로 세분화해야하거나 시퀀스를 생성하는 단일 실패 지점 (point-of-failure)에 유용 할 수 있습니다.

코딩 관점에서 볼 때 단일 기본 키를 사용하면 나중에 추가 할 수있는 추가 데이터 테이블에 조인 할 수 있습니다. 나는 당신이 하나를 사용하는 것이 좋습니다. 제안 된 접근법에는 이점이 있지만 해시 방법이 선호 될 수 있습니다. 자동 증가/시퀀스 값으로 인해 가끔 확장 성 문제가 발생할 수 있기 때문입니다.

+1

SHA256을 기본 키로 사용하는 경우 불변 일 필요는 없습니까? 콘텐츠 + 링크 값이 변경되면 어떻게됩니까? –

+0

Harvey, 좋은 지적이지만 행의 내용 값을 변경하려는 경우 새로운 콘텐츠 + 링크 alredy의 해시가 있는지 확인합니다. 그렇다면 변화가 일어나지 않을 것입니다. – KRTac

+0

따라서 내용이 변경되면 새 레코드가 생성됩니까? –

1

해시는 기본 키에 대해 좋지 않은 아이디어입니다. 삽입물이 테이블에서 임의의 순서로 끝나게 만들고, 재 할당해야하므로 비용이 많이 든다. (Postgres는 다른 사람들이하는 것처럼 적용되지는 않지만). 순차적 인 번호를 가진 세분화 된 타임 스탬프/타임 스탬프 일 수있는 순차 기본 키를 제안합니다. 돌로 두 마리의 새를 죽이게하고 해시 코드가 포함 된 두 번째 고유 인덱스를 삭제할 수 있습니다. 기본 키는 더 작은 (64 비트 이하) 열로 유지해야합니다.

http://en.wikipedia.org/wiki/Birthday_attack#The_mathematics의 표를 참조하면 충돌이 발생하지 않을 것이라고 확신 할 수 있습니다.

진공 청소기를 잊지 마세요.

3

기본 키 정수가 모두 소진되기 전에 엄청난 양의 기록이 있어야합니다.

정수는 64 자 문자열 기본 키보다 조인 속도가 빠릅니다.또한 쿼리 작성자가 처리하기가 훨씬 쉽습니다.

충돌이 발생할 수있는 경우 해시를 기본 키로 사용할 수 없습니다. 기본 키는 정의에 의해 고유해야합니다.

저는 여러 기업 및 정부 기관에 대해 수백 개의 프로덕션 데이터베이스를 보았으며 해시 프라이 머리 키를 사용하지 않았습니다. 이유가 있다고 생각하십니까?

그러나 필드가 어떤 용도로도 사용되지 않고 기본 키가되기 때문에 디스크 공간이 낭비되고 낭비되는 것처럼 보입니다.

대리자 기본 키를 제외하고는 항상 기본 키가 아닌 의미가 있어야하므로 귀하의 이의 제기가 확실하지 않습니다.

+0

테이블에 많은 행을 넣을 계획입니다. 이전 행은 삭제되지만 필드는 행 개수를 자동으로 늘리므로 직렬 필드가 2147483647에 도달하면 테이블에 더 이상 행을 가져올 수 없으므로 테이블이 절반 비어있을 수도 있습니다. – KRTac

+1

32 비트 부호있는 정수를 나타냅니다. 64 비트 부호있는 정수의 경우 최대 값은 9,223,372,036854775807입니다. 네가 그걸 다 피할 수 있을지 의심한다. –

+1

해시가 빠를까요, 에바노 64 비트 int입니까? – KRTac

3

대용 키를 사용하도록 선택했습니다. 즉, 애플리케이션의 비즈니스 데이터의 일부가 아닌 키. 레코드 당 최대 50KB의 텍스트를 처리 할 때 추가적인 64 비트 정수의 추가 공간 요구 사항은 무시할 수 있습니다. 이 키를 다른 테이블에서 외래 키로 사용하기 시작하면 실제로 보다 작은 공백을 사용하게됩니다.

레코드에 저장된 데이터의 해시를 사용하면 해시가 기반으로하는 데이터가 변경되면 기본 키가 매우 나쁜 후보가됩니다. 그런 다음 기본 키를 변경하여 다른 테이블에서이 테이블로의 관계가있는 경우 모든 곳에서 업데이트합니다.

추신. 비슷한 질문이 제기되어 여기 before에 응답되었습니다.

여기에 주제에 대한 또 다른 좋은 쓰기까지입니다 : http://www.agiledata.org/essays/keys.html

+0

큰 충고, 그리고 나는 그것의 대부분에 동의합니다. 그러나 이전에 언급했듯이 surogat 키가 2147483647에 도달하면 어떻게됩니까? bigserial을 사용할 수는 있지만 그 성능은 무엇입니까? – KRTac

+0

이 컨텍스트 (블로그 게시물 및 뉴스 기사 저장)에서 나는 2^31 개의 항목에 도달 할 가능성이 매우 높습니다. 그럼에도 불구하고 미리 계획을 세우고 안전하게 게임을하고 bigserial을 사용하고 싶다면, 퍼포먼스 히트가 최소가 될 것이라고 말하고 싶습니다. 특히 CHAR (32)를 PK로 사용하는 것에 비해. –

1

기본 키로 일반 32 비트 정수를 사용합니다. 나는 그 숫자를 매우 빨리 초과 할 것이라고 생각하지 않습니다 :-) 전체 Wikipedia에는 ​​약 3 천 5 백만 건의 기사가 있습니다. 하루 1000 건의 기사를 작성하면 정수형의 최대 값에 도달하는 데 약 6000 년이 걸릴 것입니다.

관련 문제