I have designed a relatively simple data warehouse that uses the star schema. I have a fact table with just a primary key along with CompanyID and Amount (the actual measurement) columns. Of course I also have a dimension table to represent the companies which the fact table references.
Now I'm required to create a single level hierarchy (CompanyGroup) for companies. This seems like an easy task but the catch is that a single company should be allowed to exist within multiple CompanyGroups.
I experimented with this by creating a new dimension table called CompanyHierarchy that holds a primary key, GroupKey and CompanyKey. Defining a user defined hierarchy where GroupKey is the top level and CompanyKey is the second level yields A duplicate attribute key has been found error for the CompanyKey attribute while processing the dimension.
So, I'm not quite sure how to even start with this. How can I create a user defined hierarchy within a dimension where attributes can exist multiple times?
Screen shot of my current cube definition can be seen at:
img132.imageshack.us/img132/6729/ssasm2m.gif
You need to create a many-to-many relationship (one company can belong to many groups and one group can have many companies) There is an example of a many-to-many relationship in the Adventure Works cube around the sales reason dimension and there is an extensive white paper here that explains a number of different ways of using many-to-many relationships.
There is also a technique for supporting multiple members in the one hierarchy that I documented here
Related
I am trying to make simple app for chess tournaments, but I have problem with database, I have users that participate in tournament (thats fine) but how do I give users to the round and match, should i make another relations user_tournament-round-tournament, user_tournament-match-round?
Please see this answers a food for though rather than a solution. In your question there is not enough information to fully cover all use cases, so the answer below contains a lot of speculation.
In my over simplistic view and picking up on your initial model, the tournament_competitors (renaming from user_tournament as we have competitors and not users) table would create a unique id for each enrolled competitor. This id would be used as a reference in a tournament_matches table (the table would link twice to the tournament_competitors this table would connect two opponents - constraint warning). The table would also register the match type.
For the match type, I see two possibilities.
The matches table would list all possible match types (final, semi-final, quarter-final, elimination rounds, etc.) and these would be referred to in the tournament_matches table via id (composite key in the form tournament_id-competitor_id-group_id). This approach, specially for the elimination round matches, requires the need to find a way to link the number of competitors in each elimination group with then number of matches each competitor has to through before they are considered eliminated or not - creating a round number. I see this as a business logic part so not on the DB. The group_id also needs to be calculated and it would be best done on the application.
The alternative is to have the various match types in the tournament_matches table as a free field - populated by the application. The tournament structure (Number of Groups, number of opponents in each group, etc.) would be defined as attributes in the tournaments table. In this view there is no need for the rounds table.
I am modelling cube in SSAS. Cube has around 20 dimensions and 6 fact tables. Some of the dimensions are common among the fact tables. e.g. Time dimension. Fact_PNL has 3 date columns for those we have 3 role playing dimensions in the dimension usages.Another fact table has 5 date columns for them as well we have separate role playing dimensions in dimension usage tab. We have a common dimension Company which is foreign key in all fact tables. We might need to combine the data from multiple facts to get final output.
Should i create 6 role playing dimension for each of the fact table or use the same dimension for all fact tables?
Role playing dimensions should be created when we have multiple columns pointing to the same dimension ?
It's up to you. If the role playing dimension plays the same logical role for each fact table, then I would use the same RPD for the same logical role in each fact table. But if you want to use separate ones for each fact table, maybe because you think in the future they might be used differently, then you can.
In short, either way works fine, so whatever makes the most intuitive sense to you and other users is the way you should go.
Yes, that is the purpose of Role Playing Dimensions. When two or more columns in the same fact table reference the same dimension.
I am developing an ssas database and have snowflaked dimensions to which it has links. For example I have a customer dimension table, distributor dimension table and a territory dimension table in which there is a relationship to the latter from the other two. Therefore I can illustrate the relationships as follows:
Retailer <-- Territory
Distributor <-- Territory
In a specific cube in the database, I have measures where all the three dimensions mentioned above have relationships to. As far as the measures are considered browsing across individual dimensions happen smoothly.
But the problem comes when I try to browse a related measure from two dimensions at the same time; eg: territory and distributor
All the distributors are shown under a given territory.
When I add the territory key attribute to the distributor dimension and that specific attribute is used from the distributor dimension it self the relationship is shown correctly. But when I try to go from the territory dimension in the cube this relationship does not get exposed as explained earlier.
Any help is deeply appreciated.
This may not answer your question directly, but if you have several dimensions that are closely related and often used together, you could consolidate them into a "mini-dimension" that has every possible combination of territory, distributor and retailer (see my answer to another question):
create table dbo.DIM_TerritorySalesChannels (
TerritorySalesChannelID int not null primary key,
TerritoryName nvarchar(100) not null,
RetailerName nvarchar(100) not null,
DistributorName nvarchar(100) not null,
/* other attributes */
)
This might initially seem awkward, but it's actually quite easy to populate and manage and it avoids the complexity of relationships between dimensions, which often gets messy (as you've discovered). Obviously you end up with one very large dimension instead of three smaller ones, but as I mentioned in the other answer, we have several hundred thousand rows in one dimension and it's never been an issue for us.
I was hoping someone could explain the appropriate use of the 'FACT Relationship Type' under the Dimension Usage tab. Is it simply to create a dimension out of your fact table to access attribute on the fact table itself?
Thanks in advance!
Yes, if your fact table has attributes that you would like to slice by (create a dimension from), you would use this relationship type.
Functionally, to the users it behaves no differently than a regular relationship.
After you create your dimensions and cubes you need to define how each dimension is related to each measure group. A measure group is a set of measures exposed by a single fact table.
Each cube can contain multiple fact tables and multiple dimensions. However, not every dimension will be related to every fact table.
To define relationships right click the cube in BIDS and choose open; then navigate to the Dimension Usage tab. If you click the ellipsis button next to each dimension you will see a screen that allows you to change dimension usage for a particular measure group. You can choose from the following options:
Regular default option; the dimension is joined directly to the fact table
No relationship the dimension is not related to the current measure group
Fact the dimension and fact are derived from a single table. If this is the case your dimensional warehouse has poor design and isn't likely to perform well. Consider separating fact and dimension tables.
Referenced the dimension is joined to an intermediate table prior to being joined to the fact table. Referenced relationship resembles a snowflake dimension, but is slightly different. Suppose you have a customer dimension and a sales fact; you'd like to examine total sales by customer, but you also want to examine line item sales by customer. Instead of duplicating the customer key in the line item fact table you can treat the sales fact as an intermediate table to join customer to line item.
Many-to-many this option involves two fact tables and two dimension tables. Dimension A is joined to an intermediate fact A, which in turn joins to dimension B to which the fact B is joined. Much like with fact option if you need to use many-to-many option your design could probably use some improvement. This type of relationship is sometimes necessary if you are building cubes on top of a relational database that is in 3rd normal form. It is strongly advisable to use a dimensional model with star schema for all cubes. For example you could have two fact tables: vehicles and options; each vehicle can come with a number of options. You're likely to examine vehicle sales by customer, and options by the items that are included in each option. Therefore you would have a customer dimension and item dimension. You could also want to examine vehicles sales by included item. If so the vehicle fact would be joined to the options fact and customer dimension; the options fact would also join to items' dimension.
Data mining target dimension is based on a mining model which is built from a source dimension. Both source dimension and target dimension must be included in the cube.
Working on a data warehouse, a suitable analogy for the problem is that we have Healthcare Practitioners. Healthcare Practitioners have a number of professional attributes and work in an open number of teams and in an open number of clinical areas.
For example, you may have a nurse who works in children's services across a number of teams as a relief/contractor/bank staff person. Or you may have a newly qualified doctor who works general medicine who is doing time in a special area pending qualifying as a consultant of that special area.
So we have an open number of areas of work and an open number of teams, we can't have team 1, team 2 etc in our dimensions. The other attributes may change over time also, like base location (where they work out of), the main team and area they work in..
So, following Kimble I've gone for outriggers:
Table DimHealthProfessionals:
Key (primary key, identity)
Name
Main Team
Main Area of Work
Base Location
Other Attribute 1
Other Attribute 2
Start Date
End Date
Table OutriggerHealthProfessionalTeam:
HPKey (foreign key to DimHealthPRofessionals.Key)
Team Name
Team Type
Other Team Attribute 1
Other Team Attribute 2
Table OutriggerHealthProfessionalAreaOfWork:
HPKey (as above)
Area of Work
Other AoW attribute 1
If any attribute of the HP changes, or the combination of teams or areas of work in which they work change, we need to create a new entry in the SCD and it's outrigger tables to encapsulate this.
And we're doing this in SSIS.
The source data is basically an HP table with the main attributes, a table of areas of work, a table of teams and a pair of mapping tables to map a current set of areas of work to an HP.
I have three data sources, one brings in the HCP information, one the areas of work of all HCPs and one the team memberships.
The problem is how to run over all three datasets to determine if an HP has changed an attribute, and if they have changed an attribute, how we update the DIM and two outriggers appropriately.
Can anyone point me at a best practice for this? OR suggest an alternative way of modelling this dimension?
Admittedly I may not understand everything here, but it seems to me that the relationship in this example should be reversed. Place TeamKey and the WorkAreaKey in the dimHealthProfessionals -- this should simplify things.
With this in place, you simply make sure to deliver outriggers before the dimHealthProfessionals.
Treat outriggers as dimensions in their own right. You may want to treat dimHealthProfessionals as a type 2 dimension, to properly capture the history.
EDIT
Considering that team to person is many-to-many, a fact is more appropriate.
A column in a dimension table is appropriate only if a person can belong to only one team at a time. Same with work areas.
The problem is how to run over all three datasets to determine if an HP has changed an attribute, and if they have changed an attribute, how we update the DIM and two outriggers appropriately.
Can anyone point me at a best practice for this? OR suggest an alternative way of modelling this dimension?
I'm not sure I understand your question fully. If you are unsure about change detection, then use Checksums in the package. Build up a temp table with the data as it is in the source, then compare each row to its counterpart (joined via the business keys) by computing the checksum for both rows and comparing those. If they differ, the data has changed.
If you are talking about cascading updates in a historized dimension hierarchy (and you can treat the outriggers like a hierarchy in this context) then the foreign key lookups will automatically lookup the newer entry in DimHealthProfessionals if you have a historization (i.e. have validFrom / validThrough timestamps in DimHealthProfessionals). Those different foreign keys result in a different checksum.