매우 다른 키로 키-값 쌍 세트를 효율적으로 저장


9

다양한 유형의 활동을 사이트와 연결하는 응용 프로그램을 상속했습니다. 대략 100 개의 서로 다른 활동 유형이 있으며 각 활동 유형에는 3-10 개의 필드가 다릅니다. 그러나 모든 활동에는 하나 이상의 날짜 필드 (날짜, 시작 날짜, 종료 날짜, 예정된 시작 날짜 등의 조합 일 수 있음)와 하나의 책임자 필드가 있습니다. 다른 모든 필드는 매우 다양하며 시작 날짜 필드는 반드시 "시작 날짜"라고 할 필요는 없습니다.

각 활동 유형마다 하나의 부속 유형 테이블을 작성하면 100 개의 서로 다른 부속 유형 테이블이있는 스키마가 생성되므로 처리하기가 너무 어려워집니다. 이 문제점에 대한 현재 솔루션은 활동 값을 키-값 쌍으로 저장하는 것입니다. 이것은 현재 시스템의 요점을 쉽게 이해할 수있는 스키마입니다.

여기에 이미지 설명을 입력하십시오

각 활동에는 여러 개의 ActivityField가 있습니다. 각 사이트에는 여러 활동이 있으며 SiteActivityData 테이블은 각 SiteActivity에 대한 KVP를 저장합니다.

이렇게하면 (웹 기반) 응용 프로그램을 매우 쉽게 코딩 할 수 있습니다. 실제로 필요한 것은 지정된 활동에 대해 SiteActivityData의 레코드를 반복하고 각 행의 레이블 및 입력 제어를 양식에 추가하기 때문입니다. 그러나 많은 문제가 있습니다.

  • 무결성은 나쁘다. 활동 유형에 속하지 않는 필드를 SiteActivityData에 넣을 수 있으며 DataValue는 varchar 필드이므로 숫자와 날짜를 지속적으로 캐스트해야합니다.
  • 이 데이터의보고 및 임시 쿼리는 어렵고 오류가 발생하기 쉽고 속도가 느립니다. 예를 들어, 지정된 범위 내에 종료 날짜가있는 특정 유형의 모든 활동 목록을 가져 오려면 피벗 및 varchar를 날짜로 캐스트해야합니다. 보고서 작성자는이 스키마를 싫어하고 비난하지 않습니다.

그래서 내가 찾고있는 것은보고를 쉽게하는 방식으로 거의 공통점이없는 많은 활동을 저장하는 방법입니다. 내가 지금까지 생각해 낸 것은 XML을 사용하여 활동 데이터를 의사 noSQL 형식으로 저장하는 것입니다.

여기에 이미지 설명을 입력하십시오

활동 테이블에는 각 활동에 대한 XSD가 포함되므로 ActivityField 테이블이 필요하지 않습니다. SiteActivity는 키-값 XML을 포함하므로 사이트의 각 활동이 이제 단일 행에있게됩니다.

액티비티는 다음과 같이 보일 것입니다 (그러나 나는 그것을 완전히 이해하지 못했습니다).

<SomeActivityType>
  <SomeDateField type="StartDate">2000-01-01</SomeDateField>
  <AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
  <EmployeeId type="ResponsiblePerson">1234</EmployeeId>
  <SomeTextField>blah blah</SomeTextField>
  ...

장점 :

  • XSD는 XML을 검증하여 데이터베이스 수준의 숫자 필드에 문자열을 넣는 것과 같은 오류를 포착합니다. varchar에 모든 것을 저장 한 이전 스키마로는 불가능했습니다.
  • 웹 양식을 작성하는 데 사용되는 KVP 레코드 세트를 사용하여 쉽게 재현 할 수 있습니다. select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
  • XML의 xpath 서브 쿼리는 피벗을 사용하지 않고 시작 날짜, 종료 날짜 등에 대한 열이있는 결과 세트를 생성하는 데 사용될 수 있습니다. select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...

이것이 좋은 생각처럼 보입니까? 다른 많은 속성 집합을 저장하는 다른 방법을 생각할 수 없습니다. 내가 가진 또 다른 생각은 기존 스키마를 유지하고 데이터웨어 하우스에서 더 쉽게 쿼리 할 수있는 것으로 변환하는 것이었지만, 이전에는 스타 스키마를 설계 한 적이 없으며 어디서부터 시작해야할지 전혀 몰랐습니다.

추가 질문 :을 사용하여 XSD에 날짜 데이터 유형이있는 것으로 태그를 정의하면 xs:dateSQL Server가 태그를 날짜 값으로 색인화합니까? 날짜별로 쿼리하면 날짜 문자열을 날짜 값으로 캐스팅하고 색인을 사용할 가능성을 날려야합니다.


보고서의 데이터는 얼마나 최신 상태 여야합니까? 보고서가 생산에 타격을 줄까요?
제임스 앤더슨

대부분의 보고서는 현재 데이터웨어 하우스에 영향을 미칩니다 (실제로 DW는 아니지만 기본적으로 다른 데이터베이스의 뷰와 테이블이 추가 된 프로덕션 트랜잭션 스키마의 복사본 임). 날짜가 지난 보고서를 갖는 것은 허용되지만, 그것이 가능하다면 보너스가 될 것입니다.
Paul Abbott

필드에 겹치는 부분이 얼마나됩니까? 10 개의 필드가 100 개의 하위 유형을 모두 포함합니까? 또는 500 개의 완전히 다른 필드가 있습니까?
Jon의 모든 거래

72 개의 필드와 75 개의 활동 유형이 있습니다. 30 개의 필드는 하나의 활동 만 사용하고 나머지는 5-10 개의 활동이 사용합니다. ~ 30 개의 서로 다른 활동에 사용되는 소수의 필드가 있습니다. 대부분의 경우 활동 전반에 걸쳐 공통점이 많지 않습니다.
Paul Abbott

답변:


7

그래서 내가 찾고있는 것은보고를 쉽게하는 방식으로 거의 공통점이없는 많은 활동을 저장하는 방법입니다.

먼저 언급 할 담당자가 충분하지 않으므로 여기로 이동하십시오!

기본 목적이보고이고 DW가있는 경우 (스타 스키마가 아니더라도)이를 스타 스키마로 가져 오는 것이 좋습니다. 장점은 빠르고 간단한 쿼리입니다. 단점은 ETL이지만 이미 데이터를 새로운 디자인으로 옮기고 ETL을 스타 스키마로 옮기는 것이 XML 래퍼 솔루션보다 구축 및 유지 관리가 더 간단 할 것입니다 (SSIS는 SQL Server 라이센스에 포함되어 있음). 또한 인식 된보고 / 분석 설계 프로세스를 시작합니다.

그렇게하는 방법 ... 사실없는 사실이 있는 것 같습니다 . 이는 연관된 측정 값이없는 이벤트 (예 : 판매 가격)를 정의하는 속성의 교차입니다. 일부 또는 모든 활동에 대해 날짜가 있습니까? 아마도 활동, 사이트 및 날짜가 교차해야합니다.

DimActivity-적어도 패턴을 공유하는 열로 나눌 수있는 패턴이 있다고 생각합니다. 그렇다면 세 가지가 있습니까? 다섯? 활동 클래스의 차원. 최악의 경우 활동 이름과 같은 몇 가지 일관된 열이 있으며 필터링 할 수 있으며 나머지 임의의 세부 정보에 대해서는 "Attribute1"과 같은 일반 제목을 남겨 둡니다.

차원의 모든 것이 필요하지는 않습니다. 활동 차원에 날짜가 없어야 합니다. 대리 키 가 날짜 차원을 참조 하므로 모두 사실이어야 합니다. 예를 들어, 사람 차원에 머무르는 날짜는 사람의 속성이므로 생년월일이됩니다. 병원 방문 날짜는 무엇보다 사람과 관련된 특정 시점 이벤트이기 때문에 사실이지만, 병원을 방문하는 사람의 속성이 아닙니다. 사실 더 많은 날짜 토론.

DimSite-똑바로 보이므로 여기에 대리 키를 설명하겠습니다. 본질적으로 이것은 증가하는 고유 ID입니다. 정수 ID 열이 일반적입니다. 이를 통해 DW와 소스 시스템을 분리하고 데이터웨어 하우스에서 최적의 결합을 보장 할 수 있습니다. Natural Key 또는 Business Key는 일반적으로 유지되지만 유지 관리 / 디자인에는 분석 및 조인이 아닙니다. 스키마 예 :

CREATE TABLE [DIM].[Site]
(
 SiteSK INT NOT NULL IDENTITY PRIMARY KEY
,SiteNK INT NOT NULL --source system key
,SiteName VARCHAR(500) NOT NULL
)

DimDate-날짜 속성. 아이디 대신 "스마트 키"를 만드십시오. 이는 WHERE DateSK = 20150708과 같은 쿼리 날짜와 관련된 의미있는 정수를 입력 할 수 있음을 의미합니다. DimDate를로드 할 수있는 무료 스크립트가 많이 있으며이 스마트 키가 대부분 포함되어 있습니다. ( 하나의 옵션 )

DimEmployee -DimPerson에 대한 일반적인 변경 사항 인 경우 XML에이 정보가 포함되어 있으며보고 가능하고 관련있는 사람 특성을 작성합니다.

그리고 당신의 사실은 :

FactActivitySite
DimSiteSK - FK to DimSite
DimActivitySK - FK to DimActivity
DimEmployee - FK to DimEmployee
DimDateSK - FK to DimDate

팩트에서 이름을 바꿀 수 있으며 이벤트 당 여러 개의 날짜 키를 가질 수 있습니다. 사실은 일반적으로 매우 커서 업데이트를 피하는 것이 좋습니다. 단일 이벤트에 여러 날짜 업데이트가있는 경우 "업데이트"행을 선택할 수있는 사실에 SK를 추가하여 삭제 / 삽입 디자인을 시도 할 수 있습니다. 삭제 한 다음 최신 데이터를 삽입하십시오.

팩트 날짜를 필요한 곳으로 확장하십시오 StartDateSK, EndDateSK, ScheduledStartDateSK.

모든 차원에는 일반적으로 하드 코딩 된 -1 SK가있는 알 수없는 행이 있어야합니다. 팩트를로드 할 때 활동에 포함 된 날짜가 없으면 단순히 -1을로드해야합니다.

사실은 차원에 저장된 속성에 대한 정수 참조 모음이며, 결합하여 매우 상세한 조인 패턴으로 모든 세부 정보를 얻을 수 있으며 데이터 유형으로 인해 매우 작고 빠릅니다. SQL Server에 있으므로 성능을 더 높이려면 열 저장소 인덱스 를 추가하십시오. ETL 중에이를 삭제하고 다시 빌드 할 수 있습니다. SQL 2014+에 도달하면 columnstore 인덱스에 쓸 수 있습니다.

여기에 이미지 설명을 입력하십시오

이 경로를 사용하면 차원 모델링을 연구하십시오. Kimball 방법론을 추천 합니다. 무료 가이드도 많이 있지만, 이것이 오프 오프 솔루션 이외의 것이면 투자 가치가 있습니다.


(wesdev의 질문) : @Dave, 어떤 ERD 도구를 사용 했습니까?
ypercubeᵀᴹ

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