在数据仓库建模时,应该使用哪种数据类型的度量值

在数据仓库建模中,很重要的模型就是星型模型,在星型模型中我们将表分为维度表和事实表,事实表中存放的可以进行计算(汇总,平均等)的列就是度量值。要进行计算的度量值,可以选择的数据类型也有好多种,那么我们应该选择哪一种呢?

首先定个大的方向,是整数还是小数?如果是整数,那么我们可以选择的数据类型就只有int和bigint了,16位或者8位的整数基本不用考虑,在数据仓库这种大数据量的环境下,很容易就overflow了。即使是int这种32位的整数,在数据量特别大的情况下,如果要做sum甚至是avg操作,很可能就会溢出,所以一般推荐使用bigint。

对于价格,金额这种类型的数据,一般会记录成小数,而且是两位小数,那么我们使用什么数据类型来进行存储呢?以SQL Server为例,我们可以选择的数据类型包括:

  • float
  • money
  • decimal/numeric

1.Float是一个非精确的数据类型,也就是说,存储的数据在读取出来时可能会有一定的误差。在财务这种一分钱都不能差的系统里面,是绝对不能采用的数据类型,在数据仓库中进行sum的话会使得sum的结果与实际结果不一致。但是Float并不是一无是处,笔者使用两千万行的数据对几种小数类型的数据进行性能测试,发现float在进行运算时具有一点优势,另外Float由于内部是采用科学计数法实现,所以可以存储非常非常大的数值。

print convert(money,'12345678901234567890');--Error
print convert(decimal,'12345678901234567890');--Error
print convert(float,'12345678901234567890');--Correct

2.Money是SQL Server特有的数据类型,在Oracle,MySQL中没有对应的类型。money的精度是可以到小数点后4位,所以对于我们平时记录两位小数的金额来说,是满足要求的。如果我们的度量值不是金额,而是其他含义的值,而且精度也不会超过4位小数(比如面积、长度、重量等),那么还是否可以使用money类型呢?如果只是进行sum、avg这样的运算,是完全可以使用money类型的。关于money和decimal的性能,有人专门做了个比较,我也使用两千万的数据进行了sum和avg的比较,发现money在计算上有一定的性能优势,但是这个优势也不是明显到速度能够提高好几倍的程度。老外做的比较的博客:http://sqlblog.com/blogs/aaron_bertrand/archive/2008/04/27/performance-storage-comparisons-money-vs-decimal.aspx

money类型在进行除法运算的时候,如果没有转换为decimal类型,那么就会造成精度丢失,因为money始终保留4位小数,所以最终结果可能会比decimal类型的有误差。所以最好不要把money类型的数据参与除法运算。

select sum(money1/money2) from testMoney;

如果一定要参与除法运算,那么我们可以将一个money类型和一个decimal类型进行除法运算,这样系统会自动转换成decimal类型,从而避免由于money只保留4位小数造成的精度丢失。

select sum(money1/decimal1) from testMoney;

3.Decimal类型和money类型一样都是精确数值类型,不同之处在于decimal类型可以指定占用的长度和小数后的精度。Decimal可以提供比Money更大的数据范围和更高的精度,当然也会占用更多的存储空间。

如果对于只保留2位小数的度量值,我们可以使用decimal(xx,2)来存储,前面的值根据数据量和数据值的大小来取,我一般写成decimal(18,2)。使用decimal类型进行除法运算时,不会出现money类型遇到的小数精度丢失的问题,即使我们只申明了decimal(xx,2),但是在进行除法运算的过程中,系统会保留很高的小数精度来进行计算。

Decimal的运算性能不如money,但是差距也不是那么的明显,在无法预期的对度量值的运算的情况下,使用decimal更保险。

总结:

如果是整数,就用bigint,避免数据量太大造成的int数据溢出。

如果是小数,而且不是那么关心精度,可以使用float,如果要计算的数值非法非常大就必须使用float,但是对于一分钱都不能差的情况下,就不要使用float类型。而应该使用money或者decimal。

如果不会有除法运算,而且数据的精度是在小数点后4位以内,那么使用money,其速度比decimal更快。

如果无法预期会不会有除法运算,或者要求的小数位数精度很高,那么就得使用decimal,速度比money慢一些,但是基本上还在同一个数量级。

时间: 2024-12-28 22:51:08

在数据仓库建模时,应该使用哪种数据类型的度量值的相关文章

数据仓库建模方法初步

一.前言 数据仓库得建模方法同样也有很多种,每一种建模方法其实代表了哲学上的一个观点,代表了一种归 纳,概括世界的一种方法.目前业界较为流行的数据仓库的建模方法非常多,这里主要介绍范式建模法,维度建模法,实体建模法等几种方法,每种方法其实从本质 上讲就是从不同的角度看我们业务中的问题,不管从技术层面还是业务层面,其实代表的是哲学上的一种世界观.我们下面给大家详细介绍一下这些建模方法. 二.3NF范式建模方法 范式建模法其实是我们在构建数据模型常用的一个方法,该方法的主要由 Inmon 所提倡,主

SQL Server四类数据仓库建模方法

  SQL Server四类数据仓库建模的方法主要分为以下四类. 第一类是关系数据库的三范式建模,通常我们将三范式建模方法用于建立各种操作型数据库系统. 第二类是Inmon提倡的三范式数据仓库建模,它和操作型数据库系统的三范式建模在侧重点上有些不同. Inmon的数据仓库建模方法分为三层,第一层是实体关系层,也即企业的业务数据模型层,在这一层上和企业的操作型数据库系统建模方法是相同的;第二层是数据项集层,在这一层的建模方法根据数据的产生频率及访问频率等因素与企业的操作型数据库系统的建模方法产生了

数据仓库建模:定义事实表的粒度

数据仓库建模:定义事实表的粒度 Posted on 2015-08-25 09:03 xuzhengzhu 阅读(28) 评论(0) 编辑 收藏 维度建模中一个非常重要的步骤是定义事实表的粒度.定义了事实表的粒度,则事实表能表达数据的详细程度就确定了.定义粒度的例子如下: 1.客户的零售单据上的每个条目. 2.保险单上的每个交易. 定义好事实表的粒度有很大的用处. 第一个用处就是用来确定维度是否与该事实表相关.例如,对于粒度细到医疗单据上条目项的事实表来说,医疗结果是不会作为维度和它进行关联的,

[Remoting FAQ]传递Remoting参数时遇到的两种常见错误

[Remoting FAQ] 传递Remoting参数时遇到的两种常见错误 Version Date Creator Description 1.0.0.1 2006-4-25 郑昀@Ultrapower 草稿   继续阅读之前,我们假设您熟悉以下知识: n         Remoting [现象1] 我们先来描述一个简单的错误.当你激活远端Remoting Objects时,却得到了这样的错误提示: 提示信息 Type 'Common.BTRequest' in Assembly 'Comm

配置Informatica9.6.1的集成服务时不管选择哪种字符都不能执行成功,日志信息:

问题描述 配置Informatica9.6.1的集成服务时不管选择哪种字符都不能执行成功,日志信息: serviceType service severity timestamp threadName messageCode message IS ETL_I_S 0$_:_$严重错误 06/29/2015 12:20:23.920 下午 13056 LM_36011 代码页不匹配.服务进程在代码页 [MS Windows Simplified Chinese, superset of GB 23

visual studio-中值法背景建模时选择视频帧问题

问题描述 中值法背景建模时选择视频帧问题 请教各位大神,请问用中值法和均值法进行背景建模时,必须要用无运动目标的视频帧进行背景重构吗,我直接从视频提取的前几帧图像(里边包含运动目标),然后出来的背景也是含有运动目标的.(用的vs与opencv) 解决方案 http://wenku.baidu.com/link?url=1EgyKjGLl-vm_d5DKblNj96dnU0EmOGoAhYx2SWmtc1c5EbyVlrfWEYXAgY4YbyGhrZSMuTOR7bdn3RzFmtS7n7I6K

今年以来在介绍这方面公司时陷入了一种深沉的苦闷

作为氪星少数盯互联网金融的作者,我发现今年以来在介绍这方面公司时陷入了一种深沉的苦闷.传统上,科技媒体总是被各种"亮点"所牵引的:或者是技术创新,或者是产品出彩,或者是模式新颖--如果一家公司满足上述条件之一,讲述起来都很简单,这也符合我们向大家传递新思想.新方向的义务.但显然,氪星的义务不止这么简单,我们既要帮大家发现新的思想和机遇,还要帮大家挖掘靠谱的创业公司.而当我们遇到一个所有玩家在模式和产品上都十分接近,所有竞争都围绕着后台细节(包括风控.合规.信息安全等)的行业时,就很难去

Python中的几种数据类型

  大体上把Python中的数据类型分为如下几类: Number(数字) 包括int,long,float,complex String(字符串) 例如:hello,"hello",hello List(列表) 例如:[1,2,3],[1,2,3,[1,2,3],4] Dictionary(字典) 例如:{1:"nihao",2:"hello"} Tuple(元组) 例如:(1,2,3,abc) Bool(布尔) 包括True.False 由于P

SQL中的五种数据类型

数据|数据类型 简要描述一下SQL中的五种数据类型:字符型,文本型,数值型,逻辑型和日期型 字符型 VARCHAR VS CHAR VARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要.他们都是用来储存字符串长度小于255的字符. 假如你向一个长度为四十个字符的VARCHAR型字段中输入数据Bill Gates.当你以后从这个字段中取出此数据时,你取出的数据其长度为十个字符--字符串Bill Gates的长度. 现在假如你把字符串输入一个长度为四十个字符的CHAR型字段中,那么当你取