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

简介:
+关注继续查看

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

首先定个大的方向,是整数还是小数?如果是整数,那么我们可以选择的数据类型就只有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慢一些,但是基本上还在同一个数量级。

目录
相关文章
|
2月前
|
存储 数据挖掘 关系型数据库
数仓学习---6、数据仓库概述、 数据仓库建模概述、维度建模理论之事实表、维度建模理论之维度表
数仓学习---6、数据仓库概述、 数据仓库建模概述、维度建模理论之事实表、维度建模理论之维度表
|
3月前
|
存储 数据挖掘 BI
数据仓库建模
数据仓库建模
56 0
|
4月前
|
存储 SQL HIVE
数据仓库的Hive的数据类型的复杂数据类型的struct
在数据仓库领域,Hive是一个常用的工具。它提供了一种简单的方式来查询和分析大量数据。
50 0
|
4月前
|
存储 SQL 数据挖掘
数据仓库-维度建模不是万金油
写在前面:最近有些抵触写东西,总感觉自己没有清晰的表达思路和专业的知识体系,写的东西都是更偏向个人经验的一家之谈;之前总想着把文章结构做好,图片做好,表达做好,这样能更容易让大家理解,可以让更多的人接受所要表达的观点;但是,这样写太痛苦了,似乎是为了达到某种结果而刻意为之。。。最终还是回归表达的本质,传播思路和想法,把这个说清楚就可以了,不管是三言两语还是长篇大论,让看到的人能知道有这么一种观点和
74 0
|
5月前
|
存储 数据挖掘 BI
数据仓库(4)基于维度建模的数仓KimBall架构
基于维度建模的KimBall架构,将数据仓库划分为4个不同的部分。分别是操作型源系统、ETL系统、数据展现和商业智能应用,如下图。
151 1
|
6月前
|
大数据 数据管理 数据库
数据仓库(3)数仓建模之星型模型与维度建模
维度建模是一种将数据结构化的逻辑设计方法,也是一种广泛应用的数仓建模方式,它将客观世界划分为度量和上下文。度量是常常是以数值形式出现,事实周围有上下文包围着,这种上下文被直观地分成独立的逻辑块,称之为维度。它与实体-关系建模有很大的区别,实体-关系建模是面向应用,遵循第三范式,以消除数据冗余为目标的设计技术。维度建模是面向分析,为了提高查询性能可以增加数据冗余,反规范化的设计技术。
357 1
|
7月前
|
SQL Oracle 算法
「数据仓库架构」数据仓库的三种模式建模技术
「数据仓库架构」数据仓库的三种模式建模技术
|
8月前
|
SQL 存储 数据挖掘
ChatGPT 数据仓库实战:Kaggle 酒店入住数据分析与维度建模
ChatGPT 数据仓库实战:Kaggle 酒店入住数据分析与维度建模
|
10月前
|
OLAP 数据库
数据仓库--维度建模
数据仓库--维度建模
|
存储 机器学习/深度学习 大数据
数据仓库常见建模方法与大数据领域建模实例综述
数据仓库常见建模方法与大数据领域建模实例综述
630 0
数据仓库常见建模方法与大数据领域建模实例综述
热门文章
最新文章
相关实验场景
更多
推荐文章
更多