按照之前的想法,似乎應該先做語言處理層,再做記憶體,再做檔案儲存,而在實驗過程中突然發現如果沒有做檔案儲存的話,設計記憶體中的資料庫很難寫,或者擔心寫了和將來的檔案儲存層互相排斥,既然是嘗試編寫sql資料庫,就寫乙個全套的吧,在這裡先寫下自己對資料庫檔案儲存格式的設想。
因為資料庫涉及很多的許可權要求,因此我將資料庫的前32個byte用於描敘許可權,我對許可權的設想是這樣的,資料庫和使用者在增刪改查等各方面都有乙個許可權等級,如果使用者在某一方面的許可權等級低於資料庫該方面的許可權等級,就無法進行該項操作。在緊隨其後的乙個long,用來儲存碎片鍊錶,之後用來儲存資料庫的欄位名,之後用來表示表,之後留出8個long值用來儲存其它(如可能用到的check約束,高許可權使用者給低許可權使用者授權的記錄)。
以上為資料庫檔案的檔案頭,它的大小固定,初始預設值為0.用**列舉如下:
用來儲存許可權(32byte)
碎片鍊錶首位址(long)
欄位名首位址
表元素首位址
包含前面三個共八個long值儲存其它可能使用的功能
...
也就是說,這個資料庫是使用鍊錶的形式來儲存的,鍊錶節點頭的格式是固定的:
節點大小【長度】(int)
節點狀態(byte)
下一節點位置(long)
上一節點位置(long)
【2016-11-12修改,由於byte【int】所以節點長度為long沒有意義】資料庫使用隨機檔案訪問的方式來進行操作(randomaccessfile)這樣可以在資料庫中隨時進行跳轉。狀態量用來儲存改鍊錶節點的使用狀況,預設0代表未使用,1代表可操作,在後來的拓展中,如果需要加入多執行緒安全方面的內容,這個位元組或許需要更多的值,比如2代表寫禁止,3代表讀禁止等等。
資料庫的其他元素都是在這個的基礎上進行設計,比如對於表內的資料,可以增加右元素位址來訪問下乙個欄位的值,在這片記憶體被廢棄之後(比如進行了刪除操作),資料庫應當做乙個更改得優先順序選擇,首先應當令byte的值為0,表示記憶體已廢棄,之後將該節點按節點大小插入到碎片鍊錶中(在插入的過程中檢測相同大小的節點中是否存在已經存在該位置,即是否存在某乙個節點的next值為本節點的位址,乙個比較好的思路是每乙個新的碎片都插入到相同大小碎片的最後乙個)。之後更改廢棄節點的上乙個節點的下乙個節點位置為該廢棄節點的下乙個節點的位置,廢棄節點的下一節點的上一節點的位置為廢棄節點的上一節點的位置(有點繞口令了,就是鍊錶刪除操作要做的工作)。之所以要按照這個順序,是為了萬一在進行某乙個操作的過程中,程式突然崩潰了,導致的斷鏈或者碎片的產生。考慮到這種情況在遍歷鍊錶的時候,如果發現某一節點的下一節點狀態值為0,則應該同上進行碎片**操作,在遍歷過程中應當不斷的檢測上一節點值是否合理。特別需要注意的是:即使遍歷到某一元素的狀態值為0,他也可能擁有下乙個元素的。
在申請空間的時候應當優先考慮從碎片鍊錶中選取,實際上,碎片鍊錶完全可以設計為碎片樹以減少插入、查詢的耗時(直接把上下節點位置轉換成左右子樹)。可以對碎片樹中的碎片進行合併處理具體操作為:遍歷碎片,檢查碎片的下乙個節點的狀態值是否為0,為零的話可以合併,不為零則不可以合併,注意不要越過檔案尾。
這種設計的資料庫在理論上是不斷增大的,但是由於增設了碎片處理,資料庫應該是無碎片或者輕碎片的。在使用碎皮那煉表中的記憶體是,應當注意不要修改碎片的節點大小值,如果在必要情況下要將乙個大的碎片記憶體截斷為兩個較小的碎片記憶體,最好保持兩個碎片的大小幾乎相等,最基本的要求也是碎片的大小比節點頭大乙個byte(布林型別值等可以用到)。
暫時設想如此,還未付諸行動。具體**完成後會同步更新到git上面,希望大家可以提出意見,謝謝大家。
資料庫sql編寫規範
一 dml語句 select語句必須指定具體欄位名稱,禁止寫成 因為select 會將不該讀的資料也從mysql裡讀出來,造成磁碟和網絡卡壓力,尤其在有text或者blob欄位的時候。select語句不要使用union,推薦使用union all,並且union子句個數限制在5個以內。因為union...
資料庫sql指令碼編寫規範
對查詢進行優化,應盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引。應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃瞄,如 select id from t where num is null可以在num上設定預...
C 編寫聊天程式系列筆記(三)資料庫加鎖操作
寫鎖是神馬捏?具體來說就是一種排他鎖,當寫的時候不允許其他程式寫,這樣就可以保證資料一致性了。ok了,這就夠了,在程式中怎樣對資料庫進行加鎖呢?資料庫的加鎖是在我們寫資料庫的時候進行的,當然現在很多資料庫都自己帶了枷鎖機制,但是當我們具有大量併發的時候還是自己寫著比較好 如下 string lock...