Desain Datawarehouse: Gabungan dimensi Waktu Tanggal vs. Dimensi dan zona waktu Hari dan Waktu terpisah

10

Kami baru memulai desain untuk gudang data baru dan kami mencoba merancang bagaimana dimensi tanggal dan waktu kami akan bekerja. Kami harus dapat mendukung beberapa zona waktu (mungkin setidaknya GMT, IST, PST, dan EST). Kami awalnya berpikir bahwa kami akan memiliki satu dimensi waktu tanggal gabungan yang luas hingga mungkin 15 menit, dengan begitu kami memiliki satu kunci dalam tabel fakta kami dan semua data waktu tanggal yang berbeda untuk semua zona waktu yang didukung berada dalam tabel satu dimensi. (yaitu Kunci Tanggal, Tanggal GMT, Waktu GMT, Tanggal IST, Waktu IST, dll ...)

Kimball menyarankan untuk memiliki dimensi hari yang terpisah dari dimensi hari untuk mencegah tabel tumbuh terlalu besar (Toolkit data warehouse hal. 240) yang kedengarannya baik namun itu berarti kita memiliki dua kunci dalam tabel fakta untuk setiap zona waktu kita perlu mendukung (satu untuk tanggal dan satu untuk waktu hari).

Karena saya sangat tidak berpengalaman dalam bidang ini, saya berharap seseorang di luar sana tahu pertukaran antara kedua pendekatan, yaitu kinerja vs. pengelolaan semua kunci zona waktu yang berbeda. Mungkin ada pendekatan lain juga, saya telah melihat beberapa orang berbicara tentang memiliki baris terpisah di tabel fakta per zona waktu, tapi itu sepertinya masalah jika tabel fakta Anda adalah jutaan baris maka Anda perlu melipatgandakannya untuk menambah zona waktu .

Jika kita melakukan butiran 15 menit, kita akan memiliki baris 131.400 (24 * 15 * 365) per tahun dalam tabel dimensi waktu tanggal kita yang kedengarannya tidak terlalu mengerikan untuk kinerja tetapi kita tidak akan tahu pasti sampai kita menguji beberapa pertanyaan prototipe. Kekhawatiran lain dengan memiliki kunci zona waktu yang terpisah di tabel fakta adalah bahwa kueri harus bergabung dengan tabel dimensi ke kolom berbeda berdasarkan zona waktu yang diinginkan, mungkin ini adalah sesuatu yang SSAS urus untuk Anda, saya tidak yakin .

terima kasih atas pemikiran, -Matt

Matt Palmerlee
sumber
1
Pertanyaan ini juga ada di Stack Overflow: stackoverflow.com/questions/2507289/… .
Jon of All Trades

Jawaban:

5

Dengan memisahkan tanggal dan waktu, Anda dapat melakukan agregat berdasarkan waktu dengan lebih mudah. untuk eg: jika Anda ingin menjalankan kueri untuk menemukan periode waktu apa yang paling sibuk. Ini lebih mudah dilakukan menggunakan dimensi waktu yang terpisah.

Juga, Anda hanya perlu memiliki satu timekey. Tentukan waktu GMT / EST - lalu gunakan ini di tabel fakta. Jika Anda perlu menjalankan laporan berdasarkan zona waktu lain, cukup konversikan dalam aplikasi atau kueri Anda.

Dharmendar Kumar 'DK'
sumber
Ok, itu masuk akal, para pengguna tidak dapat mengelompokkan data kemudian berdasarkan zona waktu mereka, tapi itu mungkin sesuatu yang kita bisa hidup tanpanya untuk menyederhanakan desain.
Matt Palmerlee
@MattPalmerlee: Pengguna dapat mengelompokkan berdasarkan zona waktu jika Anda memberikannya kepada mereka. Saya biasanya memasukkannya ke dalam Geographytabel, tetapi jika tidak ada yang berlaku, Anda dapat menambahkannya sebagai atribut dari tabel fakta Anda.
Jon of All Trades
5

Hanya tindak lanjut tentang bagaimana kami memutuskan untuk mengimplementasikan DataWarehouse kami untuk mendukung beberapa Zona Waktu dan menjadi seefisien mungkin: Kami memilih untuk membuat tabel zona waktu (id, nama, dll ...) serta "Zona Waktu" tabel "jembatan yang terlihat seperti ini:

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

Dengan cara ini kita dapat menjaga tabel dimensi tanggal dan waktu normal kita kecil, semua fakta kita terhubung ke kunci tanggal / waktu UTC, maka jika kita perlu melaporkan / mengelompokkan berdasarkan zona waktu yang berbeda kita hanya perlu bergabung melalui tabel jembatan zona waktu dan tautkan kunci tanggal / waktu lokal kembali ke tabel dimensi tanggal dan waktu. Kami mengisi tabel jembatan zona waktu kami menggunakan kode C # yang dipanggil dari SSIS karena ini jauh lebih mudah daripada melakukan hal-hal TZ dari SqlServer secara langsung.

Matt Palmerlee
sumber
Saya juga berpikir solusi Anda mungkin paling masuk akal tanpa masuk ke sesuatu yang terlalu rumit. Saya menguji DW saya menggunakan tabel timeZone dan TimeZoneBridge mirip dengan Anda. Ini juga memiliki tabel TimeDimension dan DateDimension. Saya membuat indeks berkerumun pada date_key_local, time_key_local, dan timezone_id, sehingga menerjemahkan waktu lokal ke waktu UTC menggunakan TimeZoneBridge akan lebih cepat.
dsum
1
Kunci clustered utama kami untuk tabel jembatan adalah pada kolom tanggal / waktu utc + id zona waktu (jika saya ingat dengan benar), karena semua kunci waktu tabel fakta akan berada di utc, Anda akan bergabung ke jembatan melalui utc kunci + tz id, mungkin lebih baik untuk memiliki indeks berkerumun pada mereka. Lakukan apa yang masuk akal untuk kebutuhan Anda. Saya senang jawaban saya membantu seseorang, saya pikir itu adalah pendekatan yang baik dan dari semua pengujian kami, itu masih cukup cepat, hanya berhati-hati ketika datang ke klausa WHERE: menyaring rentang tanggal yang Anda inginkan sedini mungkin dalam permintaan Anda.
Matt Palmerlee
Apakah ini hanya berisi seluruh tanggal? Atau jika Anda memiliki nilai 86000 "kunci tanggal / waktu" di tabel fakta Anda, tabel jembatan akan memiliki 86.000 baris * n zona waktu yang didukung, dan itu hanya untuk satu hari saja?
Aaron Bertrand
1
mungkin Anda dapat menambahkan definisi tabel persis yang Anda miliki, sehingga pembaca dapat melihat kendala utama dan unik.
ypercubeᵀᴹ
@ AaronBertrand itu tergantung pada butiran (atau granularitas yang Anda pilih) untuk melacak data Anda di, dalam kasus kami, kami hanya memerlukan granularitas 15 menit di tabel fakta kami sehingga hanya 4 * 24 = 96 catatan per hari per zona waktu yang ingin kami dukung, yang sepenuhnya masuk akal.
Matt Palmerlee
2

Saya telah melihat gagasan tentang gudang menggunakan DateTimedimensi gabungan ditolak, tetapi saya belum melihat alasan yang sangat jelas mengapa. Sederhananya sedikit, inilah tabel fakta yang saya bangun sekarang:

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
)

DateTimeBidang - bidang bergabung dengan tabel 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)),
...
)

Ini adalah resolusi setengah jam, jadi ada 48 catatan per hari, 350.400 dalam 20 tahun - cukup mudah dikelola.

Tanggal / waktu acara diterjemahkan ke UTC saat disimpan, tetapi dengan LocalTimeZoneSKbidang dan tabel jembatan kita dapat dengan mudah bergabung untuk mendapatkan waktu setempat:

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

Untuk mendapatkan transaksi yang dibuat hari ini, waktu UTC:

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

Untuk mendapatkan transaksi yang dibuat hari ini, pada waktu setempat untuk transaksi:

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'

Anda mungkin tergoda untuk menyederhanakan hal-hal dengan mengganti TimeZoneSKdengan REALoffset (mis., -5,0 untuk Waktu Siang Tengah AS), tetapi ini akan rusak jika beberapa tanggal / waktu untuk catatan fakta dalam Waktu Hemat Siang hari dan ada yang tidak.

Jika peristiwa untuk catatan fakta dapat terjadi di zona waktu yang berbeda, seperti pengiriman atau penerbangan, maka Anda memerlukan bidang zona waktu untuk setiap tanggal, dan Anda hingga lima byte per tanggal.

Jon dari Semua Perdagangan
sumber
Itu pendekatan kreatif. Namun, seperti yang Anda katakan Anda hanya akan memiliki 350.400 baris dalam tabel redup gabungan datetime Anda, jika Anda mulai mengubah butir ke resolusi yang lebih halus, Anda akan dengan cepat masuk ke jutaan catatan. Jika Anda memilih untuk memiliki dimensi tanggal yang terpisah dari dimensi waktu, Anda hanya memiliki 48 baris dalam tabel dimensi waktu Anda dan hanya 365 baris per tahun dalam tabel dimensi tanggal Anda (atau 7300 baris dalam 20 tahun). Tabel fakta Anda kemudian memiliki kolom untuk date_key dan time_key. Ini juga membuatnya lebih fleksibel jika Anda memiliki beberapa tabel fakta yang hanya memerlukan granularity tanggal.
Matt Palmerlee
1
Satu juta baris dalam dimensi tidak menjadi perhatian saya - data hanya diubah sekali dalam satu dekade, dan indeks penutup pada PK dan dua atau tiga bidang yang paling sering digunakan akan memakan jumlah server RAM yang sepele. Namun, menambahkan setengah lusin SMALLINTke tabel fakta satu baris baris adalah 12 GB plus overhead, dan sekarang Anda berbicara uang nyata. Untuk tanggal yang hanya perlu menyimpan tanggal, tentu saja Anda dapat mengarahkannya ke catatan "00:00" untuk tanggal yang sesuai.
Jon of All Trades