由於我最近的一些工做內容跟數據分析比較密切,因此須要對SQL使用得比較熟練,因此便閱讀了《MySQL 必知必會》這本書,爲了檢驗本身的閱讀效果及幫助一些跟我同樣須要學習MySQL相關的知識的朋友,因此每閱讀一章,我就開始寫一章的讀書筆記,並在掘金的讀書筆記版塊發佈沸點。一共三十章,所有發佈完之後,便彙總成了這篇文章,感興趣的朋友經過閱讀這篇文章,快速得預覽這本書,學習MySQL相關的知識。若是你以爲這本書對你帶來幫助,但願你能夠爲我點一個關注,後續也會繼續閱讀其餘的技術書籍,並整理成讀書筆記,分享給你們。同時也歡迎你們加我掘金主頁的微信,咱們一塊兒探討學習。mysql
本章主要是介紹了一些數據庫相關的概念:正則表達式
數據庫:保存有組織的數據的容器。算法
表:某種特定類型數據的結構化清單。sql
模式(schema):關於數據庫和表的佈局及特性的信息。在MYSQL中,模式與數據庫同義。數據庫
主鍵:惟一標識表中每行的這個列稱爲主鍵。一個列成爲主鍵必須知足如下條件:安全
1.惟一性,任意兩行都不具備相同的主鍵值。bash
2.不爲空,每行數據必須具備一個主鍵值。服務器
DBMS(數據庫管理軟件)一般分爲兩類:微信
1.基於共享文件系統的DBMS。一般用於桌面(例如Microsoft Access和FileMaker)多線程
2.Client-Sever的DBMS。平常見到的MySQL,Oracle,SQL Server數據庫都是這種類型的。Client主要負責與用戶進行交互,接受用戶的指令,而後發出請求給Server,Server負責數據訪問和處理,而後將結果返回給Client。
主要介紹了一些MySQL的一些命令
use crashcourse;選擇一個名叫crashcourse數據庫(在經過命令行鏈接到數據庫時,咱們須要選擇一個數據庫,而後才能繼續操做)
show DATABASES;//展現當前可用的數據庫列表
show Tables;//展現當前是選擇的是數據庫的全部表
show COLUMNS FROM customers;//展現customers表全部的列信息(會包含字段名,類型,是否容許爲NULL,鍵信息,默認值,其餘信息),
複製代碼
DESCRIBE customers;跟show COLUMNS FROM同義,用於展現表的列信息
SHOW STATUS;展現服務器信息
SHOW CREATE DATABASE crashcourse;
複製代碼
展現以前建立crashcourse這個數據庫時使用的SQL語句,同理,SHOW CREATE TABLE也能夠展現建某張表時使用的SQL語句
SHOW GRANTS FOR 'jeffrey'@'localhost';//展現jeffrey這個帳號的權限
SHOW ERRORS和SHOW WARNINGS,//用來顯示服務器錯誤或警告消息
複製代碼
HELP SHOW;當你不瞭解某個命令時,可使用HELP+這個命令,來得到一些說明信息,瞭解這個命令的用途,這裏HELP SHOW會打印出SHOW命令的用法
這兩章主要講得是查詢相關的。
查詢時默認的數據順序:
SELECT prod_name FROM products;
複製代碼
若是是不設置任何排序條件,以這種方式來進行查詢,返回的數據的順序是根據它們在底層表中出現的順序(能夠是數據最初添加到表中的順序,可是若是數據進行過更新或刪除,順序會受到MySQL重用回收存儲空間的影響)
SELECT DISTINCT vend_id FROM products;
複製代碼
若是想要對讓返回的數據不包含重複值,可使用DISTINCT來對列進行修飾
SELECT DISTINCT vend_id,prod_price FROM products;
複製代碼
DISTINCT關鍵字是對全部字段進行修飾的,只有當全部列都相同時,纔會進行排除,在上面這個例子中,只有vend_id和prod_price都相同的數據,纔會進行排除,也就是能夠容許一些vend_id相同,prod_price不一樣的數據出現。
SELECT prod_name FROM products LIMIT 5;
複製代碼
能夠限制返回的數據爲5條
SELECT prod_name FROM products LIMIT 4,5;
複製代碼
能夠限制返回的數據是從第4行開始後面的5條
上面這條查詢語句,MySQL 5之後還支持另一種更加容易理解的寫法
SELECT prod_name FROM products LIMIT 4 offset 5;
複製代碼
使用徹底限定的表名
SELECT products.prod_name FROM crash_course.products;
複製代碼
能夠限制在某個數據庫的某個表中進行查詢,上面的例子是限制了,必須在crash_course數據庫的products表取prod_name列的數據
這一章主要講的是ORDER BY對查詢結果進行排序,以及使用ASC,DESC控制升序,降序。
SELECT prod_name FROM products ORDER BY product_name;
複製代碼
SELECT prod_id, prod_price, prod_name FROM products ORDER BY product_price, product_name;
複製代碼
在 ORDER BY 指定多個字段,能夠按規定的順序,按多個列排序,例子中的數據會先根據 product_price 從低到高進行排序,若是 product_price相同,再按 product_name ,就進行比較從A到Z進行排序,以下圖所示
默認的排序方向是升序,也就是ASC,有時候須要進行降序排序,例如價格從高到低進行排序,可使用降序DESC
這一章其實主要講得是WHERE語句對數據進行過濾。
一些常見的WHERE語句的條件判斷符,你們已經知道了。 例如:
= 等於
!= 不等於
< 小於
> 大於
<= 小於等於
>= 大於等於
BETWEEN 在指定兩個值之間
除了上面這些,有一個不太常見的操做符號
<>,表明不等於,與!= 同義
複製代碼
!= 是返回不具有特定值的行,NULL值表明未知,因此不會拿NULL值去跟特定值比較,因此不會具備NULL值的行。若是想要獲取具備NULL值的行,必須使用IS NULL 例如:
對下面這個表執行 SELECT * FROM table WHERE value != 100;
id | value |
---|---|
1 | 100 |
2 | NULL |
3 | 200 |
返回的結果:
只會返回value爲200的這一行,不會返回值爲NULL的行
id | value |
---|---|
3 | 200 |
使用BETWEEN操做符會匹配範圍中全部的值,包括指定的開始值和結束值
例如:
這一章主要說的是AND,OR, IN,NOT這四個操做符,
組合AND和OR使用時,由於AND優先級最高計算時會優先處理AND操做符,會將AND兩邊的條件進行提取,因此上面這個SQL語句其實會等價於
SELECT prod_name, prod_price FROM products WHERE vend_id = 1002 OR (vend_id = 1003 AND prod_price >= 10);
複製代碼
可能會與咱們想要的結果會有必定差距,咱們是想要
SELECT prod_name, prod_price FROM products WHERE vend_id = 1002 OR (vend_id = 1003 AND prod_price >= 10);
複製代碼
可能會與咱們想要的結果會有必定差距,咱們是想要vend_id爲1002或1002,且prod_price大於10的數據,因此在平常使用中,最好使用()明確地分組相應的操做符,而不是依賴操做符的優先級,像下面這樣:
SELECT prod_name, prod_price FROM products WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price >= 10;
複製代碼
在指定條件範圍進行匹配時,IN和OR都能知足需求,可是IN有一些優勢:
1.IN操做符語法更加簡潔直觀,容易管理
2.IN操做符執行更快。
3.IN的最大優勢是能夠包含其餘SELECT語句,從而能夠動態地簡歷WHERE語句,第14章會對此進行詳細介紹。
其餘DBMS容許使用NOT對各類條件取反,但在MySQL中,只支持使用NOT對IN、BETWEEN和EXISTS子句取反。
這一章主要是介紹了LIKE操做符,以及%,_ 這兩個通配符。
LIKE主要是配合通配符一塊兒使用的,LIKE 操做符用於在 WHERE 子句中搜索列中的指定模式。
%表明搜索模式中給定位置的0個、1個或多個字符。
可能會干擾通配符匹配。例如,在保存詞 anvil時,若是它後面有一個或多個空格,則子句WHERE prod_name LIKE '%anvil'將不會匹配它們,由於在最後的l 後有多餘的字符。解決這個問題的一個簡單的辦法是在搜索模式最後附加一個%。一個更好的辦法是使用函數(第11章將會 介紹)去掉首尾空格。 注意NULL 雖然彷佛%通配符能夠匹配任何東西,但有一個例 外,即NULL。即便是WHERE prod_name LIKE '%'也不能匹配 用值NULL做爲產品名的行。 下劃線(_)通配符 _通配符與%通配符相似,只不過只能匹配單個字符,不能匹配0個字符,也不能匹配多個字符
1.在能使用其餘操做符的請款下,儘可能不要使用通配符,由於它的搜索事件要比其餘操做符的長
2.儘可能不要把通配符用在搜索模式的開始處。放在搜索模式的開始處,搜索起來是最慢的。
3.仔細檢查通配符的位置。若是放錯地方,可能不會返回想要的數據。
這一章主要講得是正則相關的知識,我我的認爲把正則當成一門單獨的技術進行學習會比較好,因此建議能夠專門去學習
某些場景下,存儲在的表中的數據不是咱們所須要的,咱們須要對它進行轉換、計算或格式化過,這就是計算字段的用途。
多數DBMS使用+或||來實現拼接, MySQL則使用Concat()函數來對字段進行拼接。Concat()能夠將多個字符串拼接成一個,以下圖所示:
Trim()函數 :去除字符串左右兩邊的空格 LTrim()函數 :去除字符串左邊的空格 RTrim()函數 :去除字符串右邊的空格 下面是使用RTrim()函數的例子
咱們使用Concat()函數拼接出來的字段是沒有名字的,可使用AS關鍵字給它賦予一個名字,固然當已有的字段包含不符合規定的字符時,也能夠AS關鍵字給一個已有字段起別名。
除了使用Concat()函數獲得一個計算字符,也可使用+,-,,/計算獲得一個字段。如圖所示:
除了使用SQL語句對數據進行處理,還可使用一些函數對數據進行處理,須要注意的是,函數沒有SQL的可移植性那麼強。
使用案例: 這是使用Upper()函數將文本處理成大寫的案例
上面這些常見函數你們可能都可以理解,只有Soundex()不太常見,SOUNDEX是一個將任何文 本串轉換爲描述其語音表示的字母數字模式的算法。
在平常開發中,咱們除了得到檢索獲得的數據,還可使用聚合函數對數據彙總,獲得處理後的結果。
AVG()是計算特定列的平均值,會忽略掉值爲NULL的列。
兩種用法: 1.使用COUNT(*)對錶中行的數目進行計數,無論表列中包含的是空值(NULL)仍是非空值。 2.使用COUNT(column)對特定列中具備值的行進行計數,會忽略 NULL值。
這一章主要講了若是使用GROUP BY 對數據進行分組。
若是要對分組進行過濾,咱們可使用WHERE語句對錶中數據進行過濾後,而後使用GROUP BY進行分組,也能夠在使用GROUP BY進行分組後,再使用HAVING語句過濾掉一些分組。 例如:
id | value |
---|---|
1 | 100 |
2 | 150 |
3 | 200 |
3 | 500 |
對於上面這個表的數據,若是咱們想要過濾掉id爲3的分組,那麼能夠寫成使用WHERE語句的方式:
SELECT id,COUNT(*) FROM table WHERE id != 3 GROUP BY id;
複製代碼
也能夠寫成使用HAVING語句的方式:
SELECT id,COUNT(*) FROM table GROUP BY id HAVING id !=3;
複製代碼
固然在過濾分組這方面,HAVING要比WHERE更增強大,好比咱們想要對數據分組,而且獲得數量大於2的組,那麼WHERE就沒法實現,只能用HAVING語句。以下:
使用GROUP BY在對數據進行分組後,輸出的組的順序一般是按從小到到大,從A到Z升序輸出的,可是SQL規範並無對此進行明確要求,因此有可能不是順序的,可使用ORDER BY來對分組進行升序或者降序排序。
在使用這些語句時,它們的前後順序應該要按下面的表中順序來寫
有時候一條SELECT語句沒法知足咱們的需求,咱們能夠把一條SELECT語句的結果用於另一條SELECT語句的WHERE子句,來實現複雜查詢。
例如:咱們想要獲取訂購物品TNT2的全部客戶的名字和聯繫方式: 能夠按照下圖中的複雜查詢實現:
(1) 查詢包含物品TNT2的全部訂單的編號。 (2) 根據訂單編號查詢全部客戶的ID。 (3) 根據客戶的ID查詢名字和聯繫方式。
在WHERE子句中使用子查詢可以編寫出功能很強而且很靈活的 SQL語句。對於能嵌套的子查詢的數目沒有限制,不過在實際使用時因爲 性能的限制,不能嵌套太多的子查詢。
須要的注意的地方:
1.能嵌套的子查詢的數目沒有限制,不過在實際使用時因爲 性能的限制,不能嵌套太多的子查詢。
2.列必須匹配,在WHERE子句中使用子查詢,應該保證SELECT語句具備與WHERE子句中相同數目的列。一般,子查詢將返回單個列而且與單個列匹配,但若是須要也可使用多個列。
3.子查詢通常與IN操做符結合使用,但也能夠用於測試等於(=)、 不等於(<>)等。
例如:咱們想要在獲取顧客的信息的同時,獲取客戶的訂單數,可使用子查詢來實現,以下圖所示:
有時候針對單表的查詢沒法知足咱們的需求,咱們須要鏈接多個表,返回一組輸出。鏈接並非物理實體,只是在查詢時創建。
在進行鏈接查詢時,若是不指定任何WHERE 條件,那麼返回的結果會是笛卡爾積,會拿第一個表中的行數與第二個表中的全部行進行配對,最終總行數會是第一個表的行數乘以第二個表中的行數。
若是指定了WHERE條件,獲得的結果會是根據條件對笛卡爾積的結果進行篩選過濾後的結果。例如在這個例子中,指定了products表的vend_id與vendors表的vend_id相等做爲篩選條件,這樣,鏈接的結果就是拿vendors表的vend_id去products表中找相匹配的數據。
上面的這種鏈接實際上是等值鏈接,能夠用鏈接的語法來寫,能夠更加明確鏈接類型
一條SELECT語句能夠鏈接的表的數量沒有限制,能夠鏈接多個表,進行查詢
以前經過子查詢嵌套來完成多表查詢,如今可使用鏈接來實現
本章將講解外鏈接,以及如何對被聯結的表使用表別名和彙集函數。
除了能夠對列,計算字段起別名之外,還能夠對錶起別名。主要有如下好處:
1.縮短SQL語句(有些表名太長,能夠起短的別名)
2.容許在單條SELECT語句中屢次使用相同的表(對錶進行自鏈接查詢時會須要屢次使用相同的表,在下面有相應的例子說明)
除了上一章講到的內部鏈接(等值鏈接)覺得,還有自鏈接,天然鏈接,外部鏈接三種鏈接:
自鏈接指的是一張表對自身進行鏈接,進行信息查詢。 例如: 某物品(其ID爲DTNTR)存在問題,所以想知道生產該物 品的供應商生產的其餘物品是否也存在這些問題。此查詢要求首先找到 生產ID爲DTNTR的物品的供應商,而後找出這個供應商生產的其餘物品。 可使用自鏈接的實現:
此查詢中須要的兩個表其實是相同的表,所以products表在 FROM子句中出現了兩次。雖然這是徹底合法的,但對products 的引用具備二義性,因此使用表別名避免歧義。 固然解決上面的這個查詢需求也可使用子查詢來實現,以下圖所示:
內部鏈接會將一個表中的行與另外一個表中的行想關聯,有時候也須要包含不知足關聯條件的那些行,這就是外鏈接。 例如:
使用帶彙集函數的鏈接 彙集函數也能夠和鏈接結合起來使用。
1.注意所使用的聯結類型。通常咱們使用內部聯結,但使用外部聯 結也是有效的。
2.保證使用正確的聯結條件,不然將返回不正確的數據。
3.應該老是提供聯結條件,不然會得出笛卡兒積。
4.在一個聯結中能夠包含多個表,甚至對於每一個聯結能夠採用不一樣的聯結類型。雖然這樣作是合法的,通常也頗有用,但應該在一塊兒測試它們前,分別測試每一個聯結。這將使故障排除更爲簡單。
在 MySQL 中,能夠執行多條查詢語句,而後對多個結果集,使用UNION語句合併成單個查詢結果集返回。主要有如下兩種應用場景: 1.在單個查詢中從不一樣的表返回相似結構的數據。 2.對單個表執行多個查詢,將結果集合併成一個結果集。
例如咱們須要價格小於等於5的全部物品的一個列表,並且 還想包括供應商1001和1002生產的全部物品(不考慮價格),
這條語句由前面的兩條SELECT語句組成,語句中用UNION關鍵 字分隔。UNION指示MySQL執行兩條SELECT語句,並把輸出組 合成單個查詢結果集,固然這個需求也可使用多條WHERE語句來實現。
1.UNION必須由兩條或兩條以上的SELECT語句組成,語句之間用關 鍵字UNION分隔(所以,若是組合4條SELECT語句,將要使用3個 UNION關鍵字)。
2.UNION中的每一個查詢必須包含相同的列、表達式或彙集函數(不過 3.列數據類型必須兼容:類型沒必要徹底相同,但必須是DBMS能夠 隱含地轉換的類型(例如,不一樣的數值類型或不一樣的日期類型)。 若是遵照了這些基本規則或限制,則能夠將並用於任何數據檢索任務。
4.在用UNION組合查詢時,若是須要對結果進行排序,只能使用一條ORDER BY子句,它必須出如今最後一條SELECT語句以後。對 於結果集,不存在用一種方式排序一部分,而又用另外一種方式排序另外一 部分的狀況,所以不容許使用多條ORDER BY子句。
5.UNION從查詢結果集中自動去除了重複的行(換句話說,它的行爲與 單條SELECT語句中使用多個WHERE子句條件同樣)。由於供應商1002生產 的一種物品的價格也低於5,因此兩條SELECT語句都返回該行。在使用 UNION時,重複的行被自動取消。這是UNION的默認行爲,可是若是容許重複,可使用UNION ALL而不是UNION。以下圖所示:
當咱們須要對文本進行匹配,可使用LIKE+通配符,或正則表達式的方式來實現,可是這樣會存在不少限制:
1.性能不高——通配符和正則表達式匹配一般要求MySQL嘗試匹配表中全部行(並且這些搜索極少使用表索引)。所以,因爲被搜索行數不斷增長,這些搜索可能很是耗時。
2.不太靈活——使用通配符和正則表達式匹配,很難(並且並不老是能)明確地控制匹配什麼和不匹配什麼。例如,指定一個詞必須匹配,一個詞必須不匹配,而一個詞僅在第一個詞確實匹配的狀況下才能夠匹配或者才能夠不匹配。
3.沒法智能化——雖然基於通配符和正則表達式的搜索提供了很是靈活的搜索,但它們都不能提供一種智能化的選擇結果的方法。 例如,一個特殊詞的搜索將會返回包含該詞的全部行,而不區分包含單個匹配的行和包含多個匹配的行(按照多是更好的匹配 來排列它們)。相似,一個特殊詞的搜索將不會找出不包含該詞但包含其餘相關詞的行。因此就有了全文搜索,爲了進行全文本搜索,必須索引被搜索的列,並且要隨着數據的改 變不斷地從新索引。在對錶列進行適當設計後,MySQL會自動進行全部 的索引和從新索引。在索引以後,SELECT可與Match()和Against()一塊兒使用以實際執行 搜索。
在建表時或者建表之後使用FULLTEXT語句指定全文搜索的列,MySQL根據子句FULLTEXT(note_text)的指示對它進行索引,在以後該列增長、更新或刪除行時, 索引隨之自動更新 以下圖所示:
若是正在導入數據到一個新表, 此時不該該啓用FULLTEXT索引。應該首先導入全部數據,而後再修改表,定義FULLTEXT,這樣花費的時間會更少。
在索引以後,使用兩個函數Match()和Against()執行全文本搜索, Match() 指定被搜索的列 Against() 指定要使用的搜索表達式 以下圖所示:SELECT語句檢索單個列note_text,將包含rabbit的行進行返回。(全文搜索默認不區分大小寫,除非使用BINARY語句進行修飾)
全文搜索還可使用Rank對結果進行排序,Match()和Against() 用來創建一個計算列(別名爲rank),此列包含全文本搜索計算出的等級 值。等級由MySQL根據行中詞的數目、惟一詞的數目、整個索引中詞的 總數以及包含該詞的行的數目計算出來。不包含搜索詞的行等級爲0(所以不被前一例子中的WHERE子句選擇)。確實包含搜索詞的兩個行每行都有一個等級值,文本中詞靠前的行的等級值比詞靠後的行的等級值高。以下圖所示:
若是指定多個搜索項,則包含多數匹配詞的 那些行將具備比包含較少詞(或僅有一個匹配)的那些行高的 等級值。
查詢擴展用來設法放寬所返回的全文本搜索結果的範圍,它能夠先進行一個基本的全文本搜索,找出與搜索條件匹配的全部行。其次,MySQL檢查這些匹配行並選擇全部有用的詞,再其次,MySQL再次進行全文本搜索,此次不只使用原來的條件, 並且還使用全部有用的詞。以下圖所示;
MySQL支持全文本搜索的另一種形式,稱爲布爾方式(boolean mode)。能夠指定要匹配的詞,要排斥的詞,排列提示(指定某些詞比其餘詞更重要,更重要的詞等級更高),表達式分組等。即便沒有定義 FULLTEXT索引,也可使用它。但這是一種很是緩慢的操做。 例如: 在下圖裏面的查詢中,會匹配詞heavy,但-rope明確地 分析指示MySQL排除包含rope(任何以rope開始的詞,包括 ropes)的行。
除了布爾操做符-和*,-排除一個詞,而* 是截斷操做符(可想象爲用於詞尾的一個通配符)。還有如下全文本布爾操做符:
下面是一些全文本布爾操做符使用案例:
全文本搜索的使用說明
1.在索引全文本數據時,短詞被忽略且從索引中排除。短詞定義爲 那些具備3個或3個如下字符的詞(若是須要,這個數目能夠更改)。
2.MySQL帶有一個內建的非用詞(stopword)列表,這些詞在索引全文本數據時老是被忽略。若是須要,能夠覆蓋這個列表(請參閱MySQL文檔以瞭解如何完成此工做)。
3.許多詞出現的頻率很高,搜索它們沒有用處(返回太多的結果)。所以,MySQL規定了一條50%規則,若是一個詞出如今50%以上的行中,則將它做爲一個非用詞忽略。50%規則不用於IN BOOLEAN MODE。
4.若是表中的行數少於3行,則全文本搜索不返回結果(由於每一個詞或者不出現,或者至少出如今50%的行中)。
5.忽略詞中的單引號。例如,don't索引爲dont。
6.不具備詞分隔符(包括日語和漢語)的語言不能恰當地返回全文 本搜索結果。
7.如前所述,僅在MyISAM數據庫引擎中支持全文本搜索。
8.沒有鄰近操做符,鄰近搜索是許多全文本搜索支持的一個特 性,它能搜索相鄰的詞(在相同的句子中、相同的段落中或者 在特定數目的詞的部分中,等等。MySQL全文本搜索如今還不支持鄰近操做符。
使用INSERT語句插入數據,你們都很熟悉。 例如向 Customers 表插入一條name爲tom,age爲29的數據 通常有如下兩種方式:
INSERT INTO Customers VALUES("tom", "29");
INSERT INTO Customers(name, age) VALUES("tom", "29");
複製代碼
通常推薦第二張方式,由於第一種方式的數據順序必須與列在表中的數據保持一致,容易寫錯,其次是當表結構發生改變時,第一種方式須要變動數據順序,第二種方式不須要。
INSERT通常用來給表插入一個指定列值的行。可是,INSERT還存在 另外一種形式,能夠利用它將一條SELECT語句的結果插入表中。以下圖所示,這個例子使用INSERT SELECT從custnew表中將全部數據導入customers表
使用UPDATE語句更新數據,你們都很熟練了,通常UPDATE語句組成部分以下:
UPDATE 表名
SET 列名 = 新值
WHERE 過濾條件;
複製代碼
以下圖所示:
1.在使用UPDATE語句時,不要省略WHERE子句 ,不然就會更新表中全部行。
2.IGNORE關鍵字,若是用UPDATE語句更新多行,而且在更新這些行中的一行或多行時出一個現錯誤,則整個UPDATE操做被取消 (錯誤發生前更新的全部行被恢復到它們原來的值)。爲即便是發生錯誤,也繼續進行更新,可以使用IGNORE關鍵字,以下所示: UPDATE IGNORE customers...
使用DELETE語句更新數據,你們也都很熟練了,通常DELETE語句組成部分以下:
DELETE FROM 表名 WHERE 過濾條件;
以下圖所示:
1.在使用DELETE語句時,不要省略DELETE子句 ,不然會刪除表中全部行。
2.DELETE語句從表中刪除行,甚至是刪除表中全部行。可是,DELETE不刪除表自己。
3.若是想從表中刪除全部行,不要使用DELETE。 可以使用TRUNCATE TABLE語句,它完成相同的工做,但速度更快,由於TRUNCATE實際是刪除原來的表並從新建立一個表,而不是逐行刪除表中的數據
更新和刪除的指導原則
1.除非確實打算更新和刪除每一行,不然絕對不要使用不帶WHERE 子句的UPDATE或DELETE語句。
2.保證每一個表都有主鍵(若是忘記這個內容,請參閱第15章),儘量 像WHERE子句那樣使用它(能夠指定各主鍵、多個值或值的範圍)。
3.在對UPDATE或DELETE語句使用WHERE子句前,應該先用SELECT進行測試,保證它過濾的是正確的記錄,以防編寫的WHERE子句不正確。
4.使用強制實施引用完整性的數據庫(關於這個內容,請參閱第15 章),這樣MySQL將不容許刪除具備與其餘表相關聯的數據的行。
5.MySQL沒有撤銷(undo)按鈕。應該很是當心地使用UPDATE和DELETE,不然你會發現本身更新或刪除了錯誤的數據。
使用CREATE語句來建立一個表,你們都很熟悉了,以下圖所示
須要注意的有如下幾點:
1.在建表時,每一列要麼是可爲NULL列,要麼是NOT NULL列,若是不指定,默認爲可爲NULL列。
2.主鍵必須保證惟一,不能爲NULL。若是使用一個列做爲主鍵,值必須惟一,若是使用多個列做爲主鍵,那麼多個列組合的值必須惟一。
3.MySQL有一個具體管理和處理數據的內部引擎,在執行SQL語句時,可使用ENGINE語句指定引擎,若是省略ENGINE=語句,則使用默認引擎(極可能是MyISAM),如下爲MySQL常見的幾個引擎: InnoDB
是一個可 靠的事 務 處 理 引 擎 ( 參 見 第 26 章 ), 它 不 支 持 全 文 本搜索;
MEMORY
在功能等同於MyISAM,但因爲數據存儲在內存(不是磁盤) 中,速度很快,因此特別適合於臨時表;
MyISAM
是一個性能極高的引擎,它支持全文本搜索(參見第18章), 但不支持事務處理。
在表創建之後,若是須要對錶結構進行修改,咱們可使用ALTER TABLE語句對錶進行修改。例如:
複雜的表結構更改通常須要手動刪除過程,它涉及如下步驟:
1.用新的列布局建立一個新表。
2.使用INSERT SELECT語句從舊錶複製數據到新表。若是有必要,可以使用轉換函數和計算字段。
3.檢驗包含所需數據的新表。
4.重命名舊錶(若是肯定,能夠刪除它)。
5.用舊錶原來的名字重命名新表。
6.根據須要,從新建立觸發器、存儲過程、索引和外鍵。
刪除表(刪除整個表而不是其內容)很是簡單,使用DROP TABLE語,例如: 刪除customers2表
DROP TABLE customers2;
複製代碼
使用RENAME TABLE語句能夠重命名一個表。 例如: 將表customers2名字改成customers
RENAME TABLE customers2 to customers;
複製代碼
視圖爲虛擬的表。它們包含的不是數據而是根據須要檢索數據的查 詢。視圖提供了一種MySQL的SELECT語句層次的封裝,可用來簡化數據 處理以及從新格式化基礎數據或保護基礎數據。
1.重用SQL語句。
2.簡化複雜的SQL操做。在編寫查詢後,能夠方便地重用它而沒必要 知道它的基本查詢細節。
3.使用表的組成部分而不是整個表。
4.保護數據。能夠給用戶授予表的特定部分的訪問權限而不是整個表的訪問權限。
5.更改數據格式和表示。視圖可返回與底層表的表示和格式不一樣的數據。
1.與表同樣,視圖必須惟一命名(不能給視圖取與別的視圖或表相 同的名字)。
2.對於能夠建立的視圖數目沒有限制。
3.爲了建立視圖,必須具備足夠的訪問權限。這些限制一般由數據庫管理人員授予。
4.視圖能夠嵌套,便可以利用從其餘視圖中檢索數據的查詢來構造一個視圖。
5.ORDER BY能夠用在視圖中,但若是從該視圖檢索數據SELECT中也含有ORDER BY,那麼該視圖中的ORDER BY將被覆蓋。
6.視圖不能索引,也不能有關聯的觸發器或默認值。
7.視圖能夠和表一塊兒使用。例如,編寫一條聯結表和視圖的SELECT語句。
1.視圖用CREATE VIEW語句來建立。
2.使用SHOW CREATE VIEW viewname;來查看建立視圖的語句。
3.用DROP刪除視圖,其語法爲DROP VIEW viewname;。
4.更新視圖時,能夠先用DROP再用CREATE,也能夠直接用CREATE OR REPLACE VIEW。若是要更新的視圖不存在,則第2條更新語句會建立一個視圖;若是要更新的視圖存在,則第2條更新語句會替換原有視圖。
咱們上面的例子中視圖的做用實際上是簡化複雜SQL的使用,其實視圖還有其餘的做用,例如:
視圖是可更新的(也就是能夠對它們使用INSERT、UPDATE和DELETE)。更新一個視圖將更新其基表(能夠回憶一下,視圖自己沒有數據)。若是你對視圖增長或刪除行,其實是對其基表增長或刪除行。可是當視圖定義中有如下操做時,則不能進行視圖的更新:
1.分組(使用GROUP BY和HAVING); 聯結;
2.子查詢;
3.並;
4.彙集函數(Min()、Count()、Sum()等);
5.DISTINCT;
6.導出(計算)列。
存儲過程,就是能夠一條或多條MySQL語句的組合起來,而且能夠加入一些業務邏輯。
簡單的示例: 使用CREATE PROCEDURE語句建立一個存儲過程,對一個SELECT語句進行封裝,以後可使用CALL語句來執行這個存儲過程。
可使用DROP PROCEDURE 語句來刪除一個存儲過程,例如: 刪除名爲productpricing的存儲過程
DROP PROCEDURE productpricing;
複製代碼
在建立存儲過程時,可使用IN語句來存儲傳入參數,OUT語句來存儲返回結果。 在下面這個例子中,20005是傳入參數,@total是返回結果。傳入參數和返回結果也能夠定義多個。
在建立存儲過程當中,也可使用IF,THEN,END IF語句來設置判斷條件,這是存儲過程與簡單的語句封裝最大的區別。
例如:
可使用 SHOW CREATE PROCEDURE 語句顯示用來建立一個存儲過程的 CREATE 語句也可使用 SHOW PROCEDURE STATUS 列出全部存儲過程。爲限制其輸出,可以使用LIKE指定一個過濾模式,例如:SHOW PROCEDURE STATUS LIKE 'ordertotal';
遊標(cursor)是一個存儲在MySQL服務器上的數據庫查詢, 它不是一條SELECT語句,而是被該語句檢索出來的結果集。在存儲了遊 標以後,應用程序能夠根據須要滾動或瀏覽結果集中的數據。
定義了一個名爲ordernumbers的遊標
打開名爲ordernumbers的遊標
OPEN ordernumbers;
複製代碼
關閉名爲ordernumbers的遊標
CLOSE ordernumbers;
複製代碼
若是不明確關閉遊標,MySQL將會在到達END語句時自動關閉它。
可使用觸發器是在MySQL響應 INSERT UPDATE DELETE 語句先後自動執行一條MySQL語句。
建立觸發器語句的格式通常是 CREATE TRIGGER 觸發器名稱 觸發時機 觸發操做 FOR EACH ROW 執行操做; 例如:
CREATE TRIGGER newproduct AFTER INSERT FOR EACH ROW SELECT 'Product added';
複製代碼
CREATE TRIGGER用來建立名爲newproduct的新觸發器。觸發器 可在一個操做發生以前或以後執行,這裏給出了AFTER INSERT, 因此此觸發器將在INSERT語句成功執行後執行。這個觸發器還指定FOR EACH ROW,所以代碼對每一個插入行執行。在這個例子中,文本Product added將對每一個插入的行顯示一次。
DROP TRIGGER newproduct;刪除名爲newproduct的觸發器
複製代碼
在INSERT觸發器代碼內,可引用一個名爲NEW的虛擬表,訪問被 插入的行;
在BEFORE INSERT觸發器中,NEW中的值也能夠被更新(容許更改 被插入的值);
對於AUTO_INCREMENT列,NEW在INSERT執行以前列的值會是0,在INSERT 執行以後包含新的自動生成值。
DELETE觸發器在DELETE語句執行以前或以後執行,在DELETE觸發器代碼內,你能夠引用一個名爲OLD的虛擬表,訪問被刪除的行。OLD中的值全都是隻讀的,不能更新。
UPDATE觸發器在UPDATE語句執行以前或以後執行。在UPDATE觸發器代碼中,你能夠引用一個名爲OLD的虛擬表訪問 之前(UPDATE語句前)的值,引用一個名爲NEW的虛擬表訪問新 更新的值。在BEFORE UPDATE觸發器中,NEW中的值可能也被更新(容許更改 將要用於UPDATE語句中的值)。OLD中的值全都是隻讀的,不能更新。
1.只有表才支持觸發器,視圖不支持(臨時表也不 支持)。
2.若是BEFORE觸發器失敗,則MySQL將不執行請求的操做。此外,若是BEFORE觸發器或語句自己失敗,MySQL 將不執行AFTER觸發器(若是有的話)。
3.與其餘DBMS相比,MySQL 5中支持的觸發器至關初級。將來的MySQL版本中有一些改進和加強觸發器支持的計劃。
4.建立觸發器可能須要特殊的安全訪問權限,可是,觸發器的執行是自動的。若是INSERT、UPDATE或DELETE語句可以執行,則相關 的觸發器也能執行。
5.應該用觸發器來保證數據的一致性(大小寫、格式等)。在觸發器中執行這種類型的處理的優勢是它老是進行這種處理,並且是透 明地進行,與客戶機應用無關。
6.觸發器的一種很是有意義的使用是建立審計跟蹤。使用觸發器, 把更改(若是須要,甚至還有以前和以後的狀態)記錄到另外一個 表很是容易。
7.遺憾的是,MySQL觸發器中不支持CALL語句。這表示不能從觸發 器內調用存儲過程。所需的存儲過程代碼須要複製到觸發器內。
事務處理能夠用來維護數據庫的完整性,它保證一組SQL語句要麼徹底執行,要麼徹底不執行。利用事務處理,能夠保證一組操做不會中途中止,它們 或者做爲總體執行,或者徹底不執行(除非明確指示)。若是沒有錯誤發 生,整組語句提交給(寫到)數據庫表。若是發生錯誤,則進行回退(撤 銷)以恢復數據庫到某個已知且安全的狀態。 事務(transaction)指一組SQL語句; 回退(rollback)指撤銷指定SQL語句的過程; 提交(commit)指將未存儲的SQL語句結果寫入數據庫表; 保留點(savepoint)指事務處理中設置的臨時佔位符(place- holder),你能夠對它發佈回退(與回退整個事務處理不一樣)。
事務開始 START TRANSACTION
複製代碼
MySQL的ROLLBACK命令用來回退(撤銷)MySQL語句。例如:
通常的MySQL語句都是直接針對數據庫表執行和編寫的。這就是所謂的隱含提交(implicit commit),即提交(寫或保存)操做是自動進行的。可是,在事務處理塊中,提交不會隱含地進行。爲進行明確的提交, 使用COMMIT語句。
簡單的ROLLBACK和COMMIT語句就能夠寫入或撤銷整個事務處理。但 是,只是對簡單的事務處理才能這樣作,更復雜的事務處理可能須要部 分提交或回退。爲了支持回退部分事務處理,必須能在事務處理塊中合適的位置放 置佔位符。這樣,若是須要回退,能夠回退到某個佔位符。
SAVEPOINT delete1;建立一個名稱爲delete1的佔位符
ROLLBACK TO delete1;回退到delete1的佔位符
複製代碼
保留點在事務處理完成(執行一條ROLLBACK或 COMMIT)後自動釋放。自MySQL 5以來,也能夠用RELEASE SAVEPOINT明確地釋放保留點。
默認的MySQL行爲是自動提交全部更改。換句話說,任何 時候你執行一條MySQL語句,該語句實際上都是針對表執行的,並且所作 的更改當即生效。爲指示MySQL不自動提交更改,可使用
SET autocommit=0;
複製代碼
autocommit標誌決定是否自動提交更改,無論有沒有COMMIT 語句。設置autocommit爲0(假)指示MySQL不自動提交更改 (直到autocommit被設置爲真爲止)。
數據庫表被用來存儲和檢索數據。不一樣的語言和字符集須要以不一樣 的方式存儲和檢索。所以,MySQL須要適應不一樣的字符集(不一樣的字母 和字符),適應不一樣的排序和檢索數據的方法。
show CHARACTER SET;
複製代碼
能夠展現可用的字符集,MySQL 默認字符集是latin1,通常咱們經常使用的就是utf8
show COLLATION;
複製代碼
能夠展現所支持校對以及它們適用的字符集的完整列表,有的字符集具備不止一種校對。
一般系統管理在安裝時定義一個默認的字符集和校對。此外,也可 以在建立數據庫時,指定默認的字符集和校對。和校對,可使用如下語句進行查看:
show VARIABLES like 'character%';查看字符集相關的配置
show VARIABLES like 'collation%';查看校對相關的配置
複製代碼
1.若是指定CHARACTER SET和COLLATE二者,則使用這些值。
2.若是隻指定CHARACTER SET,則使用此字符集及其默認的校對(如SHOW CHARACTER SET的結果中所示)。
3.若是既不指定CHARACTER SET,也不指定COLLATE,則使用數據庫默認。
MySQL用戶帳號和信息存儲在名爲mysql的MySQL數據庫中。 得到全部用戶帳號列表
CREATE USER ben IDENTIFIED BY 'passwOrd'; CREATE USER建立一個新用戶帳號。在建立用戶帳號時不必定須要密碼,不過這個例子用IDENTIFIED BY 'passwOrd'給出了一個密碼。
RENAME USER ben TO bforta;
複製代碼
DROP USER bforta;
複製代碼
爲看到賦予用戶帳號的權限,使用SHOW GRANTS FOR,以下圖所示:
GRANT語句的通常格式是 GRANT 權限 ON 範圍 TO 用戶; 例如:
GRANT SELECT ON crashhouse.* TO bforta;
複製代碼
GRANT容許用戶在crashcourse.*(crashcourse數據庫的所 有表)上使用SELECT語句。
SHOW GRANTS能夠用來顯示bforta用戶的權限
GRANT的反操做爲REVOKE,用它來撤銷特定的權限。
REVOKE SELECT ON crashhouse.* FROM bforta;
複製代碼
這條REVOKE語句取消剛賦予用戶bforta的SELECT訪問權限。被 撤銷的訪問權限必須存在,不然會出錯。
GRANT和REVOKE可在幾個層次上控制訪問權限:
1.整個服務器,使用GRANT ALL和REVOKE ALL;
2.整個數據庫,使用ON database.*;
3.特定的表,使用ON database.table;
4.特定的列;
5.特定的存儲過程。
下面是能夠授予或撤銷的每一個權限:
在使用GRANT和REVOKE時,用戶帳號必須存在, 但對所涉及的對象沒有這個要求。這容許管理員在建立數據庫 和表以前設計和實現安全措施。這樣作的反作用是,當某個數據庫或表被刪除時(用DROP語 句),相關的訪問權限仍然存在。並且,若是未來從新建立該 數據庫或表,這些權限仍然起做用。
更改特定用戶的密碼
SET PASSWORD FOR bforta = Password('123456');
複製代碼
更改當前用戶的密碼
SET PASSWORD = Password('123456');
複製代碼
備份數據通常有如下幾種方案:
1.使用命令行實用程序 mysqldump 轉儲全部數據庫內容到某個外部 文件。在進行常規備份前這個實用程序應該正常運行,以便能正 確地備份轉儲文件。
2.可用命令行實用程序 mysqlhotcopy 從一個數據庫複製全部數據 (並不是全部數據庫引擎都支持這個實用程序)。
3.可使用 MySQL 的 BACKUP TABLE 或 SELECT INTO OUTFILE 轉儲全部數據到某個外部文件。這兩條語句都接受將要建立的系統文件名,此係統文件必須不存在,不然會出錯。數據能夠用 RESTORE TABLE 來複原。
ANALYZE TABLE 用來檢查表鍵是否正確,返回的狀態信息以下:
CHECK TABLE 用來針對許多問題對錶進行檢查。在MyISAM表上還對索引進行檢查。 CHECK TABLE支持一系列的檢查選項(僅用於MyISAM表) :
CHANGED 檢查自最後一次檢查以來改動過的表
EXTENDED 執行最完全的檢查
FAST 只檢查未正常關閉的表
MEDIUM 檢查全部被刪 除的連接並進行鍵檢驗
QUICK 只進行快速掃描 以下所示,CHECK TABLE發現和修復問題:
若是MyISAM表訪問產生不正確和不一致的結果,可能須要用REPAIR TABLE來修復相應的表。這條語句不該該常用,若是須要常用,可能會有更大的問題要解決。 若是從一個表中刪除大量數據,應該使用OPTIMIZE TABLE來收回所用的空間,從而優化表的性能。
服務器啓動問題一般在對MySQL配置或服務器自己進行更改時出現。MySQL在這個問題發生時報告錯誤,但因爲多數MySQL服務器是做爲系統進程或服務自動啓動的,這些消息可能看不到。 在排除系統啓動問題時,首先應該儘可能用手動啓動服務器。MySQL 服務器自身經過在命令行上執行mysqld啓動。下面是幾個重要的mysqld命令行選項:
--help 顯示幫助
--safe-mode 裝載減去某些最佳配置的服務器
--verbose 顯示全文本消息(爲得到更詳細的幫助消息與--help聯合使用)
--version 顯示版本信息而後退出
查看日誌文件
MySQL維護管理員依賴的一系列日誌文件。主要的日誌文件有如下幾種。
錯誤日誌
它包含啓動和關閉問題以及任意關鍵錯誤的細節。此日誌一般名爲hostname.err,位於data目錄中。此日誌名可用 --log-error命令行選項更改。
查詢日誌
它記錄全部MySQL活動,在診斷問題時很是有用。此日誌文件可能會很快地變得很是大,所以不該該長期使用它。此 日誌一般名爲hostname.log,位於data目錄中。此名字能夠用 --log命令行選項更改。
二進制日誌
它記錄更新過數據(或者可能更新過數據)的全部語句。此日誌一般名爲hostname-bin,位於data目錄內。此名字 能夠用--log-bin命令行選項更改。注意,這個日誌文件是MySQL 5 中添加的,之前的MySQL版本中使用的是更新日誌。
緩慢查詢日誌
顧名思義,此日誌記錄執行緩慢的任何查詢。這 個日誌在肯定數據庫何處須要優化頗有用。此日誌一般名爲 hostname-slow.log,位於data目錄中。此名字能夠用 --log-slow-queries命令行選項更改。 在使用日誌時,可用FLUSH LOGS語句來刷新和從新開始全部日誌文件。
1.首先,MySQL(與全部DBMS同樣)具備特定的硬件建議。在學習和研究MySQL時,使用任何舊的計算機做爲服務器均可以。但對用於生產的服務器來講,應該堅持遵循這些硬件建議。
2.通常來講,關鍵的生產DBMS應該運行在本身的專用服務器上。
3.MySQL是用一系列的默認設置預先配置的,從這些設置開始一般是很好的。但過一段時間後你可能須要調整內存分配、緩衝區大 小等。(爲查看當前設置,可以使用SHOW VARIABLES;和SHOW STATUS;)
4.MySQL一個多用戶多線程的DBMS,換言之,它常常同時執行多個任務。若是這些任務中的某一個執行緩慢,則全部請求都會執 行緩慢。若是你遇到顯著的性能不良,可以使用SHOW PROCESSLIST 顯示全部活動進程(以及它們的線程ID和執行時間)。你還能夠用KILL命令終結某個特定的進程(使用這個命令須要做爲管理員登陸)。
5.老是有不止一種方法編寫同一條SELECT語句。應該試驗聯結、並、子查詢等,找出最佳的方法。
6.使用EXPLAIN語句讓MySQL解釋它將如何執行一條SELECT語句。
7.通常來講,存儲過程執行得比一條一條地執行其中的各條MySQL語句更快
8.應該老是使用正確的數據類型。
9.決不要檢索比需求還要多的數據。換言之,不要用SELECT *(除非你真正須要每一個列)。
10.有的操做(包括INSERT)支持一個可選的DELAYED關鍵字,若是使用它,將把控制當即返回給調用程序,而且一旦有可能就實際執行該操做。
11.在導入數據時,應該關閉自動提交。你可能還想刪除索引(包括FULLTEXT索引),而後在導入完成後再重建它們。
12.必須索引數據庫表以改善數據檢索的性能。肯定索引什麼不是一件微不足道的任務,須要分析使用的SELECT語句以找出重複的 WHERE和ORDER BY子句。若是一個簡單的WHERE子句返回結果所花的時間太長,則能夠判定其中使用的列(或幾個列)就是須要索引的對象。
13.你的SELECT語句中有一系列複雜的OR條件嗎?經過使用多條SELECT語句和鏈接它們的UNION語句,你能看到極大的性能改進。
14.索引改善數據檢索的性能,但損害數據插入、刪除和更新的性能。若是你有一些表,它們收集數據且不常常被搜索,則在有必要以前不要索引它們。(索引可根據須要添加和刪除。)
15.LIKE很慢。通常來講,最好是使用FULLTEXT而不是LIKE。
16.數據庫是不斷變化的實體。一組優化良好的表一下子後可能就面目全非了。因爲表的使用和內容的更改,理想的優化和配置也會改變。
17.最重要的規則就是,每條規則在某些條件下都會被打破。