J'ai une dimension (SiteItem) a deux faits importants:
perUserClicks perBrowserClicks
Toutefois, dans cette dimension, j'ai des groupes de valeurs basés sur une colonne d'attributes (appelons les groupes AboveFoldItems, LeftNavItems, OnTheFlyItems, etc.) qui ont chacun plus de faits spécifiques à ce groupe:
AboveFoldItems: eyeTime, loadTime LeftNavItems: mouseOverTime OnTheFlyItems: doesn't have any extra, but may in the future
Le schéma de table de faits suivant est-il correct?
DateKey SessionKey SiteItemKey perUserClicks perBrowserClicks eyeTime loadTime mouseOverTime
Cela semble un peu inutile puisque seules certaines colonnes appartiennent à des keys de dimension (les faits non pertinents sont laissés NUL). Mais … il semble que ce serait un problème commun, alors il devrait y avoir une solution commune, n'est-ce pas?
Je suis généralement d'accord avec la réponse de Damir à ce sujet, mais comme la table des faits est très étroite dans votre cas particulier, il y a toujours lieu de requestr à Aaron de conserver les valeurs NULL.
Nous avons plusieurs schémas en écanvas dans des domaines particuliers avec plusieurs tables de faits qui partagent la plupart (sinon la totalité) des dimensions (conforme et interne). Les dimensions à scope limitée ne sont pas considérées comme «conforms» dans l'set de l'entreprise, mais elles sont ce que nous appelons des dimensions «internes partagées».
Généralement, si datatables sont chargées simultanément pour que la dimension n'ait pas changé, vous pouvez joindre les deux tables de faits sur les keys, mais en général, bien sûr, vous ne pouvez pas joindre deux schémas écanvass différents sur les keys de dimension dans les dimensions traditionnelles qui changent lentement. En général, vous devez joindre des écanvass séparées sur les keys naturelles ou les «keys commerciales» dans la dimension et non sur les substituts (sauf habituellement dans le cas particulier de la dimension de date où elle est immuable et n'a qu'une key naturelle).
Notez que lorsque vous rejoignez les deux écanvass, vous devez utiliser un LEFT JOIN, auquel cas vous allez produire des valeurs nulles dont vous aurez probablement à tenir count – vous revenez donc au model original que vous aviez avec NULLs! 😉
L'avantage de la table de faits supplémentaires est plus évident lorsque vos tables sont larges avec un jeu de keys plus petit et que le partitionnement vertical des données produit un gain d'espace et un model logique plus propre – ceci est particulièrement vrai lorsque les keys sont réellement partagées jusqu'à un certain point – avoir une key factice ou une key NULL n'est certainement pas une bonne idée – cela pointe généralement vers un problème de modélisation dimensionnelle.
Cependant, comme le dit Aaron, si vous le poussez à l'extrême, vous pouvez avoir une seule colonne de faits dans chaque table de faits avec des keys partagées, ce qui signifie que le coût de la key éclipse le coût réel.
Je regarderais aussi pour voir si vous êtes dans la situation de Kimball de "trop peu de dimensions". On dirait que vous devez avoir de bons attributes dimensionnels dans SessionKey et SiteItemKey – mais sans voir votre model et vos exigences, c'est difficile à dire, mais je pense que vous auriez des données démocharts sur les users avec une faible cardinalité ou même une dimension flocon de neige sans dimension complète de la session ou du site.
Il n'y a pas vraiment de solution élégante, vous avez soit des colonnes nullables, soit vous utilisez une solution EAV. J'ai posté sur EAV auparavant (et j'ai généré beaucoup de commentaires qui méritent d'être lus):
http://sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/what-is-so-bad-about-eav-anyway.aspx
Je suis un fan de ce model dans certains scénarios, mais si vos dimensions / attributes ne changent pas fréquemment, cela peut représenter beaucoup de travail supplémentaire pour rien. Les valeurs NULL dans une colonne ne font pas vraiment de gaspillage tant que le code environnant peut les traiter de manière appropriée.
Vous pourriez avoir plus d'une table de faits: factperUserClicks, factperBroWserClicks, factEyeTime, etc …
Chacun d'eux aurait DateKey, SessionKey, SiteItemKey. De cette façon, seules les keys de dimension qui «ont du sens» apparaissent avec chaque fait.
Idéalement, il ne devrait pas y avoir de NULLS dans le DW – si vous les gardez dans la même table de faits, l'utilisation de zéros pourrait être plus appropriée.
En ce qui concerne l'économie d'espace disque, je ne vois pas de solution idéale – mais dans un DW on est supposé échanger de l'espace pour la rapidité et la (requête) simplicité de toute façon.