咱們在 MySQL 入門篇主要介紹了基本的 SQL 命令、數據類型和函數,在局部以上知識後,你就能夠進行 MySQL 的開發工做了,可是若是要成爲一個合格的開發人員,你還要具有一些更高級的技能,下面咱們就來探討一下 MySQL 都須要哪些高級的技能mysql
數據庫最核心的一點就是用來存儲數據,數據存儲就避免不了和磁盤打交道。那麼數據以哪一種方式進行存儲,如何存儲是存儲的關鍵所在。因此存儲引擎就至關因而數據存儲的發動機,來驅動數據在磁盤層面進行存儲。算法
MySQL 的架構能夠按照三層模式來理解sql
存儲引擎也是 MySQL 的組建,它是一種軟件,它所能作的和支持的功能主要有數據庫
MySQL 默認支持多種存儲引擎,來適用不一樣數據庫應用,用戶能夠根據須要選擇合適的存儲引擎,下面是 MySQL 支持的存儲引擎緩存
默認狀況下,若是建立表不指定存儲引擎,會使用默認的存儲引擎,若是要修改默認的存儲引擎,那麼就能夠在參數文件中設置 default-table-type
,可以查看當前的存儲引擎安全
show variables like 'table_type';
複製代碼
奇怪,爲何沒有了呢?網上求證一下,在 5.5.3 取消了這個參數數據結構
能夠經過下面兩種方法查詢當前數據庫支持的存儲引擎架構
show engines \g
複製代碼
在建立新表的時候,能夠經過增長 ENGINE
關鍵字設置新建表的存儲引擎。併發
create table cxuan002(id int(10),name varchar(20)) engine = MyISAM;
複製代碼
上圖咱們指定了 MyISAM
的存儲引擎。函數
若是你不知道表的存儲引擎怎麼辦?你能夠經過 show create table
來查看
若是不指定存儲引擎的話,從MySQL 5.1 版本以後,MySQL 的默認內置存儲引擎已是 InnoDB了。建一張表看一下
如上圖所示,咱們沒有指定默認的存儲引擎,下面查看一下表
能夠看到,默認的存儲引擎是 InnoDB
。
若是你的存儲引擎想要更換,可使用
alter table cxuan003 engine = myisam;
複製代碼
來更換,更換完成後回顯示 0 rows affected ,但其實已經操做成功
咱們使用 show create table
查看一下表的 sql 就知道
下面會介紹幾個經常使用的存儲引擎以及它的基本特性,這些存儲引擎是 **MyISAM、InnoDB、MEMORY 和 MERGE **
在 5.1 版本以前,MyISAM 是 MySQL 的默認存儲引擎,MyISAM 併發性比較差,使用的場景比較少,主要特色是
不支持事務
操做,ACID 的特性也就不存在了,這一設計是爲了性能和效率考慮的。
不支持外鍵
操做,若是強行增長外鍵,MySQL 不會報錯,只不過外鍵不起做用。
MyISAM 默認的鎖粒度是表級鎖
,因此併發性能比較差,加鎖比較快,鎖衝突比較少,不太容易發生死鎖的狀況。
MyISAM 會在磁盤上存儲三個文件,文件名和表名相同,擴展名分別是 .frm(存儲表定義)
、.MYD(MYData,存儲數據)
、MYI(MyIndex,存儲索引)
。這裏須要特別注意的是 MyISAM 只緩存索引文件
,並不緩存數據文件。
MyISAM 支持的索引類型有 全局索引(Full-Text)
、B-Tree 索引
、R-Tree 索引
Full-Text 索引:它的出現是爲了解決針對文本的模糊查詢效率較低的問題。
B-Tree 索引:全部的索引節點都按照平衡樹的數據結構來存儲,全部的索引數據節點都在葉節點
R-Tree索引:它的存儲方式和 B-Tree 索引有一些區別,主要設計用於存儲空間和多維數據的字段作索引,目前的 MySQL 版本僅支持 geometry 類型的字段做索引,相對於 BTREE,RTREE 的優點在於範圍查找。
數據庫所在主機若是宕機,MyISAM 的數據文件容易損壞,並且難以恢復。
增刪改查性能方面:SELECT 性能較高,適用於查詢較多的狀況
自從 MySQL 5.1 以後,默認的存儲引擎變成了 InnoDB 存儲引擎,相對於 MyISAM,InnoDB 存儲引擎有了較大的改變,它的主要特色是
可重複讀(repetable-read)
、經過MVCC(併發版本控制)
來實現的。可以解決髒讀
和不可重複讀
的問題。行級鎖
,併發性能比較好,會發生死鎖的狀況。.frm文件存儲表結構
定義,可是不一樣的是,InnoDB 的表數據與索引數據是存儲在一塊兒的,都位於 B+ 數的葉子節點上,而 MyISAM 的表數據和索引數據是分開的。MEMORY 存儲引擎使用存在內存中的內容來建立表。每一個 MEMORY 表實際只對應一個磁盤文件,格式是 .frm
。 MEMORY 類型的表訪問速度很快,由於其數據是存放在內存中。默認使用 HASH 索引
。
MERGE 存儲引擎是一組 MyISAM 表的組合,MERGE 表自己沒有數據,對 MERGE 類型的表進行查詢、更新、刪除的操做,其實是對內部的 MyISAM 表進行的。MERGE 表在磁盤上保留兩個文件,一個是 .frm
文件存儲表定義、一個是 .MRG
文件存儲 MERGE 表的組成等。
在實際開發過程當中,咱們每每會根據應用特色選擇合適的存儲引擎。
咱們會常常碰見的一個問題就是,在建表時如何選擇合適的數據類型,一般選擇合適的數據類型可以提升性能、減小沒必要要的麻煩,下面咱們就來一塊兒探討一下,如何選擇合適的數據類型。
char 和 varchar 是咱們常常要用到的兩個存儲字符串的數據類型,char 通常存儲定長的字符串,它屬於固定長度的字符類型,好比下面
值 | char(5) | 存儲字節 |
---|---|---|
'' | ' ' | 5個字節 |
'cx' | 'cx ' | 5個字節 |
'cxuan' | 'cxuan' | 5個字節 |
'cxuan007' | 'cxuan' | 5個字節 |
能夠看到,無論你的值寫的是什麼,一旦指定了 char 字符的長度,若是你的字符串長度不夠指定字符的長度的話,那麼就用空格來填補,若是超過字符串長度的話,只存儲指定字符長度的字符。
這裏注意一點:若是 MySQL 使用了非
嚴格模式
的話,上面表格最後一行是能夠存儲的。若是 MySQL 使用了嚴格模式
的話,那麼表格上面最後一行存儲會報錯。
若是使用了 varchar 字符類型,咱們來看一下例子
值 | varchar(5) | 存儲字節 |
---|---|---|
'' | '' | 1個字節 |
'cx' | 'cx ' | 3個字節 |
'cxuan' | 'cxuan' | 6個字節 |
'cxuan007' | 'cxuan' | 6個字節 |
能夠看到,若是使用 varchar 的話,那麼存儲的字節將根據實際的值進行存儲。你可能會疑惑爲何 varchar 的長度是 5 ,可是卻須要存儲 3 個字節或者 6 個字節,這是由於使用 varchar 數據類型進行存儲時,默認會在最後增長一個字符串長度,佔用1個字節(若是列聲明的長度超過255,則使用兩個字節)。varchar 不會填充空餘的字符串。
通常使用 char 來存儲定長的字符串,好比身份證號、手機號、郵箱等;使用 varchar 來存儲不定長的字符串。因爲 char 長度是固定的,因此它的處理速度要比 VARCHAR 快不少,可是缺點是浪費存儲空間,可是隨着 MySQL 版本的不斷演進,varchar 數據類型的性能也在不斷改進和提升,因此在許多應用中,VARCHAR 類型更多的被使用。
在 MySQL 中,不一樣的存儲引擎對 CHAR 和 VARCHAR 的使用原則也有不一樣
通常在保存較少的文本的時候,咱們會選擇 CHAR 和 VARCHAR,在保存大數據量的文本時,咱們每每選擇 TEXT 和 BLOB;TEXT 和 BLOB 的主要差異是 BLOB 可以保存二進制數據
;而 TEXT 只能保存字符數據
,TEXT 往下細分有
BLOB 往下細分有
三種,它們最主要的區別就是存儲文本長度不一樣和存儲字節不一樣,用戶應該根據實際狀況選擇知足需求的最小存儲類型,下面主要對 BLOB 和 TEXT 存在一些問題進行介紹
TEXT 和 BLOB 在刪除數據後會存在一些性能上的問題,爲了提升性能,建議使用 OPTIMIZE TABLE
功能對錶進行碎片整理。
也可使用合成索引來提升文本字段(BLOB 和 TEXT)的查詢性能。合成索引就是根據大文本(BLOB 和 TEXT)字段的內容創建一個散列值,把這個值存在對應列中,這樣就可以根據散列值查找到對應的數據行。通常使用散列算法好比 md5() 和 SHA1() ,若是散列算法生成的字符串帶有尾部空格,就不要把它們存在 CHAR 和 VARCHAR 中,下面咱們就來看一下這種使用方式
首先建立一張表,表中記錄 blob 字段和 hash 值
向 cxuan005 中插入數據,其中 hash 值做爲 info 的散列值。
而後再插入兩條數據
插入一條 info 爲 cxuan005 的數據
若是想要查詢 info 爲 cxuan005 的數據,能夠經過查詢 hash 列來進行查詢
這是合成索引的例子,若是要對 BLOB 進行模糊查詢的話,就要使用前綴索引。
其餘優化 BLOB 和 TEXT 的方式:
浮點數指的就是含有小數的值,浮點數插入到指定列中超過指定精度後,浮點數會四捨五入,MySQL 中的浮點數指的就是 float
和 double
,定點數指的是 decimal
,定點數可以更加精確的保存和顯示數據。下面經過一個示例講解一下浮點數精確性問題
首先建立一個表 cxuan006 ,只爲了測試浮點數問題,因此這裏咱們選擇的數據類型是 float
而後分別插入兩條數據
而後執行查詢,能夠看到查詢出來的兩條數據執行的舍入不一樣
爲了清晰的看清楚浮點數與定點數的精度問題,再來看一個例子
先修改 cxuan006 的兩個字段爲相同的長度和小數位數
而後插入兩條數據
執行查詢操做,能夠發現,浮點數相較於定點數來講,會產生偏差
在 MySQL 中,用來表示日期類型的有 DATE、TIME、DATETIME、TIMESTAMP,在
這篇文中介紹過了日期類型的區別,咱們這裏就再也不闡述了。下面主要介紹一下選擇
下面來認識一下 MySQL 字符集,簡單來講字符集就是一套文字符號和編碼、比較規則的集合。1960 年美國標準化組織 ANSI 發佈了第一個計算機字符集,就是著名的 ASCII(American Standard Code for Information Interchange)
。自從 ASCII 編碼後,每一個國家、國際組織都研究了一套本身的字符集,好比 ISO-8859-1
、GBK
等。
可是每一個國家都使用本身的字符集爲移植性帶來了很大的困難。因此,爲了統一字符編碼,國際標準化組織(ISO)
指定了統一的字符標準 - Unicode 編碼,它容納了幾乎全部的字符編碼。下面是一些常見的字符編碼
字符集 | 是否認長 | 編碼方式 |
---|---|---|
ASCII | 是 | 單字節 7 位編碼 |
ISO-8859-1 | 是 | 單字節 8 位編碼 |
GBK | 是 | 雙字節編碼 |
UTF-8 | 否 | 1 - 4 字節編碼 |
UTF-16 | 否 | 2 字節或 4 字節編碼 |
UTF-32 | 是 | 4 字節編碼 |
對數據庫來講,字符集是很重要的,由於數據庫存儲的數據大多數都是各類文字,字符集對數據庫的存儲、性能、系統的移植來講都很是重要。
MySQL 支持多種字符集,可使用 show character set;
來查看全部可用的字符集
或者使用
select character_set_name, default_collate_name, description, maxlen from information_schema.character_sets;
複製代碼
來查看。
使用 information_schema.character_set
來查看字符集和校對規則。