摘要:主鍵唯一標識表中每行的這個列稱為主鍵。不為空,每行數據必須具有一個主鍵值。主要負責與用戶進行交互,接受用戶的指令,然后發出請求給,負責數據訪問和處理,然后將結果返回給。注意雖然似乎通配符可以匹配任何東西,但有一個例外,即。
為什么寫這篇文章
因為我最近的一些工作內容跟數據分析比較密切,所以需要對SQL使用得比較熟練,所以便閱讀了《MySQL 必知必會》這本書,為了檢驗自己的閱讀效果及幫助一些跟我一樣需要學習MySQL相關的知識的朋友,所以每閱讀一章,我就開始寫一章的讀書筆記,并在掘金的讀書筆記版塊發布沸點。一共三十章,全部發布完以后,便匯總成了這篇文章,感興趣的朋友通過閱讀這篇文章,快速得預覽這本書,學習MySQL相關的知識。如果你覺得這本書對你帶來幫助,希望你可以為我點一個關注,后續也會繼續閱讀其他的技術書籍,并整理成讀書筆記,分享給大家。同時也歡迎大家加我掘金主頁的微信,我們一起探討學習。
第一章 了解SQL本章主要是介紹了一些數據庫相關的概念:
數據庫:保存有組織的數據的容器。
表:某種特定類型數據的結構化清單。
模式(schema):關于數據庫和表的布局及特性的信息。在MYSQL中,模式與數據庫同義。
主鍵:唯一標識表中每行的這個列稱為主鍵。一個列成為主鍵必須滿足以下條件:
1.唯一性,任意兩行都不具有相同的主鍵值。
2.不為空,每行數據必須具有一個主鍵值。
第二章 MySQL簡介DBMS(數據庫管理軟件)通常分為兩類:
1.基于共享文件系統的DBMS。通常用于桌面(例如Microsoft Access和FileMaker)
2.Client-Sever的DBMS。日常見到的MySQL,Oracle,SQL Server數據庫都是這種類型的。Client主要負責與用戶進行交互,接受用戶的指令,然后發出請求給Server,Server負責數據訪問和處理,然后將結果返回給Client。
第三章 使用MySQL主要介紹了一些MySQL的一些命令
use crashcourse;選擇一個名叫crashcourse數據庫(在通過命令行連接到數據庫時,我們需要選擇一個數據庫,然后才能繼續操作)
show DATABASES;//展示當前可用的數據庫列表 show Tables;//展示當前是選擇的是數據庫的所有表 show COLUMNS FORM customers;//展示customers表所有的列信息(會包含字段名,類型,是否允許為NULL,鍵信息,默認值,其他信息),
DESCRIBE customers;跟show COLUMNS FORM同義,用于展示表的列信息
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重用回收存儲空間的影響)
使用DISTINCT去重:SELECT DISTINCT vend_id FROM products;
如果想要對讓返回的數據不包含重復值,可以使用DISTINCT來對列進行修飾
SELECT DISTINCT vend_id,prod_price FROM products;
DISTINCT關鍵字是對所有字段進行修飾的,只有當所有列都相同時,才會進行排除,在上面這個例子中,只有vend_id和prod_price都相同的數據,才會進行排除,也就是可以允許一些vend_id相同,prod_price不同的數據出現。
使用LIMIT來限制結果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控制升序,降序。
使用ORDER BY進行排序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 在指定兩個值之間 除了上面這些,有一個不太常見的操作符號 <>,代表不等于,與!= 同義!= 與 IS NULL
!= 是返回不具備特定值的行,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和OR都能滿足需求,但是IN有一些優點:
1.IN操作符語法更加簡潔直觀,容易管理
2.IN操作符執行更快。
3.IN的最大優點是可以包含其他SELECT語句,從而可以動態地簡歷WHERE語句,第14章會對此進行詳細介紹。
NOT操作符其他DBMS允許使用NOT對各種條件取反,但在MySQL中,只支持使用NOT對IN、BETWEEN和EXISTS子句取反。
第八章 用通配符進行過濾這一章主要是介紹了LIKE操作符,以及%,_ 這兩個通配符。
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.仔細檢查通配符的位置。如果放錯地方,可能不會返回想要的數據。
第九章 用正則表達式進行搜索這一章主要講得是正則相關的知識,我個人認為把正則當成一門多帶帶的技術進行學習會比較好,所以建議可以專門去學習
第十章 使用計算字段某些場景下,存儲在的表中的數據不是我們所需要的,我們需要對它進行轉換、計算或格式化過,這就是計算字段的用途。
使用Concat()函數對字段進行拼接多數DBMS使用+或||來實現拼接, MySQL則使用Concat()函數來對字段進行拼接。Concat()可以將多個字符串拼接成一個,如下圖所示:
Trim()函數 :去除字符串左右兩邊的空格
LTrim()函數 :去除字符串左邊的空格
RTrim()函數 :去除字符串右邊的空格
下面是使用RTrim()函數的例子
我們使用Concat()函數拼接出來的字段是沒有名字的,可以使用AS關鍵字給它賦予一個名字,當然當已有的字段包含不符合規定的字符時,也可以AS關鍵字給一個已有字段起別名。
除了使用Concat()函數得到一個計算字符,也可以使用+,-,*,/計算得到一個字段。如圖所示:
expanded_price列為一個計算字段,是由
quantity*item_price計算得到的。
除了使用SQL語句對數據進行處理,還可以使用一些函數對數據進行處理,需要注意的是,函數沒有SQL的可移植性那么強。
文本處理函數使用案例:
這是使用Upper()函數將文本處理成大寫的案例
上面這些常見函數大家可能都能夠理解,只有Soundex()不太常見,SOUNDEX是一個將任何文 本串轉換為描述其語音表示的字母數字模式的算法。
如上圖所示,假設有一個顧客的cust_contact值為Y.Lee,但是我們不知道Y.Lee,只知道這個顧客的名字的發音近似于Y.Lie,這個時候我們可以使用Soundex()將cust_contact列值轉換為它的SOUNDEX值,因為Y.Lee和 Y.Lie發音相似,所以它們的SOUNDEX值匹配,因此可以查詢到這個顧客。
舉例,使用Date函數提取日期部分:
在日常開發中,我們除了獲得檢索得到的數據,還可以使用聚合函數對數據匯總,得到處理后的結果。
SQL聚合函數 AVG()函數AVG()是計算特定列的平均值,會忽略掉值為NULL的列。
AVG()函數也可以搭配DISTINCT關鍵字使用,將重復的數據去重后,然后計算平均值,如下圖所示:
在使用了DISTINCT后,此例子中的avg_price比較高,因為有多個物品具有相同的較低價格。排除它們提升了平均價格。
兩種用法:
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操作符結合使用,但也可以用于測試等于(=)、 不等于(<>)等。
子查詢結果作為計算字段例如:我們想要在獲取顧客的信息的同時,獲取客戶的訂單數,可以使用子查詢來實現,如下圖所示:
當然這個需求也可以使用JOIN來實現
有時候針對單表的查詢無法滿足我們的需求,我們需要連接多個表,返回一組輸出。連接并不是物理實體,只是在查詢時建立。
笛卡爾積在進行連接查詢時,如果不指定任何WHERE 條件,那么返回的結果會是笛卡爾積,會拿第一個表中的行數與第二個表中的所有行進行配對,最終總行數會是第一個表的行數乘以第二個表中的行數。
WHERE條件如果指定了WHERE條件,得到的結果會是根據條件對笛卡爾積的結果進行篩選過濾后的結果。例如在這個例子中,指定了products表的vend_id與vendors表的vend_id相等作為篩選條件,這樣,連接的結果就是拿vendors表的vend_id去products表中找相匹配的數據。
等值連接(內連接)上面的這種連接其實是等值連接,可以用連接的語法來寫,可以更加明確連接類型
一條SELECT語句可以連接的表的數量沒有限制,可以連接多個表,進行查詢
之前通過子查詢嵌套來完成多表查詢,現在可以使用連接來實現
第十六章 創建高級聯結本章將講解外連接,以及如何對被聯結的表使用表別名和聚集函數。
使用表別名除了可以對列,計算字段起別名以外,還可以對表起別名。主要有以下好處:
1.縮短SQL語句(有些表名太長,可以起短的別名)
2.允許在單條SELECT語句中多次使用相同的表(對表進行自連接查詢時會需要多次使用相同的表,在下面有相應的例子說明)
除了上一章講到的內部連接(等值連接)以為,還有自連接,自然連接,外部連接三種連接:
自連接自連接指的是一張表對自身進行連接,進行信息查詢。
例如:
某物品(其ID為DTNTR)存在問題,因此想知道生產該物 品的供應商生產的其他物品是否也存在這些問題。此查詢要求首先找到 生產ID為DTNTR的物品的供應商,然后找出這個供應商生產的其他物品。
可以使用自連接的實現:
此查詢中需要的兩個表實際上是相同的表,因此products表在
FROM子句中出現了兩次。雖然這是完全合法的,但對products 的引用具有二義性,所以使用表別名避免歧義。
當然解決上面的這個查詢需求也可以使用子查詢來實現,如下圖所示:
內部連接會將一個表中的行與另一個表中的行想關聯,有時候也需要包含不滿足關聯條件的那些行,這就是外連接。
例如:
這條SELECT語句使用了關鍵字OUTER JOIN來指定聯結的類型(而不是在WHERE子句中指 定)。但是,與內部聯結關聯兩個表中的行不同的是,外部聯結還包括沒 有關聯行的行。在使用OUTER JOIN語法時,必須使用RIGHT或LEFT關鍵字 指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表,而LEFT 指出的是OUTER JOIN左邊的表)。上面的例子使用LEFT OUTER JOIN從FROM 子句的左邊表(customers表)中選擇所有行。
使用帶聚集函數的連接
聚集函數也可以和連接結合起來使用。
在這個例子中,使用INNER JOIN將customers和orders表互相關聯。GROUP BY子句按客戶分組數據,因此,函數調用COUNT (orders.order_num)對每個客戶的訂單計數,將它作為num_ord返回。
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語句層次的封裝,可用來簡化數據 處理以及重新格式化基礎數據或保護基礎數據。
后面就可以把productcustomers視圖看成一個虛擬表進行查詢,如下圖所示:
1.重用SQL語句。
2.簡化復雜的SQL操作。在編寫查詢后,可以方便地重用它而不必 知道它的基本查詢細節。
3.使用表的組成部分而不是整個表。
4.保護數據??梢越o用戶授予表的特定部分的訪問權限而不是整個表的訪問權限。
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語句來執行這個存儲過程。
需要注意的是,因為在存儲過程中會包含一些;分隔符,而在命令行實用程序中,使用;字符來作為語句分隔符,為了避免語法錯誤,可以使用DELIMITER語句來定義一個新的語句結束分隔符。如下圖所示:
可以使用DROP PROCEDURE 語句來刪除一個存儲過程,例如:
刪除名為productpricing的存儲過程
DROP PROCEDURE productpricing;使用參數
在創建存儲過程時,可以使用IN語句來存儲傳入參數,OUT語句來存儲返回結果。
在下面這個例子中,20005是傳入參數,@total是返回結果。傳入參數和返回結果也可以定義多個。
在創建存儲過程中,也可以使用IF,THEN,END IF語句來設置判斷條件,這是存儲過程與簡單的語句封裝最大的區別。
例如:
添加了另外一個 參數taxable,它是一個布爾值(如果要增加稅則為真,否則為假)。在 存儲過程體中,用DECLARE語句定義了兩個局部變量。DECLARE要求指定 變量名和數據類型,它也支持可選的默認值(這個例子中的taxrate的默 認被設置為6%)。SELECT語句已經改變,因此其結果存儲到total(局部 變量)而不是ototal。IF語句檢查taxable是否為真,如果為真,則用另 一SELECT語句增加營業稅到局部變量total。最后,用另一SELECT語句將 total(它增加或許不增加營業稅)保存到ototal。
BOOLEAN值指定為1表示真,指定為0表示假(實際上,非零值 都考慮為真,只有0被視為假)。通過給中間的參數指定0或1,可以有條件地將營業稅加到訂單合計上。
可以使用 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語句時自動關閉它。
使用游標數據
這個例子使用FETCH檢索當前order_num到聲明的名為o的變量中。但與前一個例子不一樣的是,這個 例子中的FETCH是在REPEAT內,因此它反復執行直到done為真(由UNTIL done END REPEAT;規定)。為使它起作用,用一個DEFAULT 0(假,不結 束)定義變量done。當在 FETCH 語句中引用的游標位置處于結果表最后一行之后時,SQLSTATE會為02000,這個時候done會為真,停止循環。
可以使用觸發器是在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觸發器
在INSERT觸發器代碼內,可引用一個名為NEW的虛擬表,訪問被 插入的行;
在BEFORE INSERT觸發器中,NEW中的值也可以被更新(允許更改 被插入的值);
對于AUTO_INCREMENT列,NEW在INSERT執行之前列的值會是0,在INSERT 執行之后包含新的自動生成值。
上面的例子中創建一個名為neworder的觸發器,它按照AFTER INSERT ON orders執行。在插入一個新訂單到orders表時,MySQL生 成一個新訂單號并保存到order_num中。觸發器從NEW. order_num取得這個值并返回它。
DELETE觸發器在DELETE語句執行之前或之后執行,在DELETE觸發器代碼內,你可以引用一個名為OLD的虛擬表,訪問被刪除的行。OLD中的值全都是只讀的,不能更新。
上面這個例子中,在任意訂單被刪除前將執行此觸發器。它使用一條INSERT語句將OLD中的值(要被刪除的訂單)保存到一個名為archive_ orders的存檔表中(為實際使用這個例子,你需要用與orders相同的列 創建一個名為archive_orders的表)。
UPDATE觸發器在UPDATE語句執行之前或之后執行。在UPDATE觸發器代碼中,你可以引用一個名為OLD的虛擬表訪問 以前(UPDATE語句前)的值,引用一個名為NEW的虛擬表訪問新 更新的值。在BEFORE UPDATE觸發器中,NEW中的值可能也被更新(允許更改 將要用于UPDATE語句中的值)。OLD中的值全都是只讀的,不能更新。
上面面的例子保證州名縮寫總是大寫(不管UPDATE語句中給出的是大 寫還是小寫)
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使用ROLLBACK
MySQL的ROLLBACK命令用來回退(撤銷)MySQL語句。例如:
從顯示ordertotals表(此表在第24章中填充)的內
容開始。首先執行一條SELECT以顯示該表不為空。然后開始一 個事務處理,用一條DELETE語句刪除ordertotals中的所有行。另一條 SELECT語句驗證ordertotals確實為空。這時用一條ROLLBACK語句回退 START TRANSACTION之后的所有語句,最后一條SELECT語句顯示該表不為空。
ROLLBACK只能在一個事務處理內使用(在執行一條START TRANSACTION命令之后)。可以回退INSERT、UPDATE和 DELETE語句。不能回退SELECT,CREATE,DROP語句。
一般的MySQL語句都是直接針對數據庫表執行和編寫的。這就是所謂的隱含提交(implicit commit),即提交(寫或保存)操作是自動進行的。但是,在事務處理塊中,提交不會隱含地進行。為進行明確的提交, 使用COMMIT語句。
在這個例子中,從系統中完全刪除訂單20010。因為涉及更新
兩個數據庫表orders和orderItems,所以使用事務處理塊來 保證訂單不被部分刪除。最后的COMMIT語句僅在不出錯時寫出更改。如 果第一條DELETE起作用,但第二條失敗,則DELETE不會提交(會被自動撤銷)。
簡單的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%";查看校對相關的配置給表指定字符集和校對
這個例子中指定了CHARACTER SET和COLLATE兩者。一般,MySQL如
下確定使用什么樣的字符集和校對。
1.如果指定CHARACTER SET和COLLATE兩者,則使用這些值。
2.如果只指定CHARACTER SET,則使用此字符集及其默認的校對(如SHOW CHARACTER SET的結果中所示)。
3.如果既不指定CHARACTER SET,也不指定COLLATE,則使用數據庫默認。
對列指定字符集和校對 查詢時指定校對順序
此SELECT使用COLLATE指定一個備用的校對順序(在這個例子 中,為區分大小寫的校對)。除了這里看到的在ORDERBY子 句中使用以外,COLLATE還可以用于GROUP BY、HAVING、聚集 函數、別名等。
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,如下圖所示:
輸出結果顯示用戶bforta有一個權限USAGE ON .。此結果表示在任意數據庫和任意表上對任何數據沒有權限。
用戶定義為user@host MySQL的權限將會把用戶名和主機名結合定義。如果不指定主機名,則使用默認的主機名%(授予用戶訪問權限而不管主機名)。
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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75242.html
摘要:主鍵唯一標識表中每行的這個列稱為主鍵。不為空,每行數據必須具有一個主鍵值。主要負責與用戶進行交互,接受用戶的指令,然后發出請求給,負責數據訪問和處理,然后將結果返回給。注意雖然似乎通配符可以匹配任何東西,但有一個例外,即。 為什么寫這篇文章 因為我最近的一些工作內容跟數據分析比較密切,所以需要對SQL使用得比較熟練,所以便閱讀了《MySQL 必知必會》這本書,為了檢驗自己的閱讀效果及幫...
摘要:報文用于協議交互的信息被稱為報文。現在出現的各種首部字段及狀態碼稍后會闡述。狀態碼響應報文包含了多個范圍的內容使用。如果服務器無法響應范圍請求,則會返回狀態碼和完整的實體內容。 showImg(https://segmentfault.com/img/bVbthNL?w=900&h=500); http報文 用于HTTP協議交互的信息被稱為HTTP報文。請求端的http報文叫做請求報文...
閱讀 791·2021-11-12 10:36
閱讀 3369·2021-09-08 10:44
閱讀 2742·2019-08-30 11:08
閱讀 1397·2019-08-29 16:12
閱讀 2672·2019-08-29 12:24
閱讀 895·2019-08-26 10:14
閱讀 683·2019-08-23 18:32
閱讀 1171·2019-08-23 17:52