Bonnes pratiques sur la dimension temps
J’ai publié récemment un post qui décrit la création d’une dimension temps.
Je vous propose de passer à présent en revue quelques bonnes pratiques de la dimension temps.
Il est important d’avoir des dimensions temps complètes, même si il n’y a pas de mesures pour ces valeurs de dates.
En effet, certaines fonctions MDX comme la fonction ParallelPeriod() retourne des positions relatives.
Ainsi si on souhaite comparer des valeurs au niveau mois par rapport à l’année N-1, si l’année n’est pas complète les calculs risquent d’être faux.
Ainsi dans l’exemple ci-dessous, la position 1 pour le niveau mois dans l’année 2001 est le mois de juillet, tandis que c’est bien le mois de janvier pour l’année 2002.
Il est une bonne pratique de créer une table pour une dimension temps.
Ainsi, il est possible d’enrichir cette dernière avec des données spécifiques au contexte de l’entité.
Cette démarche permet de répondre aux questions suivantes :
- Est-ce un jour de congés spécifique à l’entreprise ?,
- Sommes-nous en saison-hors saison ?
Si l’application doit restituer des données à un niveau plus fin que le jour, il est pertinent d’avoir deux dimensions, une au niveau du jour et une au niveau des horaires.
Par exemple, si nous traçons temps avec une hiérarchie utilisateur suivante
Year à Quarter à Month à Week à Day à Hour à Minute.
Pour cinq ans d’historique, nous aurions 2675,795 membres.
Il est préférable de créer deux dimensions avec les hiérarchies suivantes :
Time: Year à Quarter à Month à Week à Day
Time of Day: Period à Hour à Minute
(Les valeurs prises pour la période peuevent être Hors heure de travail, matin, après-midi,…)
Décrivons le code qui permet de créer et d’alimenter une table de dimension au niveau horaire, DimTime
drop table DimTime
GO
create table DimTime
([TimeKey] [int] identity NOT NULL,
[HourNumber] [tinyint] NOT NULL,
[MinNumber] [tinyint] NOT NULL,
[SecondNumber] [tinyint] NOT NULL,
[Periode] nvarchar(255) NULL,
CONSTRAINT [PK_DimTime_TimeKey] PRIMARY KEY CLUSTERED
(
[TimeKey] ASC
))
GO
create procedure FillDimTime
as
--truncate table dbo.DimTime
set nocount on
declare @Hour int;
declare @Min int;
declare @sec int;
declare @MaxHour int;
declare @MaxMin int;
declare @Maxsec int;
set @Hour = 0;
set @Min = 0;
set @sec = 0;
set @MaxHour = 23;
set @MaxMin = 59;
set @Maxsec = 59;
while @Hour <= @MaxHour --boucle sur les Heures
begin
while @Min <= @MaxMin --boucle sur les min
begin
While @sec <= @Maxsec --boucle sur les secondes
begin
insert into DimTime (HourNumber, MinNumber, SecondNumber) values (@Hour,@Min,@sec);
set @sec = @sec + 1;
end
set @Min = @Min + 1;
set @sec = 0
--insert into DimTime (HourNumber, MinNumber, SecondNumber) values (@Hour,@Min,@sec);
end
set @Hour = @Hour + 1;
set @sec = 0
set @Min = 0
--insert into DimTime (HourNumber, MinNumber, SecondNumber) values (@Hour,@Min,@sec);
end
update DimTime
set Periode = 'AM'
where HourNumber between 0 and 11
update DimTime
set Periode = 'PM'
where HourNumber between 12 and 23
GO
Et voila le résultat