天天看點

在資料倉庫模組化時,應該使用哪種資料類型的路徑成本

在資料倉庫模組化中,很重要的模型就是星型模型,在星型模型中我們将表分為次元表和事實表,事實表中存放的可以進行計算(彙總,平均等)的列就是路徑成本。要進行計算的路徑成本,可以選擇的資料類型也有好多種,那麼我們應該選擇哪一種呢?

首先定個大的方向,是整數還是小數?如果是整數,那麼我們可以選擇的資料類型就隻有int和bigint了,16位或者8位的整數基本不用考慮,在資料倉庫這種大資料量的環境下,很容易就overflow了。即使是int這種32位的整數,在資料量特别大的情況下,如果要做sum甚至是avg操作,很可能就會溢出,是以一般推薦使用bigint。

對于價格,金額這種類型的資料,一般會記錄成小數,而且是兩位小數,那麼我們使用什麼資料類型來進行存儲呢?以sql server為例,我們可以選擇的資料類型包括:

float

money

decimal/numeric

1.float是一個非精确的資料類型,也就是說,存儲的資料在讀取出來時可能會有一定的誤差。在财務這種一分錢都不能差的系統裡面,是絕對不能采用的資料類型,在資料倉庫中進行sum的話會使得sum的結果與實際結果不一緻。但是float并不是一無是處,筆者使用兩千萬行的資料對幾種小數類型的資料進行性能測試,發現float在進行運算時具有一點優勢,另外float由于内部是采用科學計數法實作,是以可以存儲非常非常大的數值。

money類型在進行除法運算的時候,如果沒有轉換為decimal類型,那麼就會造成精度丢失,因為money始終保留4位小數,是以最終結果可能會比decimal類型的有誤差。是以最好不要把money類型的資料參與除法運算。

如果一定要參與除法運算,那麼我們可以将一個money類型和一個decimal類型進行除法運算,這樣系統會自動轉換成decimal類型,進而避免由于money隻保留4位小數造成的精度丢失。

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慢一些,但是基本上還在同一個數量級。