(一)初識 MySQL
- MySQL 的客戶端/服務器架構
和我們平時使用的大部分軟件一樣,MySQL 由這兩部分組成(客戶端和服務器),它的使用過程大致是:服務器程序直接和我們存儲的數據打交道,然後可以有多個客戶端程序連接到這個服務器程序,發送增刪改查的請求,服務器接收到這些請求後響應,從而操作它維護的數據。
MySQL 服務器程序和客戶端程序本質上都算是計算機上的一個進程,每個進程都有一個唯一的編號,稱爲進程ID,英文名叫 PID,這個編號是在我們啓動程序的時候由操作系統隨機分配的(每次啓動時可能都不一樣)。每個進程都有一個名稱,這個名稱是編寫程序的人自己定義的,比如我們啓動的 MySQL 服務器進程的默認名稱爲 mysqld, 而我們常用的MySQL客戶端進程的默認名稱爲 mysql。
- MySQL 的安裝
一般我們正常安裝 MySQL 的話都會把服務器程序和客戶端程序裝到我們的機器裏,安裝時注意記住你的安裝目錄(安裝跳過)。
以在 UNIX 操作系統的安裝目錄爲例:
/usr/local/mysql/
在 MySQL 的安裝目錄下有一個特別重要的 bin 目錄,這個目錄下存放着許多可執行文件:
/usr/local/mysql/bin
假設我們現在所處的工作目錄是 MySQL 的安裝目錄,也就是 /usr/local/mysql,我們想啓動 bin 目錄下的 mysqld 這個可執行文件,可以使用相對路徑來啓動:
./bin/mysqld
或者直接輸入 mysqld 的絕對路徑也可以:
/usr/local/mysql/bin/mysqld
又或者將該 bin 目錄的路徑加入到環境變量 PATH 中,各個路徑之間使用冒號":"隔離開:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
上面例子中的環境變量 PATH 的值表明:當我在輸入一個命令時,系統便會在 /usr/local/bin、/usr/bin、/bin、/usr/sbin、/sbin 這些目錄下依次尋找是否存在我們輸入的那個命令(如果存在則執行),將 MySQL 安裝目錄下的bin目錄的路徑也加入到 PATH 中:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/mysql/bin
這樣現在不論我們所處的工作目錄是啥,我們都可以直接輸入可執行文件的名字就可以啓動它,比如這樣:
mysqld
啓動 MySQL 服務器程序
- mysqld
mysqld 這個可執行文件就代表着 MySQL 服務器程序,運行這個可執行文件就可以直接啓動一個服務器進程,另外還有mysqld_safe、mysql.server、mysqld_multi 等啓動命令,之前倒沒怎麼用過。
這裏穿插一下 Windows 服務(之前沒了解過)
- Windows 服務
如果需要長時間的運行某個程序,並且在計算機啓動的時候便啓動它,一般我們都會把它註冊爲一個 Windows 服務,操作系統會幫我們管理它。把某個程序註冊爲 Windows 服務的方式挺簡單,如下:
"完整的可執行文件路徑" --install [-manual] [服務名]
其中的 -manual 可以省略,加上它的話表示在 Windows 系統啓動的時候不自動啓動該服務,否則會自動啓動。服務名也可以省略,默認的服務名就是 MySQL。比如我的 Windows 計算機上 mysqld 的完整路徑是:
C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld
所以如果我們想把它註冊爲服務的話可以在命令行裏這麼寫:
"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld" --install
在把 mysqld 註冊爲 Windows 服務之後,我們就可以通過下邊這個命令來啓動 MySQL 服務器程序了:
net start MySQL
關閉這個服務也非常簡單,只要把上邊的 start 換成 stop 就行了:
net stop MySQL
啓動 MySQL 客戶端程序
在成功啓動 MySQL 服務器程序後,就可以接着啓動客戶端程序來連接到這個服務器了,這裏主要使用 bin 目錄下的可執行文件 mysql。啓動這個可執行文件時一般需要一些參數,格式如下:
mysql -h主機名 -u用戶名 -p密碼
按照你的情況填寫就可以啓動 MySQL 客戶端,並且連接到服務器了。
mysql -hlocalhost -uroot -p123456
連接成功後的界面:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21 Homebrew
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
最後一行的 mysql> 是一個客戶端的提示符,之後客戶端發送給服務器的命令都需要寫在這個提示符後邊。
如果需要斷開連接並且關閉客戶端的話,可以在 mysql> 提示符後輸入下邊任意一個命令:
- quit
- exit
- \q
mysql> quit
Bye
- 服務器處理客戶端請求
大部分服務器程序處理來自客戶端的查詢請求需要經過三個部分,分別是連接管理、解析與優化、存儲引擎。
連接管理
每當有客戶端斷開連接,服務器並不會立即把與該客戶端交互的線程銷燬掉,而是把它緩存起來,從而節省開銷。
如果客戶端程序和服務器程序不運行在一臺計算機上,可以採用使用了 SSL(安全套接字)的網絡連接進行通信,來保證數據傳輸的安全性。
當連接建立後,服務器線程會一直等待客戶端發送過來的請求,MySQL 服務器接收到的請求只是一個文本消息,想執行該文本消息還要經過各種解析和優化。
解析與優化
拿到了文本形式的請求,還需要經過幾個重要的過程,分別是查詢緩存、語法解析和查詢優化
- 查詢緩存
如果我問你 123 × 456 = ?,你可能會動腦去算一下,得到了結果 56088,如果我再問你一遍 123 × 456 = ?我們便可以跳過計算過程直接說答案就好了(緩存)。MySQL 也會把剛剛處理過的查詢請求和結果緩存起來,並且這個查詢緩存可以在不同客戶端之間共享。
緩存失效的情況:①任何字符上的不同(例如:空格、註釋、大小寫) ②包含系統函數、用戶自定義變量和函數、一些系統表 ③表的結構或者數據被修改。
- 語法解析
從指定的文本中提取出我們需要的信息本質上算是一個編譯過程,涉及詞法解析、語法分析、語義分析等階段。
- 查詢優化
語法解析之後,已經知道了要查詢的列是哪些,表是哪個,搜索條件是什麼等,但 SQL 語句執行起來的效率可能不高,MySQL 的優化程序會對我們的語句做一些優化,如外連接轉換爲內連接、表達式簡化、子查詢轉爲連接等。優化的結果就是生成一個執行計劃,這個執行計劃表明了應該使用哪些索引進行查詢,表之間的連接順序是怎樣的,執行計劃可用 EXPLAIN 語句查看。
存儲引擎
截止到服務器程序完成了查詢優化爲止,還沒有真正的去訪問真實的數據表,MySQL服務器把數據的存儲和提取操作都封裝到了一個叫存儲引擎的模塊裏。我們知道表是由一行一行的記錄組成的,但這只是一個邏輯上的概念,物理上如何表示記錄,怎麼從表中讀取數據,怎麼把數據寫入具體的物理存儲器上,這都是存儲引擎負責的事情。爲了實現不同的功能,MySQL 提供了各式各樣的存儲引擎,不同存儲引擎管理的表具體的存儲結構可能不同,採用的存取算法也可能不同。
常用的存儲引擎有 InnoDB、MyISAM 和 Memory(置於內存的表)
關於存儲引擎的一些操作
查看當前服務器程序支持的存儲引擎:
SHOW ENGINES;
設置表的存儲引擎
前邊說過,存儲引擎是負責對錶中的數據進行提取和寫入工作的,我們可以爲不同的表設置不同的存儲引擎,也就是說不同的表可以有不同的物理存儲結構,不同的提取和寫入方式。
創建表時指定存儲引擎:
CREATE TABLE 表名(
建表語句;
) ENGINE = 存儲引擎名稱;
比如想創建一個存儲引擎爲 MyISAM 的表可以這麼寫:
mysql> CREATE TABLE engine_demo_table(
-> i int
-> ) ENGINE = MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql>
修改表的存儲引擎
如果表已經建好了,可以使用下邊這個語句來修改表的存儲引擎:
ALTER TABLE 表名 ENGINE = 存儲引擎名稱;
比如我們修改一下 engine_demo_table 表的存儲引擎:
mysql> ALTER TABLE engine_demo_table ENGINE = InnoDB;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
這時再查看一下 engine_demo_table 的表結構:
mysql> SHOW CREATE TABLE engine_demo_table\G
*************************** 1. row ***************************
Table: engine_demo_table
Create Table: CREATE TABLE `engine_demo_table` (
`i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
mysql>
可以看到該表的存儲引擎已經改爲 InnoDB 了。