09.11 乾貨分享|37個MySQL數據庫小技巧,新人必知!

無論是運維、開發、測試,還是架構師,數據庫技術是一個必備加薪神器,那麼,一直說學習數據庫、學MySQL,到底是要學習它的哪些東西呢?

1、如何快速掌握MySQL?

培養興趣

興趣是最好的老師,不論學習什麼知識,興趣都可以極大地提高學習效率。當然學習MySQL 5.6也不例外。

夯實基礎

計算機領域的技術非常強調基礎,剛開始學習可能還認識不到這一點,隨著技術應用的深 入,只有有著紮實的基礎功底,才能在技術的道路上走得更快、更遠。對於MySQL的學習來說, SQL語句是其中最為基礎的部分,很多操作都是通過SQL語句來實現的。所以在學習的過程中, 讀者要多編寫SQL語句,對於同一個功能,使用不同的實現語句來完成,從而深刻理解其不同之處。

及時學習新知識

正確、有效地利用搜索引擎,可以搜索到很多關於MySQL 5.6的相關知識。同時,參考別 人解決問題的思路,也可以吸取別人的經驗,及時獲取最新的技術資料。

多實踐操作

數據庫系統具有極強的操作性,需要多動手上機操作。在實際操作的過程中才能發現問題, 並思考解決問題的方法和思路,只有這樣才能提高實戰的操作能力。

2、如何選擇服務器的類型?

MySQL服務器配置窗口中各個參數的含義如下。

【Server Configuration Type】該選項用於設置服務器的類型。單擊該選項右側的向下按鈕, 即可看到包括3個選項。

3個選項的具體含義如下:
  • Development Machine(開發機器):該選項代表典型個人用桌面工作站。假定機器上運行 著多個桌面應用程序。將MySQL服務器配置成使用最少的系統資源。
  • Server Machine (服務器):該選項代表服務器,MySQL服務器可以同其它應用程序一起 運行,例如FTP、email和web服務器。MySQL服務器配置成使用適當比例的系統資源。
  • DedicatedMySQL Server Machine (專用 MySQL 服務器):該選項代表只運行MySQL服務的服務器。假定運行沒有運行其它應用程序。MySQL服務器配置成使用所有可用系統資源。作為初學者,建議選擇【DevelopmentMachine】(開發者機器)選項,這樣佔用系統的資源 比較少。

3、如何選擇存儲引擎

不同存儲引擎都有各自的特點,以適應不同的需求,如下表所示。為了做出選擇:

  • 首先需 要考慮每一個存儲引擎提供了哪些不同的功能。如果要提供提交,回滾和崩潰恢復能力的事務安全(ACID兼容)能力,並要求實現併發控 制,InnoDB是個很好的選擇。如果數據表主要用來插入和查詢記錄,則MyISAM引擎能提供較 高的處理效率;如果只是臨時存放數據,數據量不大,並且不需要較高的數據安全性,可以選擇將數據保存在內存中的Memory引擎,MySQL中使用該引擎作為臨時表,存放查詢的中間結果。如果只有INSERT和SELECT操作,可以選擇Archive引擎,Archive存儲引擎支持高併發的插 入操作,但是本身並不是事務安全的。Archive存儲引擎非常適合存儲歸檔數據,如記錄日誌信 息可以使用Archive引擎。
  • 使用哪一種引擎要根據需要靈活選擇,一個數據庫中多個表可以使用不同引擎以滿足各種性能和實際需求。
  • 使用合適的存儲引擎,將會提高整個數據庫的性能。

4、如何查看默認存儲引擎?

使用SHOW ENGINES語句查看系統中所有的存儲引擎,其中包括默認的存儲引擎。可以看出來當前數據庫系統中有五種存儲引擎,默認是MyISAM。還可以使用一種直接的方法查看默認存儲引擎。執行結果直接顯示了當前默認的存儲引擎為MyISAM。

5、表刪除操作須謹慎

表刪除操作將把表的定義和表中的數據一起刪除,並且MySQL在執行刪除操作時,不會有 任何的確認信息提示,因此執行刪除操時,應當慎重。在刪除表前,最好對錶中的數據進行備份, 這樣當操作失誤時,可以對數據進行恢復,以免造成無法挽回的後果。同樣的,在使用ALTER TABLE進行表的基本修改操作時,在執行操作過程之前,也應該 確保對數據進行完整的備份,因為數據庫的改變是無法撤銷的,如果添加了一個不需要的字段, 可以將其刪除;相同的,如果刪除了一個需要的列,該列下面的所有數據都將會丟失。

6、每個表中都要有一個主鍵嗎?

並不是每一個表中都需要主鍵,一般的,如果多個表之間進行連接操作時,需要用到主鍵。 因此並不需要為每個表建立主鍵,而且有些情況最好不使用主鍵。

7、每個表都可以任意選擇存儲引擎嗎?

外鍵約束(FOREIGN KEY)不能跨引擎使用。MySQL支持多種存儲引擎,每一個表都可 以指定一個不同的存儲引擎,但是要注意:外鍵約束是用來保證數據的參照完整性,如果表之間 需要關聯外鍵,卻指定了不同的存儲引擎,這些表之間是不能創建外鍵約束的。所以說,存儲引 擎的選擇也不完全是隨意的。

8、帶AUTO_INCREMENT約束的字段值是從1開始的嗎?

默認的,在MySQL中,AUTO_INCREMENT的初始值是1,每新增一條記錄,字段值自動加1。設置自增屬性(AUTO_INCREMENT)的時候,還可以指定第一條插入記錄的自增字段的 值,這樣新插入的記錄的自增字段值從初始值開始遞增,如在tb_emp8中插入第一條記錄,同時 指定id值為5,則以後插入的記錄的id值就會從6開始往上增加。添加唯一性的主鍵約束時, 往往需要設置字段自動增加屬性。

9、TIMESTAMP與DATATIME兩者的區別

TIMESTAMP與DATETIME除了存儲字節和支持的範圍不同外,還有一個最大的區別就是: DATETIME在存儲日期數據時,按實際輸入的格式存儲,即輸入什麼就存儲什麼,與時區無關; 而TIMESTAMP值的存儲是以UTC(世界標準時間)格式保存的,存儲時對當前時區進行轉換, 檢索時再轉換回當前時區。即查詢時,根據當前時區的不同,顯示的時間值是不同的。

10、選擇數據類型的方法和技巧是什麼?

MySQL提供了大量的數據類型,為了優化存儲,提高數據庫性能,在任何情況下均應使用 最精確的類型。即在所有可以表示該列值的類型中,該類型使用的存儲最少。

整數和浮點數

如果不需要小數部分,則使用整數來保存數據;如果需要表示小數部分,則使用浮點數類 型。對於浮點數據列,存入的數值會對該列定義的小數位進行四捨五入。例如如果列的值的範 圍為1〜99999,若使用整數,則MEDIUMINT UNSIGNED是最好的類型;若需要存儲小數,則 使用FLOAT類型。浮點類型包括FLOAT和DOUBLE類型。DOUBLE類型精度比FLOAT類型高,因此,如要求存儲精度較高時,應選擇DOUBLE類型。

浮點數和定點數

浮點數FLOAT,DOUBLE相對於定點數DECIMAL的優勢是:在長度一定的情況下,浮點 數能表示更大的數據範圍。但是由於浮點數容易產生誤差,因此對精確度要求比較高時,建議使 用DECIMAL來存儲。DECIMAL在MySQL中是以字符串存儲的,用於定義貨幣等對精確度要 求較高的數據。在數據遷移中,float(M,D)是非標準SQL定義,數據庫遷移可能會出現問題,最 好不要這樣使用。另外兩個浮點數進行減法和比較運算時也容易出問題,因此在進行計算的時候, 一定要小心。如果進行數值比較,最好使用DECIMAL類型。

日期與時間類型

MySQL對於不同種類的日期和時間有很多的數據類型,比如YEAR和TIME。如果只需要 記錄年份,則使用YEAR類型即可;如果只記錄時間,只須使用TIME類型。如果同時需要記錄日期和時間,則可以使用TIMESTAMP或者DATETIME類型。由於 TIMESTAMP列的取值範圍小於DATETIME的取值範圍,因此存儲範圍較大的日期最好使用 DATETIME。TIMESTAMP也有一個DATETIME不具備的屬性。默認的情況下,當插入一條記錄但並沒 有指定TIMESTAMP這個列值時,MySQL會把TIMESTAMP列設為當前的時間。因此當需要 插入記錄同時插入當前時間時,使用TIMESTAMP是方便的,另外TIMESTAMP在空間上比 DATETIME更有效。

CHAR與VARCHAR之間的特點與選擇

CHAR和VARCHAR的區別:
  • CHAR是固定長度字符,VARCHAR是可變長度字符;CHAR會自動刪除插入數據的尾部 空格,VARCHAR不會刪除尾部空格。
  • CHAR是固定長度,所以它的處理速度比VARCHAR的速度要快,但是它的缺點就是浪費 存儲空間。所以對存儲不大,但在速度上有要求的可以使用CHAR類型,反之可以使用 VARCHAR類型來實現。
存儲引擎對於選擇CHAR和VARCHAR的影響:
  • 對於MyISAM存儲引擎:最好使用固定長度的數據列代替可變長度的數據列。這樣可以使 整個表靜態化,從而使數據檢索更快,用空間換時間。
  • 對於InnoDB存儲引擎:使用可變長度的數據列,因為InnoDB數據表的存儲格式不分固定 長度和可變長度,因此使用CHAR不一定比使用VARCHAR更好,但由於VARCHAR是按照 實際的長度存儲,比較節省空間,所以對磁盤I/O和數據存儲總量比較好。

ENUM 和 SET

ENUM只能取單值,它的數據列表是一個枚舉集合。它的合法取值列表最多允許有65 535 個成員。因此,在需要從多個值中選取一個時,可以使用ENUM。比如:性別字段適合定義為 ENUM類型,每次只能從’男’或’女’中取一個值。SET可取多值。它的合法取值列表最多允許有64個成員。空字符串也是一個合法的SET值。 在需要取多個值的時候,適合使用SET類型,比如:要存儲一個人興趣愛好,最好使用SET類型。ENUM和SET的值是以字符串形式出現的,但在內部,MySQL以數值的形式存儲它們。

BLOB 和 TEXT

BLOB是二進制字符串,TEXT是非二進制字符串,兩者均可存放大容量的信息。BLOB主 要存儲圖片、音頻信息等,而TEXT只能存儲純文本文件。應分清兩者的用途。

11、MySQL中如何使用特殊字符?

諸如單引號(’),雙引號("),反斜線()等符號,這些符號在MySQL中不能直接輸入 使用,否則會產生意料之外的結果。在MySQL中,這些特殊字符稱為轉義字符,在輸入時需要 以反斜線符號(’\\’)開頭,所以在使用單引號和雙引號時應分別輸入(\\’)或者(\\"),輸入反 斜線時應該輸入(\\),其他特殊字符還有回車符(\\r),換行符(\\n),製表符(\\tab),退格 符(\\b)等。在向數據庫中插入這些特殊字符時,一定要進行轉義處理。

12、MySQL中可以存儲文件嗎?

MySQL中的BLOB和TEXT字段類型可以存儲數據量較大的文件,可以使用這些數據類型 存儲圖像、聲音或者是大容量的文本內容,例如網頁或者文檔。雖然使用BLOB或者TEXT可 以存儲大容量的數據,但是對這些字段的處理會降低數據庫的性能。如果並非必要,可以選擇只 儲存文件的路徑。

13、MySQL中如何執行區分大小寫的字符串比較?

在Windows平臺下,MySQL是不區分大小的,因此字符串比較函數也不區分大小寫。如果 想執行區分大小寫的比較,可以在字符串前面添加BINARY關鍵字。例如默認情況下,’a’=‘A’ 返回結果為1,如果使用BINARY關鍵字,BINARY’a’=‘A’結果為0,在區分大小寫的情況下,’a’ 與’A’並不相同。

14、如何從日期時間值中獲取年、月、日等部分日期或時間值?

MySQL中,日期時間值以字符串形式存儲在數據表中,因此可以使用字符串函數分別截取日期時間值的不同部分,例如某個名稱為dt的字段有值“2010-10-01 12:00:30”,如果只需要獲 得年值,可以輸入LEFT(dt, 4),這樣就獲得了字符串左邊開始長度為4的子字符串,即YEAR 部分的值;如果要獲取月份值,可以輸入MID(dt,6,2),字符串第6個字符開始,長度為2的子 字符串正好為dt中的月份值。同理,讀者可以根據其他日期和時間的位置,計算並獲取相應的值。

15、如何改變默認的字符集?

CONVERT()函數改變指定字符串的默認字符集,在開始的章節中,向讀者介紹使用GUI圖形化安裝配置工具進行MySQL的安裝和配置,其中的一個步驟是可以選擇MySQL的默認字符集。但是,如果只改變字符集,沒有必要把配置過程重新執行一遍,在這裡,一個簡單的方式是 修改配置文件。在Windows中,MySQL配置文件名稱為my.ini,該文件在MySQL的安裝目錄下面。修改配置文件中的default-character-set和character-set-server參數值,將其改為想要的字 符集名稱,如gbk、gb2312、latinl等,修改完之後重新啟動MySQL服務,即可生效。讀者可以在修改字符集時使用SHOW VARIABLES LIKE ’character_set_°%’;命令查看當前字符集,以進行對比。

16、DISTINCT可以應用於所有的列嗎?

查詢結果中,如果需要對列進行降序排序,可以使用DESC,這個關鍵字只能對其前面的列 進行降序排列。例如,要對多列都進行降序排序,必須要在每一列的列名後面加DESC關鍵字。 而DISTINCT不同,DISTINCT不能部分使用。換句話說,DISTINCT關鍵字應用於所有列而不 僅是它後面的第一個指定列。例如,查詢3個字段s_id,f_name,f_price,如果不同記錄的這3個字段的組合值都不同,則所有記錄都會被查詢出來。

17、ORDER BY可以和LIMIT混合使用嗎?

在使用ORDER BY子句時,應保證其位於FROM子句之後,如果使用LIMIT,則必須位 於ORDER BY之後,如果子句順序不正確,MySQL將產生錯誤消息。

18、什麼時候使用引號?

在查詢的時候,會看到在WHERE子句中使用條件,有的值加上了單引號,而有的值未加。 單引號用來限定字符串,如果將值與字符串類型列進行比較,則需要限定引號;而用來與數值進 行比較則不需要用引號。

19、在WHERE子句中必須使用圓括號嗎?

任何時候使用具有AND和OR操作符的WHERE子句,都應該使用圓括號明確操作順序。 如果條件較多,即使能確定計算次序,默認的計算次序也可能會使SQL語句不易理解,因此使 用括號明確操作符的次序,是一個好的習慣。

20、更新或者刪除表時必須指定WHERE子句嗎?

在前面章節中可以看到,所有的UPDATE和DELETE語句全都在WHERE子句中指定了條 件。如果省略WHERE子句,則UPDATE或DELETE將被應用到表中所有的行。因此,除非 確實打算更新或者刪除所有記錄,否則要注意使用不帶WHERE子句的UPDATE或DELETE 語句。建議在對錶進行更新和刪除操作之前,使用SELECT語句確認需要刪除的記錄,以免造 成無法挽回的結果。

21、索引對數據庫性能如此重要,應該如何使用它?

為數據庫選擇正確的索引是一項複雜的任務。如果索引列較少,則需要的磁盤空間和維護開銷 都較少。如果在一個大表上創建了多種組合索引,索引文件也會膨脹很快。而另一方面,索引較多 可覆蓋更多的查詢。可能需要試驗若干不同的設計,才能找到最有效的索引。可以添加、修改和刪 除索引而不影響數據庫架構或應用程序設計。因此,應嘗試多個不同的索引從而建立最優的索引。

22、儘量使用短索引。

對字符串類型的字段進行索引,如果可能應該指定一個前綴長度。例如,如果有一個 CHAR(255)的列,如果在前10個或30個字符內,多數值是惟一的,則不需要對整個列進行索引。 短索引不僅可以提高查詢速度而且可以節省磁盤空間、減少I/O操作。

23、MySQL存儲過程和函數有什麼區別?

在本質上它們都是存儲程序。函數只能通過return語句返回單個值或者表對象;而存儲過程 不允許執行return,但是可以通過out參數返回多個值。函數限制比較多,不能用臨時表,只能用表變量,還有一些函數都不可用等等;而存儲過程的限制相對就比較少。函數可以嵌入在SQL 語句中使用,可以在SELECT語句中作為查詢語句的一個部分調用;而存儲過程一般是作為一個獨立的部分來執行。

24、存儲過程中的代碼可以改變嗎?

目前,MySQL還不提供對已存在的存儲過程代碼的修改,如果必須要修改存儲過程,必須使用DROP語句刪除之後,再重新編寫代碼,或者創建一個新的存儲過程。

25、存儲過程中可以調用其他存儲過程嗎?

存儲過程包含用戶定義的SQL語句集合,可以使用CALL語句調用存儲過程,當然在存儲 過程中也可以使用CALL語句調用其他存儲過程,但是不能使用DROP語句刪除其他存儲過程。

26、存儲過程的參數不要與數據表中的字段名相同。

在定義存儲過程參數列表時,應注意把參數名與數據庫表中的字段名區別開來,否則將出 現無法預期的結果。

27、存儲過程的參數可以使用中文嗎?

一般情況下,可能會出現存儲過程中傳入中文參數的情況,例如某個存儲過程根據用戶的 名字查找該用戶的信息,傳入的參數值可能是中文。這時需要在定義存儲過程的時候,在後面加 上character set gbk,不然調用存儲過程使用中文參數會出錯,比如定義userInfo存儲過程,代碼 如下:

CREATE PROCEDURE useInfo(IN u_name VARCHAR(50) character set gbk, OUT u_age INT)

28、MySQL中視圖和表的區別以及聯繫是什麼?

兩者的區別:

  • (1)視圖是已經編譯好的SQL語句,是基於SQL語句的結果集的可視化的表,而表不是。
  • (2)視圖沒有實際的物理記錄,而基本表有。
  • (3)表是內容,視圖是窗口。
  • (4)表佔用物理空間而視圖不佔用物理空間,視圖只是邏輯概念的存在,表可以及時對它 進行修改,但視圖只能用創建的語句來修改。
  • (5)視圖是查看數據表的一種方法,可以查詢數據表中某些字段構成的數據,只是一些SQL 語句的集合。從安全的角度來說,視圖可以防止用戶接觸數據表,因而用戶不知道表結構。
  • (6)表屬於全局模式中的表,是實表;視圖屬於局部模式的表,是虛表。
  • (7)視圖的建立和刪除隻影響視圖本身,不影響對應的基本表。

兩者的聯繫:

  • 視圖(view)是在基本表之上建立的表,它的結構(即所定義的列)和內容(即所有記錄) 都來自基本表,它依據基本表存在而存在。一個視圖可以對應一個基本表,也
  • 可以對應多個基本 表。視圖是基本表的抽象和在邏輯意義上建立的新關係。

29、使用觸發器時須特別注意。

在使用觸發器的時候需要注意,對於相同的表,相同的事件只能創建一個觸發器,比如對 表account創建了一個BEFORE INSERT觸發器,那麼如果對錶account再次創建一個BEFORE INSERT觸發器,MySQL將會報錯,此時,只可以在表account上創建AFTER INSERT或者 BEFORE UPDATE類型的觸發器。靈活的運用觸發器將為操作省去很多麻煩。

30、及時刪除不再需要的觸發器。

觸發器定義之後,每次執行觸發事件,都會激活觸發器並執行觸發器中的語句。如果需求 發生變化,而觸發器沒有進行相應的改變或者刪除,則觸發器仍然會執行舊的語句,從而會影響 新的數據的完整性。因此,要將不再使用的觸發器及時刪除。

31、應該使用哪種方法創建用戶?

創建用戶有幾種方法:GRANT語句、CREATE USER語句和直接操作user表。一般情況, 最好使用GRANT或者CREATE USER語句,而不要直接將用戶信息插入user表,因為user表中存儲了全局級別的權限以及其他的賬戶信息,如果意外破壞了 user表中的記錄,則可能會對 MySQL服務器造成很大影響。

32、mysqldump備份的文件只能在MySQL中使用嗎?

mysqldump備份的文本文件實際是數據庫的一個副本,使用該文件不僅可以在MySQL中恢 複數據庫,而且通過對該文件的簡單修改,可以使用該文件在SQL Server或者Sybase等其他數 據庫中恢復數據庫。這在某種程度上實現了數據庫之間的遷移。

33、如何選擇備份工具?

直接複製數據文件是最為直接、快速的備份方法,但缺點是基本上不能實現增量備份。備 份時必須確保沒有使用這些表。如果在複製一個表的同時服務器正在修改它,則複製無效。備份 文件時,最好關閉服務器,然後重新啟動服務器。為了保證數據的一致性,需要在備份文件前, 執行以下SQL語句:

CREATE PROCEDURE useInfo(IN u_name VARCHAR(50) character set gbk, OUT u_age INT)

目錄下即可。mysqlhotcopy 是一個 PERL 程序,它使用 LOCK TABLES、FLUSH TABLES 和 cp 或 scp來快速備份數據庫。它是備份數據庫或單個表的最快的途徑,但它只能運行在數據庫文件所在的 機器上,並且mysqlhotcopy只能用於備份MyISAM表。mysqlhotcopy適合於小型數據庫的備份, 數據量不大,可以使用mysqlhotcopy程序每天進行一次完全備份。mysqldump將數據表導成SQL腳本文件,在不同的MySQL版本之間升級時相對比較合適, 這也是最常用的備份方法。mysqldump比直接複製要慢些。也就是把內存中的數據都刷新到磁盤中,同時鎖定數據表,以保證複製過程中不會有新的 數據寫入。這種方法備份出來的數據恢復也很簡單,直接複製回原來的數據庫

34、平時應該打開哪些日誌?

日誌既會影響MySQL的性能,又會佔用大量磁盤空間。因此,如果不必要,應儘可能少地 開啟日誌。根據不同的使用環境,可以考慮開啟不同的日誌。例如,在開發環境中優化查詢效率 低的語句,可以開啟慢查詢日誌;如果需要記錄用戶的所有查詢操作,可以開啟通用查詢日誌; 如果需要記錄數據的變更,可以開啟二進制日誌;錯誤日誌是默認開啟的。

35、如何使用二進制日誌?

二進制日誌主要用來記錄數據變更。如果需要記錄數據庫的變化,可以開啟二進制日誌。 基於二進制日誌的特性,不僅可以用來進行數據恢復,還可用於數據複製。在數據庫定期備份的 情況下,如果出現數據丟失,可以先用備份恢復大部分數據,然後使用二進制日誌恢復最近備份 後變更的數據。在雙機熱備情況下,可以使用MySQL的二進制日誌記錄數據的變更,然後將變 更部分複製到備份服務器上。

36、如何使用慢查詢日誌?

慢查詢日誌主要用來記錄查詢時間較長的日誌。在開發環境下,可以開啟慢查詢日誌來記 錄查詢時間較長的查詢語句,然後對這些語句進行優化。通過配long_query_time的值,可以靈活地掌握不同程度的慢查詢語句。

37、是不是索引建立得越多越好?

合理的索引可以提高查詢的速度,但不是索引越多越好。在執行插入語句的時候,MySQL 要為新插入的記錄建立索引。所以過多的索引會導致插入操作變慢。原則上是隻有查詢用的字段 才建立索引。


分享到:


相關文章: