一個資料庫被映射到多個不同的文件,這些文件由底層的操作系統來維護。每個文件分成定長的存儲單元,稱為塊(bolck),塊是存儲分配和數據傳輸的基本單元。資料庫預設的塊在4-8k之間。通常沒有記錄比塊更大(圖片音頻等大文件先不考慮),此外還要求每條記錄保存在單個塊中。 一、定長記錄instructor表 ...
一個資料庫被映射到多個不同的文件,這些文件由底層的操作系統來維護。每個文件分成定長的存儲單元,稱為塊(bolck),塊是存儲分配和數據傳輸的基本單元。資料庫預設的塊在4-8k之間。通常沒有記錄比塊更大(圖片音頻等大文件先不考慮),此外還要求每條記錄保存在單個塊中。
一、定長記錄
instructor表的屬性有:ID
char(5); name
char(20)。假設每個字元占用1位元組,則每條記錄占用25位元組,不能將這些記錄順序存儲,否則會出現跨塊的情況;而且刪除記錄時,將後面的記錄依次向前移動開銷很大。為瞭解決跨塊的問題,每個塊只存儲整數條記錄,多餘的空間暫時不用。而在刪除記錄時,可以將最後一條記錄移動到被刪除記錄的位置,而不是將所有後面的記錄依次向前移動。此外考慮到插入操作往往比刪除操作更為頻繁,可以將刪除記錄後留出的空間給下次的插入數據占用。
但插入記錄時,如何找到被刪除記錄的位置呢:可以在文件頭部留出一定空間來存儲第一條被刪除記錄的位置,第二條記錄被刪除後,其位置被記錄在第一條刪除記錄的位置,這樣依次進行,形成了圖示的情況:
被刪除的記錄形成了一條鏈表(linked list),這兒也稱為空閑列表(free list)。每次新插入數據時,都插入header指向的地址,同時header中的地址更新為下一條被刪除記錄的地址。
二、變長記錄
A)存儲方式
數據表中包含變長屬性時就會涉及到變長記錄的存儲。不管何種變長存儲技術,都需要解決這兩個基本問題:如何描述一條記錄,可以方便地獲取其中的屬性;如何在塊中存儲一條記錄,可以使它被方便地獲取到。
一條有變長屬性的記錄通常具有兩部分:定長的初始部分,然後是緊隨其後的變長部分。定長部分用(偏移量,長度)這樣的格式來表示,偏移量指示了數據的起始位置,長度即為變長部分的長度。變長部分在定長部分之後連續存儲。
上圖示例為instructor(ID varchar(5);name varchar(20);dept_name varchar(20);salary numeric(8,2))的存儲方式,ID
name dept_name是變長的(假定偏移量、長度分別占用2個位元組);salary是定長的,所以直接存儲。
上圖也演示了空點陣圖(null
bitmap)的使用,如果屬性salary是空的,則空點陣圖的第4位會被置為1,存儲salary的12-19位會被忽略。1位元組的空點陣圖可以應對最多8個屬性的表結構,如果有更多屬性,則需要擴展空點陣圖的長度。這種方式以額外的空點陣圖讀取為代價,節約了存儲空間,在具有很多屬性同時這些屬性多為空的表中是很有效的。
B)在塊中存儲變長記錄
在塊中存儲變長記錄時一般使用分頁的槽結構(slotted-page structure),如圖所示,每個塊(block)中都有header:
header中包含的信息有:塊中條目的個數、空閑空間的結尾處、每條記錄的入口(entry,包含記錄位置和大小)。記錄在塊中連續存儲,但是,是從塊的尾部開始存起的。每次插入新的紀錄時,就放置在空閑空間的末尾,同時在header中保存這條記錄的入口信息;當刪除一條記錄時,被刪除記錄前的記錄依次先後移動,以占據被刪記錄的空間。由於每個塊的體積在4-8k之間,並不算太大,所以這種移動的開銷相對較小。在分頁的槽結構中,數據指針不是直接指向數據,而是指向數據的入口(entry),於是數據在塊中可以任意被移動,這可以避免塊中碎片的產生。
學習資料:Database System Concepts, by Abraham Silberschatz, Henry F.Korth, S.Sudarshan