MySQL數據目錄
最近寫的有點慢,各位見諒,這篇是理解事務和鎖實現的一個開篇,我想了很久才決定從數據目錄開始寫,充分尊重小白的認知過程,代價就是寫的有點慢~ 開始正文,非常重要的幾條閱讀建議,有些同學這開都不看就跳過了,再一次強調,不要跳!不要跳!不要跳!尤其是要看一下學習本篇之前應該掌握的知識,不然你的閱讀體驗會很糟糕的!下邊是建議正文:
1. 最好使用電腦觀看。
2. 如果你非要使用手機觀看,那請把字體調整到最小,這樣觀看效果會好一些。
3. 碎片化閱讀並不會得到真正的知識提升,要想有提升還得找張書桌認認真真看一會書,或者我們公眾號的文章。
4. 如果覺得不錯,各位幫著轉發轉發,如果覺得有問題或者寫的哪不清晰,務必私聊我~
5. 本公眾號的文章都是需要被系統性學習的,在閱讀本篇文章前最好已經閱讀過下邊幾篇文章,要不然可能會有閱讀不暢的體驗:
資料庫和文件系統的關係
我們知道像、這樣的存儲引擎都是把表存儲在磁碟上的,而操作系統用來管理磁碟的那個東東又被稱為,所以用專業一點的話來表述就是:像InnoDB、MyISAM這樣的存儲引擎都是把表存儲在文件系統上的。當我們想讀取數據的時候,這些存儲引擎會從文件系統中把數據讀出來返回給我們,當我們想寫入數據的時候,這些存儲引擎會把這些數據又寫迴文件系統。至於讀寫的方式,就是人家存儲引擎內部的事兒了,也就是我們說的存儲引擎的實現原理。
由於存儲引擎非常多,本篇文章只會嘮叨和這兩個存儲引擎的數據如何在文件系統中存儲。
MySQL數據目錄
那麼問題就來了,數據存在哪呢?用哪些文件來存儲表中的數據呢?其實為了管理數據,專門在文件系統上創建了一個目錄,這個目錄就稱為,下邊我們詳細嘮嘮這個玩意兒。
數據目錄和安裝目錄的區別
我們之前只接觸過的安裝目錄(在安裝的時候我們可以自己指定),我們重點強調過這個下非常重要的目錄,它裡邊存儲了許多關於控制客戶端程序和伺服器程序的命令(許多可執行文件,比如,,等等等等好幾十個)。比如在我的計算機上的下的內容如下:
而是用來存儲在運行過程中產生的數據,一定要和裝的區別開!一定要區分開!一定要區分開!一定要區分開!
如何確定MySQL中的數據目錄
那說了半天,到底把數據都存到哪個路徑下呢?下邊了解幾種查看路徑的方法。
在伺服器未啟動時查看
如果此時MySQL伺服器還沒有啟動,我們可以進入安裝目錄的目錄下,執行下邊這個命令:
但是這個命令會把所有啟動時的參數都列印出來,為了找到的位置,我們用命令過濾一下(是Linux中的字元串過濾命令,如果不知道可以找資料學習一下,Windows中怎麼過濾字元串我也不知道)。的參數名稱是,所以我們這麼寫命令就可以了:
可以看到結果里有這麼一行字元串:
這也就意味著,在我的計算機上的數據目錄就是,也就意味著會把運行過程中產生的數據都放在這個目錄下。
在伺服器啟動時查看
如果現在伺服器處於啟動狀態,查看的位置就更簡單了。對應著一個系統變數,我們在使用客戶端與伺服器建立連接之後查看這個系統變數的值就可以了:
從結果中可以看出,在我的計算機上的數據目錄就是,你用你的計算機試試唄~
數據目錄的結構
在運行過程中都會產生哪些數據呢?當然會包含我們創建的資料庫、表、視圖和觸發器吧啦吧啦的用戶數據,除了這些用戶數據,為了程序更好的運行,也會創建一些其他的額外數據,我們接下來細細的品味一下這個下的內容。
資料庫在文件系統中的表示
每當我們使用語句創建一個資料庫的時候,在文件系統上實際發生了什麼呢?
其實很簡單,每個資料庫都對應數據目錄下的一個子目錄,或者說對應一個文件夾,我們每當我們新建一個資料庫時,會幫我們做這兩件事兒:
在下創建一個和資料庫名同名的子目錄(或者說是文件夾)。
在該與資料庫名同名的子目錄下創建一個名為的文件,這個文件中包含了該資料庫的各種屬性,比方說該資料庫的字符集和比較規則是個啥。
比方說我們查看一下在我的計算機上當前有哪些資料庫:
可以看到在我的計算機上當前有7個資料庫,我們再看一下我的計算機上的下的內容:
可以看到,除了這個資料庫外,其他的資料庫在下都有對應的子目錄。這個比較特殊,我們在後邊的章節中會詳細嘮叨它的使用的,現在先忽略它哈~
表在文件系統中的表示
我們的數據其實都是以記錄的形式插入到表中的,每個表的信息其實可以分為兩種:
表結構的定義
表中的數據
就是該表的名稱是啥,表裡邊有多少列,每個列的數據類型是啥,有啥約束條件和索引,用的是啥字符集和比較規則吧啦吧啦的各種信息,這些信息都體現在了我們的建表語句中了。為了保存這些信息,和這兩種存儲引擎都在下對應的資料庫子目錄下創建了一個專門用於描述表結構的文件,文件名是這樣:
比方說我們在資料庫下創建一個名為的表:
那在資料庫對應的子目錄下就會創建一個名為的用於描述表結構的文件。值得注意的是,這個後綴名為.frm是以二進位格式存儲的,我們直接打開會是亂碼的~你還不趕緊在你的計算機上創建個表試試~
描述表結構的文件我們知道怎麼存儲了,那表中的數據存到什麼文件中了呢?在這個問題上,不同的存儲引擎就產生了分歧了,下邊我們分別看一下和是用什麼文件來保存表中數據的。
InnoDB是如何存儲表數據的
我們前邊重點嘮叨過的一些實現原理,到現在為止我們應該熟悉下邊這些東東:
其實是使用為基本單位來管理存儲空間的,默認的大小為。
對於存儲引擎來說,每個索引都對應著一棵樹,該樹的每個節點都是一個數據頁,數據頁之間不必要是物理連續的,因為數據頁之間有來維護著這些頁的順序。
的聚簇索引的葉子節點存儲了完整的用戶記錄,也就是所謂的索引即數據,數據即索引。
為了更好的管理這些頁,設計的大叔們提出了一個(英文名:)的概念,每一個可以被劃分為很多很多很多個,我們的表數據就存放在某個下。默認情況下,InnoDB只有一個表空間,稱為系統表空間,如果我們開心,我們也可以通過配置來建立自己的獨立表空間,下邊我們詳細看一下~
系統表空間
這個所謂的其實是一個抽象的概念,它實際可以對應著文件系統中若干個真實文件。默認情況下,會在下創建一個名為(在你的數據目錄下找找看有木有)、大小為的文件,這個文件就是對應的在文件系統上的表示。怎麼才?這麼點兒還沒插多少數據就用完了,哈哈,那是因為這個文件是所謂的,也就是當不夠用的時候它會自己增加文件大小~
當然,如果我們覺得這個文件作為不太好,我們也可以在啟動時配置對應的文件以及它們的大小,比如我們這樣修改一下配置文件:
這樣在啟動之後就會使用這兩個4G大小的文件作為,我們也可以把不配置到下,甚至可以配置到單獨的磁碟分區上,具體的配置語法其實挺複雜的,我們這就不多嘮叨了,知道改哪個參數可以修改對應的文件就好了~ 當然,如果它們不夠用了也會自擴展的~
再一次強調,默認情況下,我們表中的數據都會被存儲到這個系統表空間,也就是所有表的數據都被放到一個地方嘍~ 如果我們想讓每個表都有一個的話,需要自己配置一個。
獨立表空間
如果我們想讓每個表的數據都存儲到一個單獨的表空間中的話,可以在啟動伺服器的時候這樣配置:
使用來存儲表數據的話,會在該表所屬資料庫對應的子目錄下創建一個表示該的文件,文件名和表名相同,只不過添加了一個.ibd的擴展名而已,所以完整的文件名稱長這樣:
比方說假如我們使用了去存儲資料庫下的表的話,那麼在該表所在資料庫對應的目錄下會為表創建這兩個文件:
MyISAM是如何存儲表數據的
好了,嘮叨完了的系統表空間和獨立表空間,現在輪到了,說實話,我對這個存儲引擎也不太了解,只能說個大概,大家見諒哈哈。
我們知道不像的索引和數據是一個東東,存儲引擎的數據和索引是分開存放的,在中的索引全部都是。所以在文件系統中也是使用不同的文件來存儲數據文件和索引文件。而且和不同的是,並沒有什麼所謂的一說,表數據都存放到對應的資料庫子目錄下。假如表使用存儲引擎的話,那麼在該資料庫對應的目錄下會為表創建這三個文件:
其中代表表的數據文件,也就是我們插入的用戶記錄;代表表的索引文件,我們為該表創建的樹索引都會放到這個文件中。
視圖在文件系統中的表示
我們知道中的視圖其實是虛擬的表,也就是某個查詢語句的一個別名而已,所以在存儲的時候是不需要存儲真實的數據的,只需要把它的結構存儲起來就行了。和一樣,描述視圖結構的文件也會被存儲到所屬資料庫對應的子目錄下邊,只會存儲一個的文件。
其他的文件
除了我們上邊說的這些用戶自己存儲的數據以外,下還包括為了更好運行程序的一些額外文件,主要包括這幾種類型的文件:
伺服器進程文件。
我們知道每啟動一個伺服器,都意味著啟動一個進程。伺服器會把自己的進程ID寫入到一個文件中。
伺服器日誌文件。
在伺服器運行過程中,會產生各種各樣的日誌,比如常規的查詢日誌、錯誤日誌、二進位日誌、redo日誌吧啦吧啦各種日誌,這些日誌各有各的用途,我們之後會重點嘮叨各種日誌的用途,現在先了解一下就可以了。
伺服器相關其他文件。
比如為了和客戶端使用加密通信方式而生成的SSL證書和密鑰文件啥的~ 大家看不懂可以忽略~
文件系統對資料庫的影響
因為的數據都是存在文件系統中的,就不得不受到文件系統的一些制約,這在資料庫和表的命名、表的大小和性能方面體現的比較明顯,比如下邊這些方面:
資料庫名稱和表名稱不得超過文件系統所允許的最大長度。
每個資料庫都對應的一個子目錄,資料庫名稱就是這個子目錄的名稱;每個表都會在資料庫子目錄下產生一個和表名同名的文件,如果是的獨立表空間或者使用引擎還會有別的文件的名稱與表名一致。這些目錄或文件名的長度都受限於文件系統所允許的長度~
特殊字元的問題
為了避免因為資料庫名和表名出現某些特殊字元而造成文件系統不支持的情況,會把資料庫名和表名中所有除數字和拉丁字母以外的所有字元在文件名里都映射成 的形式作為文件名。比方說我們創建的表的名稱為,由於不屬於數字或者拉丁字母,所以會被映射成編碼值,所以這個表對應的文件的名稱就變成了。
文件長度受文件系統最大長度限制
對於的獨立表空間來說,每個表的數據都會被存儲到一個與表名同名的文件中;對於存儲引擎來說,數據和索引會分別存放到與表同名的和文件中。這些文件會隨著表中記錄的增加而增大,它們的大小受限於文件系統支持的最大文件大小。
對性能的影響
對於的獨立表空間和存儲引擎來說,每創建一個表都會在文件系統上創建幾個文件來表示這個表的結構和數據。如果伺服器中的表數量特別多,比方說有幾萬幾十萬張表,而且此時又有非常多的客戶端同時發送請求,那就意味著文件系統需要同時打開特別特別多的文件,每打開一個文件都需要一個所謂的,你不需要知道這個東西是什麼,這需要知道這個玩意兒是個稀缺貨,如果用的太多了文件系統讀寫文件的速度就會變慢,從而降低性能。
所以咋辦呢?少建些表唄,能合併就給合併了,或者用的系統表空間也可以減少創建文件的數量。
總結
對於、這樣的存儲引擎會把數據存儲到文件系統上。
數據目錄和安裝目錄是兩個東西!
查看數據目錄位置的兩個方式:
伺服器未啟動時(類Linux操作系統):
伺服器啟動後:
每個資料庫都對應數據目錄下的一個子目錄。
表在文件系統上表示分兩部分
表結構的定義
不論是還是,都會在資料庫子目錄下創建一個和表名同名的文件。
表中的數據
針對和對於表數據有不同的存儲方式。
對於存儲引擎來說,使用來存儲表中的數據,分兩種類型:
系統表空間
默認情況下,將所有的表數據都存儲到這個系統表空間內,它是一個抽象的概念,實際可以對應著文件系統中若干個真實文件。
獨立表空間
如果有需要的話,可以為每個表分配獨立的表空間,只需要在啟動伺服器的時候將參數設置為即可。每個表的獨立表空間對應的文件系統中的文件是在資料庫子目錄下的與表名同名的文件。
由於中的數據實際存儲在文件系統上,所以會收到文件系統的一些制約:
資料庫名稱和表名稱不得超過文件系統所允許的最大長度。
會把資料庫名和表名中所有除數字和拉丁字母以外的所有字元在文件名里都映射成 的形式作為文件名。
文件長度受文件系統最大長度限制。
如果同時訪問的表的數量非常多,可能會受到文件系統的文件描述符有限的影響。
題外話
寫文章挺累的,有時候你覺得閱讀挺流暢的,那其實是背後無數次修改的結果。如果你覺得不錯請幫忙轉發一下,萬分感謝~
TAG:我們都是小青蛙 |