请联系我们

Project REAL分析服务技术探讨

来源: 数据库 SQL Server |  作者: landluo |  发布: 2009-7-08 10:09


和tinyint键不匹配的数据类型

在关系型设计中一个很出名的经验是你应该总是应该使用那些能够满足你正在使用对象范围要求的最小数据类型。如果你知道这点(出于商业原因),一个数值总是不会超出一个极限,就不要使用大的数据类型。这样做只会浪费存储空间。尽管,这总是一个很好的建议,但要提防在SQL Server 2005中,当我们处理tinyint的时候,可能会带来数据类型的不匹配。Tinyint键值作为byte类型(从1到255)保存。当数据源视图被创建后,如果tinyint键是一个标识列(可能是一个代理列),然后系统将把它转换为integer。因此维度的键是一个integer。但是,在你实际的表格中,智能保存tinyint的值,这可能会导致类型不匹配。

例如,在原先SQL Server 2000格式的Project REAL设计中,Department 维度是一个完整的维度表。Department 键是一个tinyint值(从1到13),包含了书本的类型,例如精装本或者软皮本。Department 键有一个Indentity属性,因此下一个值应该是14,然后是15等等。因为,往往是选择能够满足需求的最小数据类型,因此选择了tinyint。在这种情况下,原先的设计人员认为不会超过255个Department。自然地,实际表中有一个外部关键字,也是tinyint。当我们将设计前一到SQL Server 2005分析服务后,将导致数据类型的不匹配。

在这种情形下工作的时候,需要在数据源视图的维度表上创建一个计算列,需要显式的将键列转换成tinyint类型。然后,在维度的关键属性层次中舍弃原来的列而使用这个新列。尽管你也可以将实际表中的tinyint类型转成integer类型,但这会造成空间上的浪费。

尽管你会认为这可能是一个Bug(我们也这么认为过),事实上,这是由于早期使用Microsoft XML Core Services (MSXML)来进行开发造成到。在MSXML中,主张一种隐式的数据转换,能够将一个未知的数据类型转换成它们想要的数据类型(跟SQL Server RDBMS式不一样的)。在这里,tinyint是从SQL Server 早期遗留下来的数据类型,MSXML事实上直接将它转换成了integer类型。如果解决这个问题,有太多现存的MSXML代码需要修改,因此,我们不得不保留这种情况。

未知成员

决定一个系统如何处理未知值总是一个有趣的设计决定。在SQL Server 2000中,这个是很简单的,你只是需要创建一个你自己的应用程序级的未知成员。这包括在你的维度(Dimension)中添加一个未知成员以及在实际数据库表上添加一个ISNULL或者其它的关系型技术。在SQL Server 2005中,提供了一种新的技术,允许系统生成一个它自己的未知成员,并将它自动的赋给未知值。

在Project REAL中,我们采用这两种方案。在绝大部分NULL值上,我们创建了应用程序级的未知成员(我们称它为”missing”)。这种方案,在视图中的绝大部分工作都可以完成,也包括通过代理键值为0,来返回已丢失的信息。显然,当NULL值不使用0表示,而使用一些看上去就是异常的数据,这种方法会让系统看上去更完美。我们可以使用合理的“丢失”数据(我们预期的一些信息)来表示一些异常的无效数据(也就是无效的数据)。使用系统生成未知成员的问题是你不会察觉到逻辑上不合理的数据和无效、异常数据之间的区别。

最佳实践:在可能的地方,创建你自己的未知成员。使用系统生成的未知成员。

下面的代码是关于一个如何在关系型视图中如里未知成员的例子。

CREATE VIEW [dbo].[vTbl_Dim_Store] AS

SELECT store.SK_Store_ID

,store.Store_Num

,store.Order_Status

,store.Store_Desc

,COALESCE(store.Division_Num,0) as Merch_Div_Num

,store.Status

,COALESCE(store.Status_Desc,'Unknown') as Status_Desc

,store.Open_Date

,store.Close_Date

,store.Division_Num

,COALESCE(Store.Division,'Unknown') as Division

,store.Region_Num

,COALESCE(store.Region,'Unknown') as Region

,store.District_Num

,COALESCE(store.District,'Unknown') as District

,store.Market_Area_Num

,COALESCE(store.Market_Area,'Unknown') as Market_Area

,store.Market_Type

,store.Ad_Area_Num

,COALESCE(store.Ad_Area_Desc,'Unknown') as Ad_Area

,store.Center_Desc

,COALESCE(store.City,'Unknown') as City

,store.Zip_Code

,store.State

,store.Mgr_Name

. . .

FROM dbo.Tbl_Dim_Store store

COALESCE函数被用来将数据库中的NULL值转换到维度(dimension)中合理的未知成员。对于上文Transact-SQL代码范例中Merch_Div_Num 列,键值” 0”是对于未知成员的一个应用惯例。这个范例合理的清除了那些位置成员。我们有时会期望提供NULL值。我们会把这些NULL值转换成我们预定义好的、符合语义的内容。例如上文中的键值” 0”。

系统创建的未知成员是SQL Server 2005中的一个创新之处。在Project Real设计中,我们用它来处理那些丢失的客户。当它关掉的时候,这个专门的维度会包含大量的无效数据。在我们设计完整的系统后,我们注意到,因为无法根据代理值去查询相关的客户,因此大约有10%的销售数据是失败的。当它关掉的时候,这种情况是由于销售发生时间和客户在诚信卡系统中出现的时间之间的延迟造成的。在一些情况下,系统从Customer数据源得到关于新客户的数据反馈,需要花费一个月甚至更多时间。系统能够马上提供Sales数据反馈,但得到Customer数据反馈往往会有延迟。我们认为,这种反馈数据的不匹配并不是一种不正常的情况。你可能也会马上意识到这个问题。因此,为了跟踪这种类型的活动, 我们决定不调整整个ETL和分析服务(Analysis Services)处理。我们更恰当的定义了一个系统生成未知成员。然后我们为Store Sales部分修改了错误配置,因此一个外部关键字查询错误被转换成分配一个未知成员。

图9表示了如何配置一个维度。

图9:如何配置一个系统生成的未知成员

共20页: 10 下一页

【内容导航】

原文:Project REAL分析服务技术探讨(10)


* 部分内容来源于网络,版权属原作者所有,转载请注明来源。
打印 | 收藏此页 |  推荐给好友 | 举报