tl; dr:每個SQLite數據庫都是一組文件,一個用於數據庫,另一個用於事務,如事務。在數據庫文件中,每個表是一個B-tree,每個節點一行。節點的鍵是rowid,值是每列的類型和大小,以及該行每列的值。
B樹的每個節點都是數據庫文件中的頁面。每一頁都是相同的大小。如果一行對於一個頁面來說太大,它可能會溢出到另一頁面。
該SQLite database file format is documented。有兩個文件,數據庫文件和回滾日誌。回滾日誌包含事務所需的信息。
數據庫文件以包含關於數據庫的信息(如其編碼的信息)的頭開始,其餘部分分割爲固定大小的磁盤空間塊"pages"。這允許SQLite快速查找文件中的特定內容,而不必讀取整個文件,它知道每個頁面在文件中的起始位置,並且可以快速地將seek
移動到該位置。
他們可以...
- 將鎖定字節(這是針對Windows強制性文件鎖定的事情)。
- 可用頁面的鏈接列表,如已刪除並準備好可重複使用的行。
- 如果一行中的數據對於一頁太大,則溢出。
- 使吸塵效率更高的指針圖。
- B-Tree中的頁面包含表格和索引以及所有這些頁面。
你在乎的是最後一個,B樹。 B樹允許您存儲快速查找單個對的鍵/值對,快速按順序讀取整個列表,快速插入,快速刪除和高效的空間。
每個表格都是以頁爲單位散佈在文件周圍的B樹。樹中的每個條目都有一個鍵,即64位rowid,值是行。該行表示爲一個標題,該標題描述了每個字段在該行中的大小,以及所有列的字節數組按其聲明的順序排列。
因此,讓我們說你有:
create table user (
id integer primary key,
name text,
age integer
);
你insert into user (name, age) values ("Yarrow Hock", 41)
它獲取的12345的id
將被存儲在B樹中,關鍵12345的值與頭開始描述什麼是在該列。
0, 35, 4
0代表integer primary key
。 0表示它是空的。由於它是關鍵,所以不需要再次存儲該值。如果下一個字段是文本,並且長度爲11(假設你使用的是UTF-8,那麼你可能就是這樣)。怎麼樣?這是(length * 2) + 13
或(11 * 2) + 13
。它是這樣做的,以確保該領域始終是奇怪的,它已經超過了12個。即使是超過12的字段也是二元的。 12以下的任何東西都是整數或浮點數或固定寬度的東西。
而4表示最後一個字段是一個32位整數。
最後,所有列的數據放在一起組成一個字節數組。這是它在十六進制中的樣子。
59 61 72 72 6f 77 20 48 6f 63 6b 00 00 00 29
使用頭,SQLite知道名稱字段從data[0]
開始,是11個字節長。這是59 61 72 72 6f 77 20 48 6f 63 6b
的一部分。年齡字段開始於data[11]
並且是4個字節,這是00 00 00 29
部分。
所有表,索引,觸發器和視圖完整的數據庫架構存儲在一個特殊的表名爲sqlite_master
看起來像這樣。
create table sqlite_master(
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
它像常規表一樣存儲,每個表,索引,觸發器或視圖都是一行。
還有很多其他的東西在裏面,你可以read the docs to learn more,但是這是如何存儲SQLite的信息基礎。我建議你看看B-trees,他們很棒。
對不起,它不能解釋爲你演示,因爲它與SQLite如何存儲的東西沒有關係。 – Schwern