微軟BI 之SSAS 系列 - 多維數據集維度用法之一 引用維度 Referenced Dimension

在 CUBE 設計過程當中有一個很是重要的點就是定義維度與度量值組關係,維度的建立通常在前,而度量值組通常來源於一個事實表。當維度和度量值組在 CUBE 中定義完成以後,下一個最重要的動做就是定義二者之間的關係。在前面幾篇文章中也已經看到了如何將度量值組和維度經過哪些維度屬性進行關聯的操做,可是那些關聯一般都是 Regular 類型的,屬於直接的普通的關聯。html

可是實際上除了 Regular 以外,還有 Fact, Referenced, Many to Many 和 Data Mining(數據挖掘類不在此討論)。web

今天在這篇文章中講解 Referenced 和 Fact 兩種關係的定義。ide

使用的測試代碼以下 -測試

USE BIWORK_SSIS
GO
SET NOCOUNT ON
IF OBJECT_ID('FactInternetSalesReason','U') IS NOT NULL
DROP TABLE FactInternetSalesReason 

IF OBJECT_ID('FactInternetSales','U') IS NOT NULL
DROP TABLE FactInternetSales

IF OBJECT_ID('FactResellerSales','U') IS NOT NULL
DROP TABLE FactResellerSales

IF OBJECT_ID('DimEmployee','U') IS NOT NULL
DROP TABLE DimEmployee

IF OBJECT_ID('DimDate','U') IS NOT NULL
DROP TABLE DimDate 

IF OBJECT_ID('DimProduct','U') IS NOT NULL
DROP TABLE DimProduct 

IF OBJECT_ID('DimSalesReason','U') IS NOT NULL
DROP TABLE DimSalesReason 

IF OBJECT_ID('DimProductSubcategory','U') IS NOT NULL
DROP TABLE DimProductSubcategory

IF OBJECT_ID('DimProductCategory','U') IS NOT NULL
DROP TABLE DimProductCategory

IF OBJECT_ID('DimReseller','U') IS NOT NULL
DROP TABLE DimReseller 

IF OBJECT_ID('DimCustomer','U') IS NOT NULL
DROP TABLE DimCustomer 

IF OBJECT_ID('DimGeography','U') IS NOT NULL
DROP TABLE DimGeography 
GO
  
CREATE TABLE DimDate
(
    DateKey INT PRIMARY KEY,
    ShortDateName NVARCHAR(12) NOT NULL,
    FullDateName NVARCHAR(20)  NOT NULL, 
    DayNumberOfWeek TINYINT NOT NULL,
    DayNameOfWeek NVARCHAR(10) NOT NULL,
    DayNumberOfMonth TINYINT NOT NULL,
    DayNumberOfYear SMALLINT NOT NULL, 
    WeekNumberOfYear TINYINT NOT NULL,
    IsWeekend NVARCHAR(7) NOT NULL, 
    IsLeapYear BIT NOT NULL,
    MonthKey INT NOT NULL,
    MonthNumberOfYear TINYINT NOT NULL,
    MonthNameOfYear NVARCHAR(10) NOT NULL,
    MonthNameWithYear NVARCHAR(20) NOT NULL, 
    CalendarQuarterKey INT NOT NULL, 
    CalendarQuarterNumber TINYINT NOT NULL, 
    CalendarQuarterNameWithYear NVARCHAR(20) NOT NULL, 
    CalendarSemesterNumber TINYINT NOT NULL,
    CalendarYearKey SMALLINT NOT NULL, 
    CalendarYearName NVARCHAR(20) NOT NULL, 
    FiscalQuarterKey INT,
    FiscalQuarterNumber TINYINT NOT NULL, 
    FiscalQuarterName NVARCHAR(20),
    FiscalSemester TINYINT NOT NULL,
    FiscalYearKey SMALLINT NOT NULL, 
    FiscalYearName NVARCHAR(20),
)

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME

SELECT @StartDate = '2005-01-01',
       @EndDate = '2013-12-31'

WHILE (@StartDate <= @EndDate)
BEGIN
    INSERT INTO DimDate 
    (
        DateKey,
        ShortDateName,
        FullDateName, 
        DayNumberOfWeek,
        DayNameOfWeek,
        DayNumberOfMonth,
        DayNumberOfYear, 
        WeekNumberOfYear,
        IsWeekend,
        IsLeapYear, 
        MonthKey,
        MonthNumberOfYear,
        MonthNameOfYear, 
        MonthNameWithYear,  
        CalendarQuarterKey,
        CalendarQuarterNumber,
        CalendarQuarterNameWithYear,
        CalendarSemesterNumber,
        CalendarYearKey, 
        CalendarYearName,  
        FiscalQuarterNumber, 
        FiscalSemester,
        FiscalYearKey 
    )
    SELECT CAST(CONVERT(VARCHAR(8),@StartDate,112) AS INT) AS 'DateKey',
           CONVERT(VARCHAR(20), @StartDate,106) AS 'ShortDateName',
           CONVERT(VARCHAR(2),DATENAME(DD,@StartDate)) 
                    + ' ' 
                    + DATENAME(MM,@StartDate) 
                    + ' ' 
                    + CONVERT(CHAR(4), DATEPART(YY,@StartDate)) AS 'FullDateName', -- 1 July 2005  
           DATEPART(DW,@StartDate) AS 'DayNumberOfWeek',
           DATENAME(DW,@StartDate) AS 'DayNameOfWeek',
           DATENAME(DD,@StartDate) AS 'DayNumberOfMonth',
           DATENAME(DY,@StartDate) AS 'DayNumberOfYear',
           DATEPART(WW,@StartDate) AS 'WeekNumberOfYear',
           CASE WHEN DATEPART(DW,@StartDate) IN (1,7)  
                    THEN 'Weekend'
                ELSE 'Weekday' 
           END AS 'IsWeekend',
           CASE WHEN ((YEAR(@StartDate) % 4 = 0) AND (YEAR(@StartDate) % 100 != 0 OR YEAR(@StartDate) % 400 = 0))
                    THEN 1
                ELSE 0
           END AS 'IsLeapYear', 
           DATEPART(YY,@StartDate) * 100 + DATEPART(MM,@StartDate) AS 'MonthKey', -- 200507
           DATEPART(MM,@StartDate) AS 'MonthNumberOfYear',
           DATENAME(MM,@StartDate) AS 'MonthNameOfYear',
           DATENAME(MM,@StartDate) + ' ' + CONVERT(CHAR(4),DATEPART(YY,@StartDate)) AS 'MonthNameWithYear',  -- July 2005  
           DATEPART(YY,@StartDate) * 100 + DATEPART(QQ,@StartDate) AS 'CalendarQuarterKey',  -- 200503
           DATEPART(QQ,@StartDate) AS 'CalendarQuarterNumber',
           'CY ' + CONVERT(CHAR(4),DATEPART(YY,@StartDate)) 
                 + ' Qtr ' 
                 + CONVERT(CHAR(1), DATEPART(QQ,@StartDate)) AS 'CalendarQuarterNameWithYear', -- CY 2005 Qtr 3  
           CASE WHEN DATEPART(MM,@StartDate) BETWEEN 1 AND 6
                    THEN 1
                ELSE 2
           END AS 'CalendarSemester',
           DATEPART(YY,@StartDate) AS 'CalendarYearKey',  
           'CY ' + CONVERT(CHAR(4),DATEPART(YY,@StartDate)) AS 'CalendarYearName', -- CY 2005 
           CASE WHEN DATEPART(MM,@StartDate) BETWEEN 1 AND 6
                     THEN DATEPART(QQ,@StartDate) + 2
                ELSE DATEPART(QQ,@StartDate) - 2
           END AS 'FiscalQuarter',
           CASE WHEN DATEPART(MM,@StartDate) BETWEEN 1 AND 6
                    THEN 2
                ELSE 1
           END AS 'FiscalSemester',
           CASE WHEN DATEPART(MM,@StartDate) BETWEEN 1 AND 6
                    THEN DATEPART(YY,@StartDate) 
                ELSE DATEPART(YY,@StartDate) + 1
           END AS 'FiscalYear' 
    
           UPDATE DimDate 
           SET FiscalQuarterKey = FiscalYearKey * 100 + FiscalQuarterNumber,  -- 200601
               FiscalYearName = 'FY ' + CONVERT(CHAR(4), FiscalYearKey),   -- FY 2006
               FiscalQuarterName =  'FY ' + CONVERT(Char(4), FiscalYearKey) + ' Qtr ' + CONVERT(CHAR(1), FiscalQuarterNumber) -- FY 2006 Qtr 1      
           WHERE DateKey = CONVERT(INT,CONVERT(VARCHAR(8),@StartDate,112))
        
    SET @StartDate = @StartDate + 1
END

SELECT EmployeeKey,
       ParentEmployeeKey,
       EmployeeNationalIDAlternateKey,
       CASE WHEN ISNULL(MiddleName,'') = ''  THEN FirstName +' '+ LastName  
            ELSE FirstName +' '+ MiddleName +' '+LastName
       END AS FullName,
       Title 
INTO DimEmployee
FROM AdventureWorksDW2012.dbo.DimEmployee

SELECT SalesReasonKey,
       SalesReasonAlternateKey,
       SalesReasonName,
       SalesReasonReasonType
INTO DimSalesReason
FROM AdventureWorksDW2012.dbo.DimSalesReason

SELECT SalesOrderNumber,
       SalesOrderLineNumber,
       SalesReasonKey
INTO FactInternetSalesReason
FROM AdventureWorksDW2012.dbo.FactInternetSalesReason

SELECT ProductKey,
       ProductAlternateKey,
       ProductSubcategoryKey,
       EnglishProductName,
       StandardCost,
       Color,
       SafetyStockLevel,
       ListPrice,
       Class,
       Size,
       StartDate,
       EndDate,
       [Status],
       ProductAlternateKey + ' (' + CONVERT (Char(10), StartDate, 120) + ')' AS ProductID
INTO DimProduct
FROM AdventureWorksDW2012.dbo.DimProduct

SELECT ProductSubcategoryKey,
       ProductSubcategoryAlternateKey,
       EnglishProductSubcategoryName,
       ProductCategoryKey 
INTO DimProductSubcategory
FROM AdventureWorksDW2012.dbo.DimProductSubcategory

SELECT ProductCategoryKey,
       ProductCategoryAlternateKey,
       EnglishProductCategoryName
INTO DimProductCategory
FROM AdventureWorksDW2012.dbo.DimProductCategory 

SELECT ProductKey,
       OrderDateKey,
       EmployeeKey,
       ResellerKey,
       SalesOrderLineNumber,
       SalesOrderNumber,
       UnitPrice,
       ProductStandardCost,
       SalesAmount,
       CarrierTrackingNumber,
       CustomerPONumber,
       SalesOrderNumber+'_'+CONVERT(VARCHAR(10),SalesOrderLineNumber) AS 'SalesOrderLineID'
INTO FactResellerSales
FROM AdventureWorksDW2012.dbo.FactResellerSales

SELECT ProductKey,
       OrderDateKey,
       DueDateKey,
       ShipDateKey,
       CustomerKey,
       SalesOrderNumber,
       SalesOrderLineNumber,
       OrderQuantity,
       UnitPrice,
       SalesAmount
INTO FactInternetSales
FROM AdventureWorksDW2012.dbo.FactInternetSales  

SELECT GeographyKey, 
       City,
       StateProvinceCode,
       StateProvinceName,
       CountryRegionCode,
       EnglishCountryRegionName
INTO DimGeography 
FROM AdventureWorksDW2012.dbo.DimGeography

SELECT CustomerKey,
       GeographyKey,
       CustomerAlternateKey,
       Title,
       CASE WHEN ISNULL(MiddleName,'') = ''  THEN FirstName +' '+ LastName  
            ELSE FirstName +' '+ MiddleName +' '+LastName
       END AS CustomerName 
INTO DimCustomer        
FROM AdventureWorksDW2012.dbo.DimCustomer

SELECT ResellerKey,
       GeographyKey,
       ResellerAlternateKey,
       ResellerName
INTO DimReseller
FROM AdventureWorksDW2012.dbo.DimReseller

------------------------------------------------------------------------------
-- Add Primary Key Constraint
------------------------------------------------------------------------------  
ALTER TABLE DimEmployee 
ADD CONSTRAINT PK_EmployeeKey PRIMARY KEY CLUSTERED (EmployeeKey)

ALTER TABLE DimSalesReason 
ADD CONSTRAINT PK_SalesReasonKey PRIMARY KEY CLUSTERED (SalesReasonKey)

ALTER TABLE DimProduct 
ADD CONSTRAINT PK_ProductKey PRIMARY KEY CLUSTERED(ProductKey)

ALTER TABLE DimProductSubcategory 
ADD CONSTRAINT PK_SubcategoryKey PRIMARY KEY CLUSTERED(ProductSubcategoryKey)

ALTER TABLE DimProductCategory 
ADD CONSTRAINT PK_CategoryKey PRIMARY KEY CLUSTERED(ProductCategoryKey)

ALTER TABLE DimGeography 
ADD CONSTRAINT PK_GeographyKey PRIMARY KEY CLUSTERED(GeographyKey)

ALTER TABLE DimReseller 
ADD CONSTRAINT PK_ResellerKey PRIMARY KEY CLUSTERED(ResellerKey)

ALTER TABLE DimCustomer 
ADD CONSTRAINT PK_CustomerKey PRIMARY KEY CLUSTERED(CustomerKey)

ALTER TABLE FactInternetSales 
ADD CONSTRAINT PK_InternetSales PRIMARY KEY CLUSTERED(SalesOrderNumber,SalesOrderLineNumber)

ALTER TABLE FactResellerSales 
ADD CONSTRAINT PK_ResellerSales PRIMARY KEY CLUSTERED(SalesOrderNumber,SalesOrderLineNumber)

ALTER TABLE FactInternetSalesReason 
ADD CONSTRAINT PK_InternetSalesReason PRIMARY KEY CLUSTERED(SalesOrderNumber,SalesOrderLineNumber,SalesReasonKey)
------------------------------------------------------------------------------
-- Add Primary Key Constraint
------------------------------------------------------------------------------
ALTER TABLE DimCustomer
ADD CONSTRAINT FK_Customer_GeographyKey FOREIGN KEY(GeographyKey) REFERENCES DimGeography(GeographyKey)

ALTER TABLE DimReseller
ADD CONSTRAINT FK_Reseller_GeographyKey FOREIGN KEY(GeographyKey) REFERENCES DimGeography(GeographyKey)

ALTER TABLE DimEmployee
ADD CONSTRAINT FK_Employee_ParentEmployeeKey FOREIGN KEY(ParentEmployeeKey) REFERENCES DimEmployee(EmployeeKey)

ALTER TABLE FactResellerSales
ADD CONSTRAINT FK_Reseller_EmployeeKey FOREIGN KEY(EmployeeKey) REFERENCES DimEmployee(EmployeeKey)

ALTER TABLE FactResellerSales
ADD CONSTRAINT FK_Reseller_ProductKey FOREIGN KEY(ProductKey) REFERENCES DimProduct(ProductKey)

ALTER TABLE FactResellerSales
ADD CONSTRAINT FK_Reseller_OrderDateKey FOREIGN KEY(OrderDateKey) REFERENCES DimDate(DateKey) 

ALTER TABLE FactResellerSales
ADD CONSTRAINT FK_Reseller_ResellerKey FOREIGN KEY(ResellerKey) REFERENCES DimReseller(ResellerKey)

ALTER TABLE FactInternetSales
ADD CONSTRAINT FK_Internet_ProductKey FOREIGN KEY(ProductKey) REFERENCES DimProduct(ProductKey)

ALTER TABLE FactInternetSales
ADD CONSTRAINT FK_Internet_OrderDateKey FOREIGN KEY(OrderDateKey) REFERENCES DimDate(DateKey)

ALTER TABLE FactInternetSales
ADD CONSTRAINT FK_Internet_ShipDateKey FOREIGN KEY(ShipDateKey) REFERENCES DimDate(DateKey)

ALTER TABLE FactInternetSales
ADD CONSTRAINT FK_Internet_DueDateKey FOREIGN KEY(DueDateKey) REFERENCES DimDate(DateKey) 

ALTER TABLE FactInternetSales
ADD CONSTRAINT FK_Internet_CustomerKey FOREIGN KEY(CustomerKey) REFERENCES DimCustomer(CustomerKey) 

ALTER TABLE DimProduct 
ADD CONSTRAINT FK_Product_SubcatetoryKey FOREIGN KEY (ProductSubcategoryKey) REFERENCES DimProductSubcategory (ProductSubcategoryKey)

ALTER TABLE DimProductSubcategory 
ADD CONSTRAINT FK_Subcategory_CatetoryKey FOREIGN KEY (ProductCategoryKey) REFERENCES DimProductCategory (ProductCategoryKey)

ALTER TABLE FactInternetSalesReason 
ADD CONSTRAINT FK_InternetSalesReason_Order FOREIGN KEY (SalesOrderNumber,SalesOrderLineNumber) 
REFERENCES FactInternetSales (SalesOrderNumber,SalesOrderLineNumber)

ALTER TABLE FactInternetSalesReason 
ADD CONSTRAINT FK_InternetSalesReason_OrderReason FOREIGN KEY (SalesReasonKey) REFERENCES DimSalesReason (SalesReasonKey)

SELECT * FROM DimEmployee 
SELECT * FROM DimDate 
SELECT * FROM DimProduct
SELECT * FROM DimProductSubcategory
SELECT * FROM DimProductCategory
SELECT * FROM DimCustomer
SELECT * FROM DimReseller
SELECT * FROM DimGeography
SELECT * FROM DimSalesReason

SELECT * FROM FactResellerSales
SELECT * FROM FactInternetSales
SELECT * FROM FactInternetSalesReason

SELECT TOP 20 
       ProductKey,  -- 產品 KEY
       SalesOrderLineID, -- 訂單明細編號
       SalesOrderNumber, -- 訂單編號
       SalesOrderLineNumber, -- 訂單詳細編號
       UnitPrice, -- 單位價格
       ProductStandardCost, -- 標準成本
       SalesAmount, -- 銷售額
       CarrierTrackingNumber, -- 承運人跟蹤號,
       CustomerPONumber -- 採購訂單號
FROM FactResellerSales
View Code

新建 SSIS 項目並建立數據源和數據源視圖,在前面的幾篇博客中已經講到了 -spa

SSAS 系列 - 基於雪花模型的維度設計 - 主要已經處理了 DimProduct, DimProductSubcategory, DimProductCategory 這幾張表。設計

SSAS 系列 - 自定義的日期維度設計 - 主要處理 DimDate 表。code

SSAS系列 - 關於父子維度的設計 - 主要處理 DimEmployee 表。orm

SSAS 系列 - 實現Cube 以及角色扮演維度,度量值格式化和計算成員的建立 - 基於以上這些維度的度量值,角色扮演維度等概念。htm

在這個數據源視圖中,新加入了 DimCustomer, DimReseller, DimGeography , DimSalesReason, FactInternetSalesReason 這幾個維度表。 blog

那麼如今假設我須要直接經過 Geography 地理緯度直接聚合訪問 Reseller Sales 和 Internet Sales 度量值應該如何實現?

其實這個咱們徹底能夠借鑑 SSAS 系列 - 基於雪花模型的維度設計 這篇文章中的有關 Product Category, Product Subcategory, Product 這種層次結構的設計而應用到 DimGeography 和 DimCustomer 或者 DimGeography 和 DimReseller 的關係中,同樣能夠實現經過 Geography 直接聚合訪問度量值。

可是今天咱們將換一種方式來實現,直接經過定義維度和度量值關聯的 Referenced 關係來實現。

先快速建立好 Geography, Customer 和 Reseller 這幾個維度建立好,只有先建立好了維度才能定義與度量值組之間的關係。

Geography 層次結構。

Customer 維度很是簡單,只包含了一個非鍵屬性 Geography Key, Reseller 維度也是同樣建立的。

在多維數據集 Cube 的維度設計面板中選擇添加新的維度 - Customer, Geography 和 Reseller。

根據數據源視圖能夠直接看到 FactInternetSales 和 FactResellerSales 是分別引用了 DimCustomer 的 CustomerKey 和 DimReseller 的 ResellerKey。因此當添加完這幾個維度的時候,在維度用法中能夠看到 Customer 維度和Reseller 維度是已經自動關聯上了度量值組,而且它們之間的關係就是最簡單的 Regular 關係。

能夠觀察數據源視圖 FactInternetSales 是經過 DimCustomer 間接的關聯到 DimGeography 上的,所以咱們能夠說:

度量值組 Internet Sales "引用了" Geography 維度,Internet Sales 的 "引用維度 Reference Dimension" 是 Geography。

是經過 「中間維度」 Customer 維度引用的。

須要引用到"引用維度上的屬性" Reference dimension attribute 是 GeographyKey。

經過"中間維度的屬性" Intermediate dimension attribute 是 GeographyKey。

編輯 Geography 和 Internet Sales 交叉的區域,定義它們之間的關聯關係,在這裏選擇 Referenced 引用關係。

而後對照下面的操做完成關聯,其實下面的這些關聯動做就是實現了上述關聯描述。

Materialize 具體化 - 默認選項。它是指咱們這種引用關係一旦被具體化,那麼維度成員和事實數據之間的關聯關係將成員多維數據集物理存儲結構中的一部分。效率上是提升了,可是處理的時間可能會增多。 若是不選擇具體化,那麼每次查詢的時候多維數據集須要根據中間維度關聯到引用維度而後再計算聚合值,效率上會變得很低。由於此時,多維數據集的物理存儲結構中將只會保存事實數據和中間維度的關聯關係。

下圖一樣創建了 Reseller Sales 與 Reseller 維度之間的引用關聯關係。

記住引用關聯關係的圖標,之後打開已有項目時經過圖標就知道維度和度量值組是什麼關聯方式了。

部署並瀏覽數據,直接經過 Geography 維度來瀏覽 Internet Sales Amount 和 Reseller Sales Amount 度量值的數據。

更多 BI 文章請參看 BI 系列隨筆列表 (SSIS, SSRS, SSAS, MDX, SQL Server) 若是以爲這篇文章看了對您有幫助,請幫助推薦,以方便他人在 BIWORK 博客推薦欄中快速看到這些文章。

相關文章
相關標籤/搜索