如何自己實現一個關系型數據庫?
https://www.zhihu.com/question/38870156
作者:robert
鏈接:https://www.zhihu.com/question/25405073/answer/138210064
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
Database System Concept 和 Database System Implementation 是兩本不錯的書,但是大家好像只提到了書,卻沒有說該怎么做。寫一個數據庫,路徑的選擇很重要,否則很容易放棄。推薦這樣的路徑:
1. 數據庫是一個后端server,因此網絡通信,如何並發處理多個客戶端連接,收發數據,是首先要解決的問題。這個問題比較簡單,不再贅述。
2. 數據庫最基本的工作模式,是接收並理解一段代碼,根據這段代碼的邏輯,往服務器上寫入/讀取一些數據。因此,最基本的模塊有兩個,一個是代碼的解釋和執行, 一個是數據存儲。
a.sql的解釋和執行,可以用lex&yacc簡單寫一個語法解析器,一段sql發過來能夠正確轉換成內部結構體;再圍繞這些內部結構體,寫出語義分析代碼,最終將sql轉換成對存儲模塊的調用。
b.存儲模塊,除了設計好供上層調用的API,重點解決兩個問題:1. 構建B樹,管理一張表的數據; 2.將整顆B樹持久化到磁盤/從磁盤中讀取B樹數據。一般的做法是一個B樹節點對應一個數據塊,一個數據塊對應多條記錄,以及相鄰B樹節點的數據塊地址。 以數據塊為單位寫入,讀取。為優化數據庫的讀寫性能,需要在設計緩存和日志模塊,將數據塊緩存到內存,作為讀取操作的緩存;日志則用來優化磁盤數據寫入,將寫入數據塊時的隨機寫磁盤,轉換為寫日志的順序寫磁盤,如果宕機能夠根據日志恢復數據塊。在保證數據持久化的同時提高磁盤寫入性能。
c.存儲模塊寫好后,還需要一個元數據模塊,來描述各數據塊對應的庫表,和數據庫中記錄的語義。簡單的做法,可以把業務表的定義放在配置文件中,系統啟動后即加載配置文件,將庫表定義放入內存,用來解釋數據塊內容;如果還要支持DDL,即根據SQL語句創建/修改表結構,則可以從create table這條sql的實現入手,去構建元數據的管理模塊,一方面做到根據元數據解釋數據塊;另一方面做到將元數據持久化。
3. 事務支持。事務這套理論,用來解決多用戶並發操作相同庫表時,操作的一致性問題。理想的情況下,數據庫系統最終需要讓多個並發操作的結果,能夠等同於將這多個操作,進行某種串行排列后執行的結果,即並發操作的可串行化,但是實際上達、做到這一點成本很高,數據庫系能會很差,所以事務理論定義了4種隔離級別,對一致性做了一些妥協,來保證並發讀寫性能。單機數據庫下,事務機制不管從理論還是實現,都已經非常成熟,但要做好並不容易。
如何設計並實現一個 DBMS?
https://www.zhihu.com/question/25405073
實現簡單的sql增刪改查應該可以用python實現的。不過語言只是工具,原理才是根本,我覺得了解簡單的DB結構還是必要的。
1. 數據庫文件的組織形式,包括數據文件和索引文件。一種是將數據,索引分離存儲(MyISAM),另一種數據庫文件本身就是按B+樹組織的,也就是數據和索引是同個文件(InnoDB)。
2. 數據庫文件的結構:一般按page或block組織,一個block 4k大小。SQLite的數據表就是由一個或多個page構成。
3. 數據庫系統結構:可以參照SQLite的系統結構,將系統分為Front-end前端,和Back-end(后端)。
Front-end:SQL的解析器,將輸入的sql命令進行tokenize,然后對sql語法進行parse,轉化為內部命令格式(后端調用)。
Back-end:要負責catalog的管理,增刪改查record時要建立index,也就涉及page/buffer管理。
4. 具體實現:如果不考慮事務,並發,復雜的sql操作,可以參考下面的實現模塊。
作者:陳炳金
鏈接:https://www.zhihu.com/question/38870156/answer/80538773
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
