MySQL基礎知識總結

1. MySQL基礎

  MySQL數據類型:
    整數 TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT  屬性:UNSIGNED  長度:能夠爲整數類型指定寬度,例如:INT(11),對大多數應用沒有意義,不會限制值的合法範圍,只會影響顯示字符的個數(寬度),不夠則zerofill
    實數 FLOAT, DOUBLE, DECIMAL(可存儲比BIGINT還大的整數,能夠存儲精確的小數)
    字符串 VARCHAR(存儲可變長字符串,比定長類型更節省時間,使用1或2個額外字節記錄字符串的長度,列長度小於255字節使用1個字節表示,不然2個;若是存儲內容超出指定長度,會被截斷), CHAR(定長,根據定義的字符串長度分配足夠的空間;會根據須要採用空格進行填充以方便比較;適合存儲很短的字符串,或者全部值都接近同一個長度;超出設定的長度會被截斷;對於常常變動的數據,CHAR比VARCHAR更好,CHAR不容易產生碎片,對於很是短的列,CHAR比VARCHAR在存儲空間上更有效率,只分配真正須要的空間,更長的列會消耗更多的內存), TEXT, BLOB(儘可能避免使用,查詢會使用臨時表,致使嚴重的性能開銷)
    枚舉:有時可使用枚舉代替經常使用的字符串類型,把不重複的集合存儲成一個預約義的集合,很是緊湊,把列表值壓縮到一個或兩個字節,內部存儲的是整數,儘可能避免使用數字做爲ENUM枚舉的常量,易混亂,排序是按照內部存儲的整數進行排序,枚舉表會使表大小大大減少
    日期和時間:儘可能使用TIMESTAMP,比DATETIME空間效率高;用整數保存時間戳的格式一般不方便處理,若是須要存儲微秒可使用bigint存儲
    列屬性:auto_increment default not null zerofillmysql

  MySQL基礎操做:
    鏈接和關閉:mysql -u -p -h -P  其它:\G \c \q \s \h \d程序員

  MySQL數據表引擎:
    InnoDB表引擎:默認事務型引擎,最重要最普遍的存儲引擎,性能很是優秀;數據存儲在共享表空間,能夠經過配置分開;對主鍵查詢的性能高於其它類型的存儲引擎;內部作了不少優化,從磁盤讀取數據時自動在內存構建hash索引,插入數據時自動構建插入緩衝區;經過一些機制和工具支持真正的熱備份;支持崩潰後的安全恢復;支持行級鎖和外鍵 
    MyISAM表引擎:5.1版本前,MyISAM是默認的存儲引擎;擁有全文、索引、壓縮空間函數;不支持事務和行級鎖,不支持崩潰後的安全恢復;表存儲在兩個文件,MYD和MYI;設計簡單,某些場景下性能很好;
    其餘表引擎:Archive Blackhole CSV Memory算法

  MySQL鎖機制:
    表鎖是平常開發當中常見的問題,當多個查詢同一時刻進行數據修改時,就會產生併發控制的問題。共享鎖和排他鎖,就是讀鎖和寫鎖
    讀鎖:共享的,不堵塞,多個用戶能夠同時讀一個資源,互不干擾
    寫鎖:排他的,會阻塞其它的寫鎖和讀鎖,這樣能夠只容許一我的進行寫入,防止其餘用戶讀取正在寫入的資源
    鎖粒度:表鎖,系統性能開銷最小,會鎖定整張表,MyISAM使用表鎖;行鎖,最大程度支持併發處理,可是也帶來了最大的鎖開銷,InnoDB實現行級鎖sql

  MySQL事務處理:
    提供事務處理的表引擎,InnoDB;服務器層無論理事務,由下層的引擎實現,因此同一個事務中,使用多種存儲引擎不靠譜;在非事務的表上執行事務操做MySQL不會發出提醒,也不會報錯數據庫

  MySQL存儲過程:
    爲之後的使用而保存的一條或多條MySQL語句的集合;存儲過程就是有業務邏輯和流程的集合;能夠在存儲過程當中建立表,更新數據,刪除等等;經過把處理封裝在容易使用的單元中,簡化複雜的操做,保證數據的一致性,簡化對變更的管理緩存

  MySQL觸發器:
    提供給程序員和數據分析員來保證數據完整性的一種方法,是與表事件相關的特殊的存儲過程;可經過數據庫中的相關表實現級聯更改;實時監控某張表中的某個字段的更改而須要作出相應的處理;某些業務編號的生成等;濫用會形成數據庫及應用程序的維護困難安全

2. 建立高性能索引

  MySQL索引的基礎和類型
    索引的基礎:索引相似於書籍的目錄,存儲引擎使用相似的方式進行數據查詢,先去索引當中找到對應的值,而後根據匹配的索引找到對應的數據行
    索引對性能的影響:大大減小服務器須要掃描的數據量;幫助服務器避免排序和臨時表,將隨機I/O變順序I/O;大大提升查詢速度,下降寫的速度、佔用磁盤
    索引的使用場景:對於很是小的表,大部分狀況下全表掃描效率更高;中到大型表,索引很是有效;特大型的表,創建和使用索引的代價將隨之增加,可使用分區技術來解決
    索引的類型:都是實如今存儲引擎層的
      普通索引:最基本的索引,沒有任何約束限制
      惟一索引:與普通索引相似,可是具備惟一性約束
      主鍵索引:特殊的惟一索引,不容許有空值;一個表只能有一個主鍵索引,能夠有多個惟一索引;主鍵能夠與外鍵構成參照完整性約束,防止數據不一致
      組合索引:將多個列組合在一塊兒建立索引,能夠覆蓋多個列
      外鍵索引:只有InnoDB類型的表可使用,保證數據的一致性、完整性和實現級聯操做
      全文索引:MySQL自帶的全文索引只能用於MyISAM,而且只能對英文進行全文檢索服務器

  MySQL索引的建立原則
    最適合索引的列是出如今WHERE子句中的列,或鏈接子句中的列而不是出如今SELECT後的列;索引列的基數越大,索引的效果越好;對字符串進行索引,應該制定一個前綴長度,能夠節省大量的索引空間;根據狀況建立複合索引,能夠提升查詢效率;避免建立過多索引,會額外佔用磁盤空間,下降寫操做效率;主鍵儘量選擇較短的數據類型,能夠有效減小索引的磁盤佔用提升查詢效率併發

  MySQL索引的注意事項
    複合索引遵循前綴原則;like查詢,%不能在前,可使用全文索引;column is null可使用索引;若是MySQL估計使用索引比全表掃描更慢,會放棄使用索引;若是or前的條件中的列有索引,後面的沒有,索引都不會被用到;列類型是字符串,查詢時必定要給值加引號,不然索引失效負載均衡

3. SQL語句編寫

  關聯更新:UPDATE A,B SET A.c1 = B.c1,A.c2 = B.c2 WHERE A.id = B.id
    UPDATE A INNER JOIN B ON A.id = B.id SET A.c1 = B.c1,A.c2 = B.c2 WHERE...... 

  6種關聯查詢:交叉鏈接CROSS JOIN,
    內鏈接INNER JOIN:SELECT * FROM A,B WHERE A.id=B.id 或者SELECT * FROM A INNER JOIN B ON A.id = B.id。多表中同時符合某種條件的數據記錄的集合。分爲等值鏈接,不等值鏈接,自鏈接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid

    外鏈接LEFT/RIGHT JOIN:以左表爲主,先查詢出左表,按照ON後的關聯條件匹配右表,沒有匹配到的用NULL填充
    聯合查詢UNION與UNION ALL:SELECT * FROM A UNION SELECT * FROM B UNION ......。就是把多個結果集集中在一塊兒,UNION前的結果爲基準,須要注意的是聯合查詢的列數要相等,相同的記錄行會合並;若是使用UNION ALL則不會合並重復的記錄行
    全鏈接FULL JOIN:MySQL不支持全鏈接,可使用LEFT JOIN和RIGHT JOIN和UNION聯合使用:SELECT * FROM A LEFT JION B ON A.id=B.id UNION SELECT * FROM A RIGHT JION B ON A.id=B.id
    嵌套查詢:用一條SQL語句的結果做爲另一條SQL語句的條件,如SELECT * FROM A WHERE id IN (SELECT id FROM B)

4. 查詢優化

  查找分析查詢速度慢的緣由
    分析SQL查詢慢的方法:
    記錄慢查詢日誌;分析查詢日誌,不要直接打開慢查詢日誌進行分析,這樣比較浪費時間和精力,可使用pt-query-digest工具進行分析
    使用show profile:set profiling=1;開啓,服務器上執行的全部語句會檢測消耗的時間,存到臨時表中;show profiles;show profile for query 臨時表ID
    使用show status:會返回一些計數器,show global status查看服務器級別的全部計數;有時根據這些計數,能夠猜想出哪些操做代價較高或者消耗時間多
    使用show  processlist:觀察是否有大量線程處於不正常的狀態或者特徵
    使用explain\desc:分析單條SQL語句

  優化查詢過程當中的數據訪問:訪問數據太多致使查詢性能降低;肯定應用程序是否在檢索大量超過須要的數據,多是太多行或列;確認MySQL服務器是否在分析大量沒必要要的數據行
    避免使用以下SQL語句:查詢不須要的記錄,使用limit解決;多表關聯返回所有列,指定A.id,A.name,B.age;老是取出所有列,SELECT * 會讓優化器沒法完成索引覆蓋掃描的優化
    重複查詢相同的數據,能夠緩存數據,下次直接讀取緩存
    是否在掃描額外的記錄:使用explain進行分析,若是發現查詢須要掃描大量的數據但只返回少數的行,能夠經過以下技巧去優化:使用索引覆蓋掃描,把全部用的列都放到索引中,這樣存儲引擎不須要回表獲取對應行就能夠返回結果;改變數據庫和表的結構,修改數據表範式;重寫SQL語句,讓優化器能夠以更優的方式執行查詢

  優化長難的查詢語句:
    一個複雜查詢仍是多個簡單查詢:MySQL內部每秒能掃描內存中上百萬行數據,相比之下,響應數據給客戶端就要慢得多;使用盡量少的查詢是好的,可是有時將一個大的查詢分解爲多個小的查詢是頗有必要的
    切分查詢:將一個大的查詢分爲多個小的相同的查詢;一次性刪除1000w的數據要比一次刪除1w,暫停一會的方案更加損耗服務器開銷
    分解關聯查詢:能夠將一條關聯語句分解成多條SQL來執行,讓緩存的效率更高,執行單個查詢能夠減小鎖的競爭,在應用層作關聯能夠更容易對數據庫進行拆分,查詢效率會有大幅提高,較少冗餘記錄的查詢

  優化特定類型的查詢語句:
    優化count()查詢:count(*)中的*會忽略全部的列,直接統計全部列數,所以不要使用count(列名);MyISAM中,沒有任何WHERE條件的count(*)很是快,當有WHERE條件,MyISAM的count統計不必定比其餘表引擎快;可使用explain查詢近似值,用近似值替代count(*);增長彙總表;使用緩存
    優化關聯查詢:肯定ON或者USING子句的列上有索引;確保GROUP BY和ORDER BY中只有一個表中的列,這樣MySQL纔有可能使用索引
    優化子查詢:儘量使用關聯查詢來替代
    優化GROUP BY和DISTINCT:這兩種查詢都可使用索引來優化,是最有效的優化方法;關聯查詢中,使用標識列進行分組的效率會更高;若是不須要ORDER BY,進行GROUP BY時使用ORDER BY NULL,MySQL不會再進行文件排序;WITH ROLLUP超級聚合,能夠挪到應用程序處理
    優化LIMIT分頁:LIMIT偏移量大的時候,查詢效率較低;能夠記錄上次查詢的最大ID,下次查詢時直接根據該ID來查詢
    優化UNION查詢:UNION ALL的效率高於UNION

5. 高擴展和高可用

  分區表的原理:
  工做原理:對用戶而言,分區表是一個獨立的邏輯表,可是底層MySQL將其分紅了多個物理子表,這對用戶來講是透明的,每個分區表都會使用一個獨立的表文件;建立表時使用partition by子句定義每一個分區存放的數據,執行查詢時,優化器會根據分區定義過濾那些沒有咱們須要數據的分區,這樣查詢只須要查詢所需數據在的分區便可;分區的主要目的是將數據按照一個較粗的粒度分在不一樣的表中,這樣能夠將相關的數據存放在一塊兒,並且若是想一次性刪除整個分區的數據也很方便
  使用場景:表很是大,沒法所有存在內存,或者只在表的最後有熱點數據,其餘都是歷史數據;分區表的數據更易維護,能夠對獨立的分區進行獨立的操做;分區表的數據能夠分佈在不一樣的機器上,從而高效使用資源;可使用分區表來避免某些特殊的瓶頸;能夠備份和恢復獨立的分區;
  限制:一個表最多隻能有1024個分區;5.1版本中,分區表表達式必須是整數,5.5可使用列分區;分區字段中若是有主鍵和惟一索引列,那麼主鍵列和惟一列都必須包含進來;分區表中沒法使用外鍵約束;須要對現有表的結構進行修改;全部分區都必須使用相同的存儲引擎;分區函數中可使用的函數和表達式會有一些限制;某些存儲引擎不支持分區;對於MyISAM的分區表,不能使用load index into cache;對於MyISAM表,使用分區表時須要打開更多的文件描述符

  分庫分表的原理:
  工做原理:經過一些HASH算法或者工具實現將一張數據表垂直或者水平進行物理切分
  適用場景:單表記錄條數達到百萬到千萬級別時;解決表鎖的問題;
  分表方式:
    水平分割:表很大,分割後能夠下降在查詢時須要讀的數據和索引的頁數,同時也下降了索引的層數,提升查詢速度;使用場景:表中的數據自己就有獨立性,例如表中分別記錄各個地區的數據或者不一樣時期的數據,特別是有些數據經常使用,有些不經常使用;須要把數據存放在多個介質上;缺點:給應用增長複雜度,一般查詢時須要多個表名,查詢全部數據都需UNION操做;在許多數據庫應用中,這種複雜性會超過它帶來的優勢,查詢時會增長讀一個索引層的磁盤次數。
    垂直分表:把主鍵和一些列放在一個表,而後把主鍵和另外的列放在另外一個表中;使用場景:若是一個表中某些列經常使用,而另一些列不經常使用;可使數據行變小,一個數據頁能存儲更多數據,查詢時減小I/O次數;缺點:管理冗餘列,查詢全部數據須要JOIN操做
  分表缺點:有些分表的策略基於應用層的邏輯算法,一旦邏輯算法改變,整個分表邏輯都會改變,擴展性較差;對於應用層來講,邏輯算法無疑增長開發成本

  MySql的複製原理及負載均衡
  MySQL主從複製工做原理:在主庫上把數據更改記錄到二進制日誌,從庫將主庫的日誌複製到本身的中繼日誌,從庫讀取中繼日誌中的事件,將其重放到從庫數據中
  解決的問題:數據分佈:隨意中止或開始複製,並在不一樣地理位置分佈數據備份;負載均衡:下降單個服務器的壓力;高可用和故障切換:幫助應用程序避免單點失敗;升級測試:可使用更高版本的MySQL做爲從庫

6. 安全性

  SQL查詢的安全方案:使用預處理語句防SQL注入;寫入數據庫的數據要進行特殊字符的轉義;查詢錯誤信息不要返回給用戶,將錯誤記錄到日誌。PHP端儘可能使用PDO對數據庫進行相關操做,PDO擁有對預處理語句很好的支持的方法,MySQLi也有,可是可擴展性不如PDO,效率略高於PDO,MySQL函數在新版本中已經趨向於淘汰,因此不建議使用,並且它沒有很好的支持預處理的方法

  MySQL的其餘安全設置:按期作數據備份;不給查詢用戶root權限,合理分配權限;關閉遠程訪問數據庫權限;修改root口令,不用默認口令,使用較複雜的口令;刪除多餘的用戶;改變root用戶的名稱;限制通常用戶瀏覽其餘庫;限制用戶對數據文件的訪問權限

相關文章
相關標籤/搜索