데이터웨어 하우스 디자인 : 결합 된 날짜 시간 차원 대 별도의 요일 및 시간 차원 및 시간대


10

새로운 데이터웨어 하우스를위한 디자인을 시작하고 있으며 날짜 및 시간 차원의 작동 방식을 디자인하려고합니다. 여러 시간대 (아마도 GMT, IST, PST 및 EST)를 지원할 수 있어야합니다. 우리는 처음에 15 분의 세분화까지 하나의 넓은 결합 날짜 시간 차원을 가질 것이라고 생각했습니다. 이렇게하면 팩트 테이블에 하나의 키가 있고 지원되는 모든 시간대에 대한 모든 다른 날짜 시간 데이터가 하나의 차원 테이블에 있습니다. (예 : 날짜 키, GMT 날짜, GMT 시간, IST 날짜, IST 시간 등)

Kimball은 테이블이 너무 커지는 것을 방지하기 위해 시간 차원과 별도의 일 차원을 가질 것을 제안합니다 (데이터웨어 하우스 툴킷 p. 240). 우리는 지원해야합니다 (하나는 날짜와 하나는 시간).

내가이 분야에서 매우 경험이 없기 때문에 누군가가 두 가지 접근 방식, 즉 다른 표준 시간대 키의 성능과 관리 간의 상충 관계를 알고 있기를 바랍니다. 어쩌면 다른 접근법도있을 수 있습니다. 시간대마다 팩트 테이블에 별도의 행을 갖는 것에 대해 이야기하는 사람들이 있지만 실제로 팩트 테이블이 수백만 행이면 시간대를 추가하기 위해 4 배로 늘려야하는 것처럼 보입니다. .

우리가 15 분 곡물을 수행하면 날짜 시간 차원 테이블에 연간 131,400 (24 * 15 * 365) 행이있어 성능이 너무 무섭지 않지만 테스트 할 때까지 확실하지 않습니다. 프로토 타입 쿼리. 팩트 테이블에 별도의 표준 시간대 키가있는 다른 문제는 쿼리가 원하는 표준 시간대를 기준으로 차원 테이블을 다른 열에 조인해야한다는 것입니다. 아마도 SSAS가이를 처리하는 것일 수도 있습니다. 확실하지 않습니다. .

어떤 생각에 감사합니다, -Matt


1
이 질문은 Stack Overflow : stackoverflow.com/questions/2507289/… 에도 있습니다 .
Jon의 모든 거래

답변:


5

날짜와 시간을 분리하면 시간별로 집계를 훨씬 쉽게 수행 할 수 있습니다. 예를 들어, 하루 중 가장 바쁜 시간대를 찾기 위해 쿼리를 실행하려는 경우. 이것은 별도의 시간 차원을 사용하여 훨씬 쉽게 수행됩니다.

또한 하나의 타임 키가 있어야합니다. GMT / EST 시간을 결정한 다음 팩트 테이블에서이를 사용하십시오. 다른 시간대를 기준으로 보고서를 실행해야하는 경우 응용 프로그램이나 쿼리에서 변환하십시오.


좋습니다. 사용자는 시간대를 기준으로 데이터를 그룹화 할 수 없지만 디자인을 단순화하기 위해 우리가 살 수없는 것일 수도 있습니다.
매트 팔 머리

@MattPalmerlee : 사용자가 시간대를 지정하면 시간대별로 그룹화 할 수 있습니다. 일반적으로 Geography테이블에 포함 시키지만, 해당 사항이 없으면 팩트 테이블의 속성으로 추가 할 수 있습니다.
Jon의 모든 거래

5

여러 표준 시간대를 지원하고 가능한 효율적으로 DataWarehouse를 구현하기로 결정한 방법에 대한 후속 조치 : "표준 시간대뿐만 아니라 표준 시간대 테이블 (ID, 이름 등)을 작성하기로 선택했습니다. 브리지 "테이블은 다음과 같습니다.

time_zone_bridge
---------------
date_key_utc
time_key_utc
timezone_id
date_key_local
time_key_local

이렇게하면 일반적인 날짜 및 시간 차원 테이블을 작게 유지할 수 있으며 모든 사실은 UTC 날짜 / 시간 키에 연결됩니다. 다른 시간대로보고 / 그룹화 해야하는 경우 시간대 브리지 테이블을 통해 조인해야합니다. 로컬 날짜 / 시간 키를 날짜 및 시간 차원 테이블에 다시 연결하십시오. SSIS에서 호출 된 C # 코드를 사용하여 표준 시간대 브리지 테이블을 채 웁니다. 이는 SqlServer에서 직접 TZ 작업을 수행하는 것보다 훨씬 덜 복잡하기 때문입니다.


또한 귀하의 솔루션이 너무 복잡하게 들어 가지 않고 아마도 가장 합리적이라고 생각합니다. timeZone 테이블과 TimeZoneBridge를 사용하여 DW를 테스트하고 있습니다. 또한 TimeDimension 및 DateDimension 테이블이 있습니다. date_key_local, time_key_local 및 timezone_id에 클러스터형 인덱스를 만들었으므로 TimeZoneBridge를 사용하여 현지 시간을 UTC 시간으로 변환하는 것이 빠릅니다.
dsum

1
브리지 테이블의 기본 클러스터 키는 utc 날짜 / 시간 열 + 시간대 ID (정확히 기억하는 경우)에 있습니다. 모든 팩트 테이블 시간 키는 utc에 있기 때문에 utc를 통해 브리지에 합류하게됩니다 키 + tz id를 사용하면 클러스터형 인덱스를 사용하는 것이 좋습니다. 그래도 필요에 맞는 것을하십시오. 나는 내 대답이 누군가를 도왔 기 때문에 기쁘다. 나는 그것이 좋은 접근법이라고 생각한다. 그리고 우리의 모든 테스트에서, 여전히 합리적으로 빠르다 .WHERE 절에 관해서 조심하십시오 : 원하는 날짜 범위를 필터링하십시오. 당신의 쿼리에서 가능합니다.
매트 팔 머리

여기에는 전체 날짜 만 포함됩니까? 또는 팩트 테이블에 86000 "날짜 / 시간 키"값이있는 경우 브릿지 테이블에는 86000 개의 행 * n 개의 지원되는 시간대가 있으며 그 날에만 해당됩니까?
Aaron Bertrand

1
정확한 테이블 정의를 추가하여 독자가 기본 고유 제한 조건을 볼 수 있습니다.
ypercubeᵀᴹ

@AaronBertrand는 데이터를 추적하기 위해 결정 (또는 선택한 단위)에 따라 달라집니다.이 경우 팩트 테이블에는 15 분 단위 만 필요하므로 지원하려는 시간 대당 하루에 4 * 24 = 96 개의 레코드 만 있으면됩니다. 그것은 완전히 합리적입니다.
매트 팔 머리

2

결합 된 DateTime차원이 거부 된 창고에 대한 아이디어는 거부되었지만 그 이유를 알 수 없었습니다. 약간 단순화하면 다음은 현재 구축중인 팩트 테이블입니다.

Transactions
(
...
CreatedDateTimeSK         INT NOT NULL,  -- Four bytes per date...
AuthorizedDateTimeSK      INT NOT NULL,
BatchSubmittedDateTimeSK  INT NOT NULL,
BatchApprovedDateTimeSK   INT NOT NULL,
SettlementDateTimeSK      INT NOT NULL,
LocalTimeZoneSK           TINYINT NOT NULL  -- ...plus one byte for the time zone
)

DateTime필드는 날짜 시간 테이블에 조인

DateTimes
(
DateTimeSK   INT NOT NULL PRIMARY KEY,
SQLDate      DATE NOT NULL,
SQLDateTime  DATETIME2(0) NOT NULL,
Year         SMALLINT NOT NULL,
Month        TINYINT NOT NULL,
Day          TINYINT NOT NULL,
Hour         TINYINT NOT NULL,
Minute       TINYINT NOT NULL CHECK (Minute IN (0, 30)),
...
)

이것은 30 분의 1 초의 해상도로 하루에 48 개의 레코드, 20 년 동안 350,400 개의 레코드가 있습니다.

이벤트 날짜 / 시간은 저장 될 때 UTC로 변환되지만 LocalTimeZoneSK필드와 브리지 테이블을 사용하면 현지 시간을 얻기 위해 쉽게 조인 할 수 있습니다.

TimeZoneBridge
(
DateTimeSK       INT NOT NULL,
TimeZoneSK       TINYINT NOT NULL,
PRIMARY KEY (DateTimeSK, TimeZoneSK),
LocalDateTimeSK  INT NOT NULL
)

오늘 UTC로 생성 된 트랜잭션을 가져 오려면 다음을 수행하십시오.

SELECT COUNT(*)
FROM Transactions AS T
  INNER JOIN DateTimes AS CD ON T.CreatedDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'

거래를 위해 현지 시간으로 오늘 거래를 만들려면 :

SELECT COUNT(*)
FROM Transactions AS T
  INNER JOIN TimeZoneBridge AS TZB ON T.CreatedDateTimeSK = TZB.DateTimeSK AND T.TimeZoneSK = TZB.TimeZoneSK
  INNER JOIN DateTimes AS CD ON TZB.LocalDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'

당신은 대체하여 단순화 것들에 유혹 할 수있다 TimeZoneSKREAL오프셋 (예를 들어, -5.0 미국 중부 일광 절약 시간에 대한)하지만, 사실 레코드의 일부 날짜 / 시간이 일광 절약 시간에 일부가 아닌 경우이 분해됩니다.

팩트 레코드에 대한 이벤트가 선적 또는 항공편과 같은 다른 시간대에서 발생할 수있는 경우 각 날짜에 대한 시간대 필드가 필요하며 날짜 당 최대 5 바이트입니다.


창의적인 접근 방식입니다. 그러나 결합 된 datetime dim 테이블에 350,400 개의 행 만 있다고 말하지만 곡물을 더 정밀한 해상도로 변경하기 시작하면 수백만 개의 레코드를 빠르게 얻을 수 있습니다. 시간 차원과 다른 날짜 차원을 선택하면 시간 차원 테이블에는 48 행만 있고 날짜 차원 테이블에는 연간 365 행 (20 년 동안 7300 행) 만 있습니다. 팩트 테이블에는 단순히 date_key 및 time_key에 대한 열이 있습니다. 또한 날짜 단위 만 요구하는 팩트 테이블이있는 경우 더욱 유연합니다.
매트 팔 머리

1
차원의 백만 행은 저와 관련이 없습니다. 데이터는 10 년에 한 번만 변경되며 PK와 2 ~ 3 개의 가장 많이 사용되는 필드의 커버링 인덱스는 사소한 양의 서버 RAM을 차지합니다. 그러나 SMALLINT10 억 행에 이르는 팩트 테이블에 수십 s를 추가하는 것은 12GB에 오버 헤드가 더해 지므로 이제 실제 돈을 사용하고 있습니다. 날짜 만 저장해야하는 날짜의 경우 적절한 날짜의 "오전 12시"레코드를 가리킬 수 있습니다.
모든 거래의 존
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.