The two most important days in your life are the day you were born and the day you find out why. -Mark Twain

#21 資料庫的資料實體儲存單位 Page - 2

延續上一篇文章 (#19 資料庫的資料實體儲存單位 Page) 的內容,在這篇文章裡,我們來談談有關資料庫的實體儲存結構.所謂的實體儲存結構是指資料放在硬碟中的情況.

首先,我們先來看看一個很簡單的結構,資料長度是固定的.這種情況在前面的文章有提過.因為長度都是固定的,所以每筆資料的長度便可以固定,這樣好處是在於方便計算也方便存取.

另一種情況是資料長度不是固定的,這種情況在前面文章也有提過.因為長度不是固定的,因此必須要想一個方法把不同欄位的資料做一個區隔,這樣在讀取資料時才知道什麼情況下是資料欄位的終點.在實體資料儲存時,有兩個方式可以來達成這種目的.第一,在每個資料欄位之間都用一個特殊符號隔開來,長相如下:


上圖是用一個 # 來當特殊符號,這是很笨的例子,但只是方便說明用.在資料寫入到硬碟時,資料欄位之間會透過特殊符號做為間隔,而在讀取資料時,資料庫引擎也知道該如何處理資料了,而這樣的好處就是非常直覺且簡單,並不會浪費多餘的硬碟空間,缺點就是會浪費較多的資料讀取時間,例如我只要讀取表格裡欄位五的資料,那麼資料庫引擎就必須從欄位一讀取過四個特殊符號才能取得欄位五的資料.從前面文章中,你應該有學到一個精神就是當你對時間不滿意時,那就犧牲點空間去換取時間.所以可以把上述的儲存方式最一點小改良如下圖:


在整筆資料的最前面加上一個導覽式的目錄,裡面存放著每個資料欄位開始的位址起點,所以每筆資料有五個欄位,因此目錄裡就有五個 pointer,而每個 pointer 的內容就是一個硬碟位址用來記得資料的起點.所以當資料庫引擎要讀取欄位五的資料時就不用從欄位一開始讀取了,可以透過目錄裡的第五個 pointer 就可以直接找到欄位五的位址.

以上所說的方法都是很直覺且自然的,但我們來想像一下如果進行資料更新或刪除時會發生什麼事情?

先針對資料更新來討論,如果把欄位三的內容更新成較小的內容時,此時影響不大,只是欄位三後面會有空白空間,而我們該討論的是該不該保留這個空白空間.因為這裡討論的是每個資料欄位都有一個 pointer 會對應到資料,所以若我們保留空白空間的話,可以讓資料少了些移動,但也可能會浪費許多細小的空白空間.如果此時的情況是欄位三的內容被更新成比較大的內容時,例如更長的字串,接著就面臨到沒有足夠的空間問題了,解決方法會有很多種,也許比較簡單的是把整筆資料搬移到足夠大的空間,好讓欄位三可以容納下新的內容,同時前面的五個 pointer 的內容也需要一起改變.如果是刪除呢? 那就更單純了,只要把整筆資料在刪除或是做一個已刪除的 flag 即可.所以,從這裡我們可以看到,其實在更新時所面到的挑戰是比刪除的挑戰還要大很多.而且不論是那一種更新 (內容變多或變小),都會遇到空白空間管理的問題.

所以我們可以發現,當資料庫的資料筆數越來越多時,讓資料庫引擎直接去對每一筆資料做管理時,其實是有點不方便的.因此,我們需要在這中間多一層實體儲存的管理單位,而這管理單位就是我們前面文章中所介紹的 Page.這種感覺就有點像一個國家不可能直接管理到每一個家庭,中間一定會有省,市之類的層級來做為分類,以便於管理上的應用.而 Page 也就是這樣的感覺.

Share:

0 意見:

張貼留言