MySQL中的數據目錄
確定MySQL的數據目錄
到底MySQL把數據都存到哪個路徑下呢?其實數據木對應著一個系統變量datadir
,我們在使用客戶端與服務器建立連接之后查看這個系統變量的值就可以了。
-- 以下兩種方式都可以
show variables like 'datadir';
select @@datadir;
當然這個目錄可以通過配置文件進行修改,由我們自己指定。
數據目錄都放些什么?
MySOL在運行過程中都會產生哪些數據呢?當然會包含我們創建的數據庫、表、視圖和觸發器等用戶數據,除了這些用戶數據,為了程序更好地運行,MySQL也會創建一些其他的額外數據。
數據庫在文件系統的中表示
create database lijin charset=utf8;
每當我們使用create database
語句從創建一個數據庫時,在文件系統上實際發生了什么呢?其實很簡單,每個數據庫都對應數據目錄下的一個子目錄,或者說對應一個文件夾,我們每當新建一個數據庫時,MySQL會幫我們做這兩件事兒:
- 在數據目錄下創建一個和數據庫名同名的子目錄(或者文件夾)
- 在該與數據庫名同名的子目錄下創建一個名為db.opt的文件,該文件中包含了該數據庫的各種屬性,比方說該數據的字符集和比較規則等。
比方說我們查看一下在我的計算機上當前有哪些數據庫︰
可以看到在當前有5個數據庫,其中 linjin 數據庫是我們自定義的,其余4個數據庫是屬于MySQL自帶的系統數據庫。我們再看一下數據目錄下的內容:
當然這個數據目錄下的文件和子目錄比較多,但是如果仔細看的話,除了information_schema這個系統數據庫外,其他的數據庫在數居目錄下都有對應的子目錄。這個information_schema比較特殊,我們后面再講它的作用。
數據表在文件系統中的表示
我們的數據其實都是以記錄的形式插入到表中的,每個表的信息其實可以分為兩種。
- 表結構的定義
- 表中的數據
表結構就是該表的名稱是啥,表里邊有多少列,每個列的數據類型是啥,有啥約束條件和索引,用的啥字符集和比較規則各種信息,這些信息都體現在了我們的見表語句中了。為了保存這些信息,InnoDB 和 MyISAM 這兩種哪個存儲引擎都在數據目錄下對應的數據庫子目錄下創建了一個專門用于描述表結構的文件,文件名是這樣:tableName.frm。
比方說我們在lijin數據庫下創建一個名為test的表
那在數據庫 lijin 對應的子目錄下就會創建一個名為test.frm的用于描述表結構的文件。這個后綴名為.fm是以二進制格式存儲的。
那表中的數據存到什么文件中了呢?不同的存儲引擎就有所不同,下邊我們分別看了下 InnoDB 和 MyISAM 是用什么文件來保存表中數據的。
InnoDB是如何存儲表數據
InnoDB 的數據會放在一個表空間或者文件空間(英文名: table space 或者 file space )的概念,這個表空間是一個抽象的概念,它可以對應文件系統上一個或多個真實文件〈不同表空間對應的文件數量可能不同)。每一個表空間可以被劃分為很多很多很多個頁,我們的表數據就存放在某個表空間下的某些頁里。表空間有好幾種類型。
系統表空間(system tablespace)
這個所謂的系統表空間可以對應文件系統上一個或多個實際的文件,默認情況下,InnoDB 會在數據目錄下創建一個名為 ibdata1 (在你的數據目錄下找找看有木有)、大小為12M的文件,這個文件就是對應的系納表空間在文件系統上的表示。
這個文件是所謂的自擴展文件,也就是當不夠用的時候它會自己增加文件大小,當然,如果你想讓系統表空間對應文件系統上多個實際文件,或者僅僅覺得原來的 ibdata1 這個文件名難聽,那可以在 MySQL 啟動時配置對應的文件路徑以及它們的大小,我們也可以把系統表空間對應的文件路徑不配置到數據目錄下,甚至可以配置到單獨的磁盤分區上。
需要注意的一點是,在一個MySQL服務器中,系統表空間只有一份。從MySQL5.5.7到MySQL5.6.6之間的各個版本中,我們表中的數據都會被默認存儲到這個系統表空間。
獨立表空間(file-per-table tablespace)
在 MySQL5.6.6 以及之后的版本中,InnoB 并不會默認的把各個表的數據存儲到系統表空間中,而是為每一個表建立一個獨立表空間,也就是說我們創建了多少個表,就有多少個獨立表空間。使用獨立表空間來存儲表數據的話,會在該表所屬數據庫對應的子目錄下創建一個表示該獨立表空間的文件,文件名和表名相同,只不過添加了一個. ibd 的擴展名而已,所以完整的文件名稱長這樣:tableName.ibd
比方說假如我們使用了獨立表空間去存儲lijin數據庫下的test表的話,那么在該表所在數據庫對應的lijin目錄下會為test表創建這兩個文件:
test.frm和test.ibd
其中test.ibd文件就用來存儲test表中的數據和索引,.frm 格式的文件前面已經說過,這里就不再贅述了。當然我們也可以自己指定使用系統表空間還是獨立表空間來存儲數據,這個功能由啟動參數
innodb_file_per_table
控制,比如說我們想刻意將表數據都存儲到系統表空間時,可以在啟動MySQL服務器的時候這樣配置:
[server]
innodb_file_per_table=0
- innodb_file_per table的值為0時,代表使用系統表空間;
- innodb_file_per table的值為1時,代表使用獨立表空間。
不過inmodb_file_per_table參數只對新建的表起作用,對于已經分配了表空間的表并不起作用。
其他類型的表空間
隨著 MySQL 的發展,除了上述兩種老牌表空間之外,現在還新提出了一些不同類型的表空間,比如通用表空間(general tablespace) 、undo表空間(undotablespace)、臨時表空間〈temporary tablespace)等。
MyISAM是如何存儲表數據的
在 MyISAM 中的數據和索引是分開存放的。所以在文件系統中也是使用不同的文件來存儲數據文件和索引文件。而且和 InnoDB 不同的是,MyISA 并沒有什么所謂的表空間一說,表數據都存放到對應的數據庫子目錄下。
test_myisam 表使用 MyISAM 存儲引擎的話,那么在它所在數據庫對應的 lijin 目錄下會為 MyISAM表創建三個文件:
其中 test_myisam.MYD 代表表的數據文件,也就是我們插入的用戶記錄; test_myisam.MYI 代表表的索引文件,我們為該表創建的索引都會放到這個文件中。