這篇是關於ORALCE對NUMBER類型儲存方式的探析, 以及試圖對設計者的初始意圖進行解釋.
最近往上看了很多對ORACLE怎樣進行資料存放區進行描述的, 感覺都不好理解, 於是參照了很多文章, 自己琢磨了下幾種單一資料型別的儲存.
Number類型
ORACLE對number的儲存, 首先是按一定規則進行轉換以後以十六進位儲存(真正儲存當然是二進位, 只是我們dump出來看到的是十六進位)的.
ORACLE資料庫中儲存的number類型包含3個部分: HEAD部分, DATA部分, 符號位.
對正數來說, 符號位省略, 對0來說, 只有80.
首先來看幾個儲存的例子, 我們可以用
SELECT DUMP(89,16) FROM dual |
來看到ORACLE對number類型實際儲存的結果: Typ=2 Len=2: c1, 5a
當然,如果我們想看十進位的,就用
SELECT DUMP(89,10) FROM dual |
Typ=2 Len=2: 193, 90
123 à C2, 2, 18
123.123 à C2, 2, 18, D, 1F
0 à 80
-123 à 3D, 64, 4E, 66
-0.123 à 3F, 59, 47, 66
HEAD部分為一個位元組8位, 表示其大小, 當然也包括正負, 就是前面看到的C2, 3D.
因為設計這種儲存格式的時候, 希望以十六進位00-FF來表示所有的number, 所以為了編碼的對稱, 首先將number分為正負, 所以以00-FF的中間位置80, 也就是十進位的128來表示0, HEAD部分小於80,即為負數,大於80即為正數.
另, 一個數, 都可以表示成(+/-)A.B * 10^(+-)C, 正負A.B * 10的正負C次方.
所以, ORACLE再次對00-80, 80-FF進行對分.
00-3E表示 x <= -1
3F-7F 表示 -1< x <0
81-C0 表示 0< x < 1
C1-FF 表示 1<= x
然後,我們再來看資料部分, ORACLE對十進位的數字是兩位兩位進行儲存的, 例如對1234, ORACLE會分別對12, 34進行儲存. 所以只需要對(+-)1-99進行編碼
1-99 分別用十六進位2-64表示就是2-100 x=y-1,
-1 – -99用十六進位64 – 2表示就是100-2 x=y-101
而位元的話, 就分別以距+-1兩個標準(為了方便,我們以下將以十進位來看)3E, C1(62,193)之差來表示. 至於符號位, 網上有人說是為了方便排序, 並且用的是(+-)1-99都不可能用到的編碼66(102)來表示.
例如123, 我們看為(100+23), 比1要多一個百位, 所以HEAD表示為193 + 1 = 194
資料部分用(2, 24)表示, 就是(194,2,24), 轉換為十六進位為(C2, 2, 18)
123.123, 我們看為(100+23+0.12+0.0030), 同樣HEAD部分為194
資料部分成了(2,24,13,31), 所以就是(C2,2,18,D,1F)
-123, 我們看為(-100-23), 比1多一個百位, 所以HEAD為62-1 = 61
資料部分(64, 78), 所以就是(3D, 64, 4E, 66)
-0.123, 我們看為(-0.12-0.0030), 最高位比-1少一個百分位, 所以HEAD為62+1 = 63
資料部分為(89,71), 所以就是(3F, 59, 47, 66)
其餘可類推, 其逆過程也很容易知道了.