中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SQLite數據庫的工作原理分析

發布時間:2022-02-24 11:09:47 來源:億速云 閱讀:357 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“SQLite數據庫的工作原理分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“SQLite數據庫的工作原理分析”這篇文章吧。

SQLite 是一個小型數據庫應用程序,用于數百萬個軟件和設備。SQLite 是由 D.Richard Hipp 于 2000 年 8 月發明的。SQLite 是一種高性能、輕量級的關系數據庫。如果您愿意在編碼級別學習數據庫的內部結構,那么 SQLite 是最好的開源數據庫,它具有高度可讀的源代碼和大量文檔。閱讀更高版本的 SQLite 變得有點困難,因為它包含許多新功能。為了理解數據庫內部的基本實現,你應該對數據結構有很好的了解,一些關于計算理論的知識,以及操作系統是如何工作的。

在這里,我們將研究 SQLite 2.5.0 版本。您可以在GitHub上找到SQLite 后端的簡單實現。 另外,我發現這個存儲庫 包含用于代碼讀取的 SQLite 2.5.0 實現。

什么是數據庫?

將數據保存在平面文件中讀取和存儲數據的效率不高。數據庫以適當的順序組織數據,以便數據讀取和寫入速度更快。數據可以是結構化的、半結構化的或非結構化的。數據庫主要用于存儲結構化和半結構化數據。可以根據要存儲的數據結構類型對數據庫進行如下挖掘。

  1. 關系型數據庫:常用的具有表結構的數據庫類型。表可以與其他表有關系。SQL 語言用于操作此類數據庫上的數據。

  2. 鍵值數據庫:與關聯的鍵一起存儲的數據。可以使用給定的鍵檢索數據。內存數據庫通常是這種類型的數據庫。

  3. 對象數據庫:數據結構更像是一個對象而不是一個表。

  4. 圖數據庫:圖數據庫是節點和邊的集合,主要用于數據挖掘和社交媒體應用程序。

SQLite 數據庫架構

SQLite 數據庫架構分為兩個不同的部分,分別命名為核心和后端。核心部分包含接口、分詞器、解析器、代碼生成器和虛擬機,它們為數據庫事務創建執行順序。后端包含 B-tree、Pager 和 OS 接口來訪問文件系統。Tokenizer、Parser 和代碼生成器統稱為編譯器,它生成一組運行在虛擬機上的操作碼。

從哪里開始?

要了解數據庫的架構,您需要具備以下先決條件。

  1. 對數據結構和算法有很好的理解。尤其是 B 樹、鏈表、Hashmaps 等數據結構。

  2. 對計算機體系結構有一定的了解。如何讀寫磁盤,分頁和緩存如何工作。

  3. 有限自動機、上下文無關語法等理論計算機和一些正則表達式知識。

SQLite 架構

SQLite數據庫的工作原理分析cdn-images-1.medium.com/max/1600/1*t5ygkzu6a28fO41ynZ8kgQ.jpeg">

VFS(虛擬文件系統)

Unix 和 Windows 上的文件訪問彼此不同。VFS 提供通用 API 來訪問文件,而無需考慮其運行的操作系統類型。該 API 包括打開、讀取、寫入和關閉文件的函數。以下是 VFS 中用于讀取、寫入數據到文件中的一些 API。

/* 
Create a connection to file to read write 
zFilename : file name 
id : file pointer 
pReadonly : read or write 
*/
int sqliteOsOpenReadWrite(const char *zFilename, OsFile *id,int *pReadonly);
/* 
Acqure the lock to read file. This function should be 
called before caling to any file read function. 
Return 0 if success
id : file pointer 
*/
int sqliteOsReadLock(OsFile *id);
/* 
Get the write lock to write into a file. This function should called before
doing any write operation into the file system.
Return 0 if success
id : file pointer
*/
int sqliteOsWriteLock(OsFile *id);
/* 
Move to the given number of offest to read or write into the file
*/
int sqliteOsSeek(OsFile *id, int offset);
/* 
Read amt bytes from the file with offset pointed by sqliteOsSeek
*/
int sqliteOsRead(OsFile *id, void *pBuf, int amt);
/* 
Write amt bytes from the pBuf into the file
*/
int sqliteOsWrite(OsFile *id, const void *pBuf, int amt);

在這里,您可以使用 sqliteOpenReadWrite 函數開始使用文件。此函數為您提供一個指向文件的指針,該文件可用于讀取或寫入數據。接下來,應該在執行任何讀寫操作之前獲取鎖。如果它只是一個讀操作,那么應該獲取讀鎖。應該為讀和寫事務獲取寫鎖。 

然后可以通過將文件的偏移量提供給 sqliteOsSeek 函數來查找位置來完成讀寫。偏移量是從文件的起點到數據應該寫入或讀取的位置的字節數。

Pager

頁是文件系統上數據庫事務的最小單位。當數據庫需要從文件中讀取數據時,它會將它作為一個頁面來請求。一旦頁面被加載到數據庫引擎中,如果它經常訪問它的緩存,它就可以存儲該頁面。頁數從一頁開始編號。第一個頁面稱為根頁面。頁的大小是恒定的。

/*
Open pager with the given file name
*/
int sqlitepager_open(Pager **ppPager,const char *zFilename,int nPage,int nEx);
/*
Get page specified by the page number
*/
int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage);
/*
Start to write data into a page specified in pData
*/
int sqlitepager_write(void *pData);
/*
Commit page changes into the file
*/
int sqlitepager_commit(Pager*);
/*
Close the connection to the file
*/
int sqlitepager_close(Pager *pPager);

Btree

Btree 是一種數據結構,用于根據數據的值將數據存儲為樹。BTree 最簡單的形式是二叉樹。數據庫使用 Btree 數據結構來存儲索引以提高數據庫的性能。Btree 的每個節點都包含一個用于索引的鍵列表。可以為表中的每一列創建 Btree 索引。每個 Btree 都有根頁面,這是任何 Btree 搜索的起點。

為了指向 Btree 上的一行,使用了稱為“Cursor”的特殊指針。游標用于指向一個記錄,該記錄由頁面 id 和偏移量指定,稱為 idx。SQLite 將數據庫模式存儲在稱為“master_table”的表上。master_table 總是存儲在數據庫的第一頁上。 

了解更多關于SQLite的B樹的設計在這個文章。

/*
Open file connection to a page file name specified by zFileName with 
nCache size cache
*/
int sqliteBtreeOpen(const char *zFilename, int mode, int nCache, Btree **ppBtree)
/*
Start transaction. This function should called before any btree modification 
operations
*/
int sqliteBtreeBeginTrans(Btree *pBt)
/*
Insert key pKey with nKey byte and value pData with nData byte put 
into the Btree
*/
int sqliteBtreeInsert(BtCursor *pCur, const void *pKey, int nKey, 
                      const void *pData, int nData)
/*
Write data into the file
*/
int sqliteBtreeCommit(Btree *pBt)
/*
Move cursor to the matching pKey with nKey bytes
*/
int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes)

VDBE(虛擬數據庫引擎)

VDBE 是運行一組操作的虛擬機,由代碼生成器生成。包括插入、刪除、更新、選擇在內的所有 SQL 命令都轉換成一組操作碼,然后在虛擬機上運行。每個操作碼包含三個名為 p1、p2 和 p3 的輸入。您可以將此輸入視為函數的輸入。

下面我為以下 SQL 選擇語句添加了示例執行操作碼堆棧。PC 是程序計數器的指令 ID。 對我來說,SQLite 中最有趣的事情是我可以通過在 SQL 查詢的開頭附加“explain”關鍵字來查看給定 SQL 代碼的一組 VBDE 操作碼指令。

explain select * from foo;
個人電腦操作碼P1P2P3評論
1列數10
將列數設置為 1
2列名00價值將列名設置為“值”
3打開03

打開光標并將其指向第三頁,即 foo 表的根頁(p3 不重要

4驗證Cookies460
確保架構未更改
5倒帶011
將光標移動到第一個條目
6柱子00
從 Btree 負載讀取數據并將其放入堆棧
7柱子00

8ne110

從堆棧中彈出頂部的兩個元素。如果它們不相等,則跳轉到指令 P2。否則,繼續執行下一條指令。

9打回來10

從堆棧中彈出 P1 值并將它們組成一個數組。這將是此 SQL 表達式的結果行

10下一個05

將光標移動到下一條記錄,如果數據退出轉到 P2 否則轉到下一行

11關閉00
關閉光標

編譯器

Tokenizer、Parser 和 Code Generator 統稱為編譯器,可生成在 VBDE 上運行的操作碼集。Tokenizer 通過掃描 SQL 代碼生成一組令牌。然后,它驗證語法并生成解析樹。Lemon 解析器用于通過預定義的上下文無關語法來解析給定的 SQL 代碼。代碼生成器將這個解析樹轉換成一個用 SQLite 操作碼編寫的小程序。

以上是“SQLite數據庫的工作原理分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新龙县| 德庆县| 汽车| 确山县| 长葛市| 舟山市| 静乐县| 镇远县| 翁源县| 太仓市| 兴仁县| 洪泽县| 高雄市| 高唐县| 达孜县| 报价| 东台市| 安仁县| 赤水市| 民乐县| 宜兴市| 五大连池市| 左贡县| 温宿县| 阿克陶县| 娄烦县| 南康市| 遂昌县| 甘南县| 宜兰市| 江孜县| 南充市| 合肥市| 河北省| 公安县| 买车| 乐昌市| 新绛县| 通江县| 石景山区| 鹤山市|