다음 중 어떤 테이블 디자인이 성능에 더 좋습니까?


16

계정에서 수집하는 일일 비용을 추적하는 무언가를 작성하라는 요청을 받았으며이를 지원하는 데이터베이스 테이블 스키마를 알아 내려고 노력 중입니다.

내가 아는 것은 다음과 같습니다

  • 회사는 250 만 개가 넘는 계정을 보유하고 있습니다.
  • 이 중 현재 월 평균 200,000 명의 직원이 근무하고 있습니다 (현재 직원 수에 따라 변경됨).
  • 그들은 추적하고 싶은 13 가지의 다른 비용 유형을 가지고 있으며, 앞으로 더 많은 것을 추가 할 것이라고 경고했습니다.
  • 그들은 매일 비용을 추적하기를 원합니다
  • 비용은 전체 재고에 분할되지 않습니다. 월 단위로 작동하는 계정 수 (200,000)로 분할되거나 사용자가 계정 식별자를 입력하여 계정 그룹에 비용을 적용하거나 단순히 비용을 적용 할 계정을 지정할 수 있습니다.

내 첫 번째 생각은 표준화 된 데이터베이스였습니다.

계정 ID
데이트
CostTypeId
양

이것에 대한 나의 문제는 수학을하는 것입니다. 이 테이블은 빠르게 커질 것입니다. 현재 한 달 동안 모든 13 개의 비용 유형이 모든 작업 계정에 적용된다고 가정하면 200k * 13 * N days in month, 이는 한 달에 약 7 천 8 백만에서 8 천만 건에 달하거나 매년 10 억 건에 가까운 레코드입니다.

내 두 번째 생각은 그것을 비정규 화하는 것이 었습니다

계정 ID
데이트
총비용
비용 유형 1
비용 유형 2
비용 유형 3
비용 유형 4
비용 유형 5
비용 유형 6
비용 유형 7
비용 유형 8
비용 유형 9
비용 유형 10
비용 유형 11
비용 유형 12
비용 유형 13

이 방법은 비정규 화 된 방식으로 한 달에 최대 6 백만 건 ( 200k * N days in month) 또는 연간 약 72 백만 건을 생성 할 수 있습니다 . 첫 번째 방법보다 훨씬 적지 만 향후 회사에서 새로운 비용 유형을 결정하는 경우 다른 데이터베이스 열을 추가해야합니다.

두 가지 방법 중 어느 것을 선호합니까? 왜? 더 잘 처리 할 수있는 다른 대안이 있습니까?

서머 닝 보고서와 상세 보고서 모두 성능보고에 가장 관심이 있습니다. 계정에 비용을 분산시키는 작업은 아무도 없을 때 밤마다 실행됩니다. 두 번째 관심사는 데이터베이스 크기입니다. 기존 데이터베이스는 이미 거의 300GB이며 디스크의 공간은 약 500GB라고 생각합니다.

데이터베이스는 SQL Server 2005입니다


다른 디스크를 가져 오십시오. 디스크는 싸다. 이 문제에 대해 회의 비용으로 2TB를 사용할 수 있습니다.

답변:


9

연간 10 억 레코드는 많지 않습니다.

파티셔닝 (비용 유형별) 및 아카이빙을 통해 관리가 가능합니다.

저장할 데이터 항목의 수는 여전히 200k * 13 * N입니다. 열의 경우 페이지 당 행 수가 줄어들고 행보다 공간이 더 많이 사용됩니다. "CostType1"이 고정 길이 데이터 유형이 아니지만 한계가있는 경우 얻을 수 있습니다.

그들이 말하는 "키스"


3
@Rachel 필자는 데이터 세트가 큰 파티셔닝 스키마를 구현하는 것이 좋습니다. 월별 작업 및보고에 중점을 두는 경우 해당 사고 방식에 맞는 파티션 키를 선택하는 것이 가장 좋습니다. 또한 파티션을 올바르게 구성하면 데이터를 테이블에서 스테이징 테이블로 쉽게 전환 할 수 있으며 데이터를 대량으로로드하고 삭제하는 데 시간이 걸리지 않고 몇 초가 걸리지 않습니다.
David

6

디자인이 밤이나 낮의 차이를 만들 수는 있지만이 경우 필 요에 따라 인덱스를 포함하여 인덱스에 더 중점을 둡니다. 또한 테이블 파티셔닝과 같은 매우 큰 테이블을 처리하기 위해 SQL Server가 제공하는 몇 가지 도구를 살펴 보겠습니다.

테이블에 800 억 개의 레코드가 있지만 적절한 인덱싱을 통해 특정 지점에서 실제로 관심이있는 레코드는 물리적으로 디스크에 그룹화됩니다. SQL Server에서 데이터가 구성되는 방식으로 인해 인덱스 경계로 분할 된 데이터는 전체 테이블을 읽을 필요가 없기 때문에 다른 테이블에도있을 수 있습니다.

테이블을 분할하도록 선택하면 액세스 시간과 삽입 시간을 향상시킬 수 있습니다.


4

나는 정상화 할 것입니다. 우리는 은행에서 고객 계정 수익성에 대한 비용 회계를 수행했으며, 비용 센터 나 총계정 원장 또는 매월 수백만 개의 계정에 대한 다양한 기타 기술에 의해 할당 된 수백 개의 드라이버를 사용하여 250m 이상의 개별 비용을 생성했습니다.

예를 들어 ATM의 총 서비스 비용은 상대적인 사용량에 따라 ATM을 사용한 계정으로 나뉩니다. 따라서 1 백만 달러가 ATM 서비스에 쓰이고 5 명의 고객 만이 각각 한 번만 사용하고 한 고객은 5 번 사용한 경우, 한 고객은 $ .5m, 다른 고객은 각각 $ 1.1m을 지불했습니다. 다른 드라이버는 훨씬 더 복잡 할 수 있습니다.

궁극적으로, 특정 소스 / 드라이버로부터 비용을받지 않는 일부 계정과 아무것도 얻지 못하는 일부 계정은 드물게 발견 될 것입니다. 정규화 된 모델에는 해당 행이 없습니다. 비정규 화 된 모델에서 일부 빈 열이있는 행이 존재합니다. 또한 희소 정규화 된 모델에서는 특정 "버킷"에서 NULL이 아닌 모든 행을 검사하는 것보다 행의 존재가 일반적으로 확인하는 것이 더 빠르기 때문에 (비용 유형의 커버링 인덱스를 사용하여) 성능이 향상되어야합니다. 모든 금액 열의 색인-매우 낭비되기 시작하는 것을 볼 수 있습니다).


스파 스-이것은 모든 차이를 만드는 아주 좋은 점입니다. 드문 경우 정규화하여 공간을 절약합니다. 그렇지 않으면 아닙니다. 그러나 디스크 공간이 저렴하므로 개인적으로 최대한의 유연성 (정규화)에 투표합니다.

3

성능 이점에 관계없이 옵션 1을 선호합니다. 옵션 2는 베드로에게 폴을 지불하기 위해 강탈 할 것이라고 생각합니다.


2

옵션 1을 사용하고보고 속도가 문제가되는 경우 표 2를 추가하고 일종의 자동화 된 야간 / 오프 피크 프로세스로보고 데이터베이스에 채 웁니다.

그런 다음 필요에 따라 일일 테이블 -2 구조를 추가로 매주, 매월, 분기 별, 매년 롤업으로 롤업 할 수도 있습니다.

그러나 내가 말했듯이 '원시'데이터를 적절한 (정규화 된) 형식으로 저장하기로 선택했습니다.


0

언급 한 볼륨을 고려할 때 TotalCost가없는 두 번째 옵션을 사용합니다. 당신은 여전히 ​​정상화되어 있다고 말할 수 있습니다.


편집 : 대안으로, 요구 사항과 AccountId의 크기에 따라 다음을 고려할 수도 있습니다.

AccountDate
-----------
AccountId  
Date  
AcDtID (surrogate key)

Costs
-------
AcDtID
CostTypeId  
Amount  

이 디자인을 사용하면 비정규 화 된 TotalCost를 첫 번째 테이블에 추가하고 야간에 다시 계산하여 첫 번째 테이블에서만 일부 보고서를 실행할 수 있습니다.


나는이 TotalCost보고의 대부분이 요약되어 있기 때문에, 나는 그것을 추가 13 개의 다른 값보다 단일 값을 조회 할 수 빠를 거라 생각 했어요.

아마도, 그러나 당신은 전이 의존성을 실제로 도입합니다. 그 기록들이 업데이트 될까? 또는 방금 쓴 다음 읽기 만합니까?

해당 날짜 범위에 새로운 비용이 적용될 때마다 레코드가 업데이트됩니다. 약 한 달 후에는 총 비용이 업데이트되지는 않지만 연간 지원 비용과 같은 이유로 여전히 가능합니다.

그런 다음 각 업데이트에는 2 개의 업데이트가 필요하며 TotalCost 필드는 불일치의 위험을 추가합니다.

전 이적 의존성이지만 불일치 위험이있는 것은 아닙니다. CHECK () 제약 조건은 TotalCost가 항상 비용의 합계임을 보장 할 수 있습니다.
Mike Sherrill 'Cat

0

하위 쿼리를 사용하고 두 번째 행을 열 또는 여러 열로 선택할 수 있도록 실제로 firs 테이블을 두 개의 테이블로 나눕니다. 그렇게하면 더 유연 해져서 두 번째 것과 같은 결과를 더 쉽게 얻을 수 있습니다.

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