藍圖
資料庫自己管理磁碟資料和緩衝區,而不是透過作業系統管理(Os is not your friend.)。
三層檢視
資料庫以頁(page)為儲存資料的基本單位,檔案(file)是一系列頁的集合,頁中儲存頁資料(data),形成檔案-頁-資料三層架構。
檔案有不同的組織形式,頁包含頁頭和頁資料,頁資料可以採用不同方式組織:元組,日誌,索引。
黃色部分為課程會提及的內容。
採用Heapfile進行檔案儲存時的執行圖:
- 頁目錄:儲存管理的頁的元資訊(空閒頁,空頁)
- 頁頭:儲存頁的元資訊(頁大小,校驗和,資料庫版本,事務可見性,壓縮後設資料)
面向元組的資料儲存
-
透過<FileId, PageId, Slot>定位到一個指向tuple的指標(磁碟地址),然後找到tuple。
-
slot指標的靈活性:內部元組位置變化時,外部無感知;指標可以指向其他頁,可以儲存大資料(檔案,大文字);支援變長記錄。
-
資料庫會為每個元組分配一個資料記錄的唯一標識(record identifier),來表示元組的物理位置。SQLite和Oracle中為ROWID,Pg中是CTID,<PageId, Slot>。但是他們對於應用程式是無用的。
-
Header包含:可見性資訊;NULL Bit Map。
-
Data包含:行資料。
Tuple只是一個字串(char[]),本身不儲存型別資訊,型別資訊存在資料庫的System Catalogs中。(為了保證資料緊湊;非自解釋的)
存資料時會遇到的問題:
- 資料對齊:填充,重排序
- 精確值問題:BIGDECIMAL(轉為字串儲存)
-
空值:Bit Map;特殊值
-
大值和檔案:Overflow Page和External File。
大值採用溢位頁;大檔案可以採用溢位頁,也可以用外部檔案系統儲存,然後儲存一個指向檔案路徑的指標,而不是直接儲存檔案內容(Oracle:BFILE, Microsoft: FILESTREAM)。
日誌結構儲存
基本概念:
- 利寫不利讀,非原地更新:只有PUT和DELETE操作,順序IO。查詢時由最新到最老時查詢日誌。
- 加速查詢:索引。
- 加速查詢:日誌壓縮,且壓縮時會排序日誌。
- 壓縮方式:層級壓縮,統一壓縮
特點 | Level Compaction | Universal Compaction |
---|---|---|
層級結構 | 有多層級,L0、L1、L2 等 | 無層級結構,所有檔案在同一級別 |
檔案組織方式 | 每個層級內檔案不重疊,跨層逐漸下推 | 基於檔案大小和數量合併,檔案可能有重疊 |
合併策略 | 層級壓縮,按順序下推合併 | 檔案數量和大小超過閾值時觸發合併 |
寫放大 | 較高,因為需要不斷下推檔案至更低層級 | 較低,因為減少頻繁合併 |
讀放大 | 較低,因為相同鍵在每層只存在一次 | 較高,因為沒有嚴格層級,需檢查多個檔案 |
適用場景 | 讀多寫少的場景 | 寫多讀少、實時資料的高寫入場景 |
索引組織儲存
直接用索引組織資料,資料掛在葉子結點上,Page內部的tuple有序。
SQLite和MySQL預設用這種方式組織資料,Oracle和SQL Server可選。
和基於元組的儲存對比:
特性 | Index-Organized Storage | Tuple-Oriented Storage |
---|---|---|
資料與索引儲存 | 資料儲存在主鍵索引結構中 | 資料和索引獨立儲存 |
資料排序 | 資料按照主鍵順序排序 | 資料無序儲存 |
主鍵查詢效能 | 高效,因資料已按主鍵排序 | 依賴主鍵索引,但資料本身無序 |
插入和更新效能 | 插入和更新時可能需要索引重排,較慢 | 插入和更新較快,無需主鍵排序 |
適用場景 | 主鍵查詢頻繁,資料順序性強的場景 | 多種查詢模式,插入和更新頻繁的場景 |