摘要:主鍵唯一標(biāo)識表中每行的這個列稱為主鍵。不為空,每行數(shù)據(jù)必須具有一個主鍵值。主要負(fù)責(zé)與用戶進(jìn)行交互,接受用戶的指令,然后發(fā)出請求給,負(fù)責(zé)數(shù)據(jù)訪問和處理,然后將結(jié)果返回給。注意雖然似乎通配符可以匹配任何東西,但有一個例外,即。
為什么寫這篇文章
因為我最近的一些工作內(nèi)容跟數(shù)據(jù)分析比較密切,所以需要對SQL使用得比較熟練,所以便閱讀了《MySQL 必知必會》這本書,為了檢驗自己的閱讀效果及幫助一些跟我一樣需要學(xué)習(xí)MySQL相關(guān)的知識的朋友,所以每閱讀一章,我就開始寫一章的讀書筆記,并在掘金的讀書筆記版塊發(fā)布沸點。一共三十章,全部發(fā)布完以后,便匯總成了這篇文章,感興趣的朋友通過閱讀這篇文章,快速得預(yù)覽這本書,學(xué)習(xí)MySQL相關(guān)的知識。如果你覺得這本書對你帶來幫助,希望你可以為我點一個關(guān)注,后續(xù)也會繼續(xù)閱讀其他的技術(shù)書籍,并整理成讀書筆記,分享給大家。同時也歡迎大家加我掘金主頁的微信,我們一起探討學(xué)習(xí)。
第一章 了解SQL本章主要是介紹了一些數(shù)據(jù)庫相關(guān)的概念:
數(shù)據(jù)庫:保存有組織的數(shù)據(jù)的容器。
表:某種特定類型數(shù)據(jù)的結(jié)構(gòu)化清單。
模式(schema):關(guān)于數(shù)據(jù)庫和表的布局及特性的信息。在MYSQL中,模式與數(shù)據(jù)庫同義。
主鍵:唯一標(biāo)識表中每行的這個列稱為主鍵。一個列成為主鍵必須滿足以下條件:
1.唯一性,任意兩行都不具有相同的主鍵值。
2.不為空,每行數(shù)據(jù)必須具有一個主鍵值。
第二章 MySQL簡介DBMS(數(shù)據(jù)庫管理軟件)通常分為兩類:
1.基于共享文件系統(tǒng)的DBMS。通常用于桌面(例如Microsoft Access和FileMaker)
2.Client-Sever的DBMS。日常見到的MySQL,Oracle,SQL Server數(shù)據(jù)庫都是這種類型的。Client主要負(fù)責(zé)與用戶進(jìn)行交互,接受用戶的指令,然后發(fā)出請求給Server,Server負(fù)責(zé)數(shù)據(jù)訪問和處理,然后將結(jié)果返回給Client。
第三章 使用MySQL主要介紹了一些MySQL的一些命令
use crashcourse;選擇一個名叫crashcourse數(shù)據(jù)庫(在通過命令行連接到數(shù)據(jù)庫時,我們需要選擇一個數(shù)據(jù)庫,然后才能繼續(xù)操作)
show DATABASES;//展示當(dāng)前可用的數(shù)據(jù)庫列表 show Tables;//展示當(dāng)前是選擇的是數(shù)據(jù)庫的所有表 show COLUMNS FORM customers;//展示customers表所有的列信息(會包含字段名,類型,是否允許為NULL,鍵信息,默認(rèn)值,其他信息),
DESCRIBE customers;跟show COLUMNS FORM同義,用于展示表的列信息
SHOW STATUS;展示服務(wù)器信息 SHOW CREATE DATABASE crashcourse;
展示之前創(chuàng)建crashcourse這個數(shù)據(jù)庫時使用的SQL語句,同理,SHOW CREATE TABLE也可以展示建某張表時使用的SQL語句
SHOW GRANTS FOR "jeffrey"@"localhost";//展示jeffrey這個賬號的權(quán)限 SHOW ERRORS和SHOW WARNINGS,//用來顯示服務(wù)器錯誤或警告消息
HELP SHOW;當(dāng)你不了解某個命令時,可以使用HELP+這個命令,來獲得一些說明信息,了解這個命令的用途,這里HELP SHOW會打印出SHOW命令的用法
第四章 檢索數(shù)據(jù)這兩章主要講得是查詢相關(guān)的。
查詢時默認(rèn)的數(shù)據(jù)順序:
SELECT prod_name FROM products;
如果是不設(shè)置任何排序條件,以這種方式來進(jìn)行查詢,返回的數(shù)據(jù)的順序是根據(jù)它們在底層表中出現(xiàn)的順序(可以是數(shù)據(jù)最初添加到表中的順序,但是如果數(shù)據(jù)進(jìn)行過更新或刪除,順序會受到MySQL重用回收存儲空間的影響)
使用DISTINCT去重:SELECT DISTINCT vend_id FROM products;
如果想要對讓返回的數(shù)據(jù)不包含重復(fù)值,可以使用DISTINCT來對列進(jìn)行修飾
SELECT DISTINCT vend_id,prod_price FROM products;
DISTINCT關(guān)鍵字是對所有字段進(jìn)行修飾的,只有當(dāng)所有列都相同時,才會進(jìn)行排除,在上面這個例子中,只有vend_id和prod_price都相同的數(shù)據(jù),才會進(jìn)行排除,也就是可以允許一些vend_id相同,prod_price不同的數(shù)據(jù)出現(xiàn)。
使用LIMIT來限制結(jié)果SELECT prod_name FROM products LIMIT 5;
可以限制返回的數(shù)據(jù)為5條
SELECT prod_name FROM products LIMIT 4,5;
可以限制返回的數(shù)據(jù)是從第4行開始后面的5條
上面這條查詢語句,MySQL 5以后還支持另外一種更加容易理解的寫法
SELECT prod_name FROM products LIMIT 4 offset 5;
使用完全限定的表名
SELECT products.prod_name FROM crash_course.products;
可以限制在某個數(shù)據(jù)庫的某個表中進(jìn)行查詢,上面的例子是限制了,必須在crash_course數(shù)據(jù)庫的products表取prod_name列的數(shù)據(jù)
第五章 排序檢索數(shù)據(jù)這一章主要講的是ORDER BY對查詢結(jié)果進(jìn)行排序,以及使用ASC,DESC控制升序,降序。
使用ORDER BY進(jìn)行排序SELECT prod_name FROM products ORDER BY product_name;按多個列進(jìn)行排序
SELECT prod_id, prod_price, prod_name FROM products ORDER BY product_price, product_name;
在 ORDER BY 指定多個字段,可以按規(guī)定的順序,按多個列排序,例子中的數(shù)據(jù)會先根據(jù) product_price 從低到高進(jìn)行排序,如果 product_price相同,再按 product_name ,就進(jìn)行比較從A到Z進(jìn)行排序,如下圖所示
指定排序方向默認(rèn)的排序方向是升序,也就是ASC,有時候需要進(jìn)行降序排序,例如價格從高到低進(jìn)行排序,可以使用降序DESC
第六章 過濾數(shù)據(jù)這一章其實主要講得是WHERE語句對數(shù)據(jù)進(jìn)行過濾。
條件判斷符一些常見的WHERE語句的條件判斷符,大家已經(jīng)知道了。
例如:
= 等于 != 不等于 < 小于 > 大于 <= 小于等于 >= 大于等于 BETWEEN 在指定兩個值之間 除了上面這些,有一個不太常見的操作符號 <>,代表不等于,與!= 同義!= 與 IS NULL
!= 是返回不具備特定值的行,NULL值代表未知,所以不會拿NULL值去跟特定值比較,所以不會具有NULL值的行。如果想要獲取具有NULL值的行,必須使用IS NULL
例如:
對下面這個表執(zhí)行 SELECT * FROM table WHERE value != 100;
id | value |
---|---|
1 | 100 |
2 | NULL |
3 | 200 |
返回的結(jié)果:
只會返回value為200的這一行,不會返回值為NULL的行
id | value |
---|---|
3 | 200 |
使用BETWEEN操作符會匹配范圍中所有的值,包括指定的開始值和結(jié)束值
例如:
第七章 數(shù)據(jù)過濾這一章主要說的是AND,OR, IN,NOT這四個操作符,
計算次序組合AND和OR使用時,因為AND優(yōu)先級最高計算時會優(yōu)先處理AND操作符,會將AND兩邊的條件進(jìn)行提取,所以上面這個SQL語句其實會等價于
SELECT prod_name, prod_price FROM products WHERE vend_id = 1002 OR (vend_id = 1003 AND prod_price >= 10);
可能會與我們想要的結(jié)果會有一定差距,我們是想要
SELECT prod_name, prod_price FROM products WHERE vend_id = 1002 OR (vend_id = 1003 AND prod_price >= 10);
可能會與我們想要的結(jié)果會有一定差距,我們是想要vend_id為1002或1002,且prod_price大于10的數(shù)據(jù),所以在日常使用中,最好使用()明確地分組相應(yīng)的操作符,而不是依賴操作符的優(yōu)先級,像下面這樣:
SELECT prod_name, prod_price FROM products WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price >= 10;IN操作符 OR操作符
在指定條件范圍進(jìn)行匹配時,IN和OR都能滿足需求,但是IN有一些優(yōu)點:
1.IN操作符語法更加簡潔直觀,容易管理
2.IN操作符執(zhí)行更快。
3.IN的最大優(yōu)點是可以包含其他SELECT語句,從而可以動態(tài)地簡歷WHERE語句,第14章會對此進(jìn)行詳細(xì)介紹。
NOT操作符其他DBMS允許使用NOT對各種條件取反,但在MySQL中,只支持使用NOT對IN、BETWEEN和EXISTS子句取反。
第八章 用通配符進(jìn)行過濾這一章主要是介紹了LIKE操作符,以及%,_ 這兩個通配符。
LIKE操作符LIKE主要是配合通配符一起使用的,LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。
%通配符%代表搜索模式中給定位置的0個、1個或多個字符。
在一個查詢語句中也可以使用多個%通配符
可能會干擾通配符匹配。例如,在保存詞 anvil時,如果它后面有一個或多個空格,則子句WHERE prod_name LIKE "%anvil"將不會匹配它們,因為在最后的l 后有多余的字符。解決這個問題的一個簡單的辦法是在搜索模式最后附加一個%。一個更好的辦法是使用函數(shù)(第11章將會 介紹)去掉首尾空格。
注意NULL
雖然似乎%通配符可以匹配任何東西,但有一個例 外,即NULL。即使是WHERE prod_name LIKE "%"也不能匹配 用值NULL作為產(chǎn)品名的行。
下劃線(_)通配符
_通配符與%通配符類似,只不過只能匹配單個字符,不能匹配0個字符,也不能匹配多個字符
1.在能使用其他操作符的請款下,盡量不要使用通配符,因為它的搜索事件要比其他操作符的長
2.盡量不要把通配符用在搜索模式的開始處。放在搜索模式的開始處,搜索起來是最慢的。
3.仔細(xì)檢查通配符的位置。如果放錯地方,可能不會返回想要的數(shù)據(jù)。
第九章 用正則表達(dá)式進(jìn)行搜索這一章主要講得是正則相關(guān)的知識,我個人認(rèn)為把正則當(dāng)成一門多帶帶的技術(shù)進(jìn)行學(xué)習(xí)會比較好,所以建議可以專門去學(xué)習(xí)
第十章 使用計算字段某些場景下,存儲在的表中的數(shù)據(jù)不是我們所需要的,我們需要對它進(jìn)行轉(zhuǎn)換、計算或格式化過,這就是計算字段的用途。
使用Concat()函數(shù)對字段進(jìn)行拼接多數(shù)DBMS使用+或||來實現(xiàn)拼接, MySQL則使用Concat()函數(shù)來對字段進(jìn)行拼接。Concat()可以將多個字符串拼接成一個,如下圖所示:
Trim()函數(shù) :去除字符串左右兩邊的空格
LTrim()函數(shù) :去除字符串左邊的空格
RTrim()函數(shù) :去除字符串右邊的空格
下面是使用RTrim()函數(shù)的例子
我們使用Concat()函數(shù)拼接出來的字段是沒有名字的,可以使用AS關(guān)鍵字給它賦予一個名字,當(dāng)然當(dāng)已有的字段包含不符合規(guī)定的字符時,也可以AS關(guān)鍵字給一個已有字段起別名。
除了使用Concat()函數(shù)得到一個計算字符,也可以使用+,-,*,/計算得到一個字段。如圖所示:
expanded_price列為一個計算字段,是由
quantity*item_price計算得到的。
除了使用SQL語句對數(shù)據(jù)進(jìn)行處理,還可以使用一些函數(shù)對數(shù)據(jù)進(jìn)行處理,需要注意的是,函數(shù)沒有SQL的可移植性那么強(qiáng)。
文本處理函數(shù)使用案例:
這是使用Upper()函數(shù)將文本處理成大寫的案例
上面這些常見函數(shù)大家可能都能夠理解,只有Soundex()不太常見,SOUNDEX是一個將任何文 本串轉(zhuǎn)換為描述其語音表示的字母數(shù)字模式的算法。
如上圖所示,假設(shè)有一個顧客的cust_contact值為Y.Lee,但是我們不知道Y.Lee,只知道這個顧客的名字的發(fā)音近似于Y.Lie,這個時候我們可以使用Soundex()將cust_contact列值轉(zhuǎn)換為它的SOUNDEX值,因為Y.Lee和 Y.Lie發(fā)音相似,所以它們的SOUNDEX值匹配,因此可以查詢到這個顧客。
舉例,使用Date函數(shù)提取日期部分:
在日常開發(fā)中,我們除了獲得檢索得到的數(shù)據(jù),還可以使用聚合函數(shù)對數(shù)據(jù)匯總,得到處理后的結(jié)果。
SQL聚合函數(shù) AVG()函數(shù)AVG()是計算特定列的平均值,會忽略掉值為NULL的列。
AVG()函數(shù)也可以搭配DISTINCT關(guān)鍵字使用,將重復(fù)的數(shù)據(jù)去重后,然后計算平均值,如下圖所示:
在使用了DISTINCT后,此例子中的avg_price比較高,因為有多個物品具有相同的較低價格。排除它們提升了平均價格。
兩種用法:
1.使用COUNT(*)對表中行的數(shù)目進(jìn)行計數(shù),不管表列中包含的是空值(NULL)還是非空值。
2.使用COUNT(column)對特定列中具有值的行進(jìn)行計數(shù),會忽略 NULL值。
這一章主要講了如果使用GROUP BY 對數(shù)據(jù)進(jìn)行分組。
創(chuàng)建分組 過濾分組如果要對分組進(jìn)行過濾,我們可以使用WHERE語句對表中數(shù)據(jù)進(jìn)行過濾后,然后使用GROUP BY進(jìn)行分組,也可以在使用GROUP BY進(jìn)行分組后,再使用HAVING語句過濾掉一些分組。
例如:
id | value |
---|---|
1 | 100 |
2 | 150 |
3 | 200 |
3 | 500 |
對于上面這個表的數(shù)據(jù),如果我們想要過濾掉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;
當(dāng)然在過濾分組這方面,HAVING要比WHERE更加強(qiáng)大,比如我們想要對數(shù)據(jù)分組,并且得到數(shù)量大于2的組,那么WHERE就無法實現(xiàn),只能用HAVING語句。如下:
使用GROUP BY在對數(shù)據(jù)進(jìn)行分組后,輸出的組的順序通常是按從小到到大,從A到Z升序輸出的,但是SQL規(guī)范并沒有對此進(jìn)行明確要求,所以有可能不是順序的,可以使用ORDER BY來對分組進(jìn)行升序或者降序排序。
在使用這些語句時,它們的先后順序應(yīng)該要按下面的表中順序來寫
有時候一條SELECT語句無法滿足我們的需求,我們可以把一條SELECT語句的結(jié)果用于另外一條SELECT語句的WHERE子句,來實現(xiàn)復(fù)雜查詢。
例如:我們想要獲取訂購物品TNT2的所有客戶的名字和聯(lián)系方式:
可以按照下圖中的復(fù)雜查詢實現(xiàn):
(1) 查詢包含物品TNT2的所有訂單的編號。
(2) 根據(jù)訂單編號查詢所有客戶的ID。
(3) 根據(jù)客戶的ID查詢名字和聯(lián)系方式。
在WHERE子句中使用子查詢能夠編寫出功能很強(qiáng)并且很靈活的 SQL語句。對于能嵌套的子查詢的數(shù)目沒有限制,不過在實際使用時由于 性能的限制,不能嵌套太多的子查詢。
需要的注意的地方:
1.能嵌套的子查詢的數(shù)目沒有限制,不過在實際使用時由于 性能的限制,不能嵌套太多的子查詢。
2.列必須匹配,在WHERE子句中使用子查詢,應(yīng)該保證SELECT語句具有與WHERE子句中相同數(shù)目的列。通常,子查詢將返回單個列并且與單個列匹配,但如果需要也可以使用多個列。
3.子查詢一般與IN操作符結(jié)合使用,但也可以用于測試等于(=)、 不等于(<>)等。
子查詢結(jié)果作為計算字段例如:我們想要在獲取顧客的信息的同時,獲取客戶的訂單數(shù),可以使用子查詢來實現(xiàn),如下圖所示:
當(dāng)然這個需求也可以使用JOIN來實現(xiàn)
有時候針對單表的查詢無法滿足我們的需求,我們需要連接多個表,返回一組輸出。連接并不是物理實體,只是在查詢時建立。
笛卡爾積在進(jìn)行連接查詢時,如果不指定任何WHERE 條件,那么返回的結(jié)果會是笛卡爾積,會拿第一個表中的行數(shù)與第二個表中的所有行進(jìn)行配對,最終總行數(shù)會是第一個表的行數(shù)乘以第二個表中的行數(shù)。
WHERE條件如果指定了WHERE條件,得到的結(jié)果會是根據(jù)條件對笛卡爾積的結(jié)果進(jìn)行篩選過濾后的結(jié)果。例如在這個例子中,指定了products表的vend_id與vendors表的vend_id相等作為篩選條件,這樣,連接的結(jié)果就是拿vendors表的vend_id去products表中找相匹配的數(shù)據(jù)。
等值連接(內(nèi)連接)上面的這種連接其實是等值連接,可以用連接的語法來寫,可以更加明確連接類型
一條SELECT語句可以連接的表的數(shù)量沒有限制,可以連接多個表,進(jìn)行查詢
之前通過子查詢嵌套來完成多表查詢,現(xiàn)在可以使用連接來實現(xiàn)
第十六章 創(chuàng)建高級聯(lián)結(jié)本章將講解外連接,以及如何對被聯(lián)結(jié)的表使用表別名和聚集函數(shù)。
使用表別名除了可以對列,計算字段起別名以外,還可以對表起別名。主要有以下好處:
1.縮短SQL語句(有些表名太長,可以起短的別名)
2.允許在單條SELECT語句中多次使用相同的表(對表進(jìn)行自連接查詢時會需要多次使用相同的表,在下面有相應(yīng)的例子說明)
除了上一章講到的內(nèi)部連接(等值連接)以為,還有自連接,自然連接,外部連接三種連接:
自連接自連接指的是一張表對自身進(jìn)行連接,進(jìn)行信息查詢。
例如:
某物品(其ID為DTNTR)存在問題,因此想知道生產(chǎn)該物 品的供應(yīng)商生產(chǎn)的其他物品是否也存在這些問題。此查詢要求首先找到 生產(chǎn)ID為DTNTR的物品的供應(yīng)商,然后找出這個供應(yīng)商生產(chǎn)的其他物品。
可以使用自連接的實現(xiàn):
此查詢中需要的兩個表實際上是相同的表,因此products表在
FROM子句中出現(xiàn)了兩次。雖然這是完全合法的,但對products 的引用具有二義性,所以使用表別名避免歧義。
當(dāng)然解決上面的這個查詢需求也可以使用子查詢來實現(xiàn),如下圖所示:
內(nèi)部連接會將一個表中的行與另一個表中的行想關(guān)聯(lián),有時候也需要包含不滿足關(guān)聯(lián)條件的那些行,這就是外連接。
例如:
這條SELECT語句使用了關(guān)鍵字OUTER JOIN來指定聯(lián)結(jié)的類型(而不是在WHERE子句中指 定)。但是,與內(nèi)部聯(lián)結(jié)關(guān)聯(lián)兩個表中的行不同的是,外部聯(lián)結(jié)還包括沒 有關(guān)聯(lián)行的行。在使用OUTER JOIN語法時,必須使用RIGHT或LEFT關(guān)鍵字 指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表,而LEFT 指出的是OUTER JOIN左邊的表)。上面的例子使用LEFT OUTER JOIN從FROM 子句的左邊表(customers表)中選擇所有行。
使用帶聚集函數(shù)的連接
聚集函數(shù)也可以和連接結(jié)合起來使用。
在這個例子中,使用INNER JOIN將customers和orders表互相關(guān)聯(lián)。GROUP BY子句按客戶分組數(shù)據(jù),因此,函數(shù)調(diào)用COUNT (orders.order_num)對每個客戶的訂單計數(shù),將它作為num_ord返回。
1.注意所使用的聯(lián)結(jié)類型。一般我們使用內(nèi)部聯(lián)結(jié),但使用外部聯(lián) 結(jié)也是有效的。
2.保證使用正確的聯(lián)結(jié)條件,否則將返回不正確的數(shù)據(jù)。
3.應(yīng)該總是提供聯(lián)結(jié)條件,否則會得出笛卡兒積。
4.在一個聯(lián)結(jié)中可以包含多個表,甚至對于每個聯(lián)結(jié)可以采用不同的聯(lián)結(jié)類型。雖然這樣做是合法的,一般也很有用,但應(yīng)該在一起測試它們前,分別測試每個聯(lián)結(jié)。這將使故障排除更為簡單。
第十七章 組合查詢在 MySQL 中,可以執(zhí)行多條查詢語句,然后對多個結(jié)果集,使用UNION語句合并成單個查詢結(jié)果集返回。主要有以下兩種應(yīng)用場景:
1.在單個查詢中從不同的表返回類似結(jié)構(gòu)的數(shù)據(jù)。
2.對單個表執(zhí)行多個查詢,將結(jié)果集合并成一個結(jié)果集。
例如我們需要價格小于等于5的所有物品的一個列表,而且 還想包括供應(yīng)商1001和1002生產(chǎn)的所有物品(不考慮價格),
這條語句由前面的兩條SELECT語句組成,語句中用UNION關(guān)鍵
字分隔。UNION指示MySQL執(zhí)行兩條SELECT語句,并把輸出組 合成單個查詢結(jié)果集,當(dāng)然這個需求也可以使用多條WHERE語句來實現(xiàn)。
1.UNION必須由兩條或兩條以上的SELECT語句組成,語句之間用關(guān) 鍵字UNION分隔(因此,如果組合4條SELECT語句,將要使用3個 UNION關(guān)鍵字)。
2.UNION中的每個查詢必須包含相同的列、表達(dá)式或聚集函數(shù)(不過
3.列數(shù)據(jù)類型必須兼容:類型不必完全相同,但必須是DBMS可以
隱含地轉(zhuǎn)換的類型(例如,不同的數(shù)值類型或不同的日期類型)。 如果遵守了這些基本規(guī)則或限制,則可以將并用于任何數(shù)據(jù)檢索任務(wù)。
4.在用UNION組合查詢時,如果需要對結(jié)果進(jìn)行排序,只能使用一條ORDER BY子句,它必須出現(xiàn)在最后一條SELECT語句之后。對 于結(jié)果集,不存在用一種方式排序一部分,而又用另一種方式排序另一 部分的情況,因此不允許使用多條ORDER BY子句。
5.UNION從查詢結(jié)果集中自動去除了重復(fù)的行(換句話說,它的行為與 單條SELECT語句中使用多個WHERE子句條件一樣)。因為供應(yīng)商1002生產(chǎn) 的一種物品的價格也低于5,所以兩條SELECT語句都返回該行。在使用 UNION時,重復(fù)的行被自動取消。這是UNION的默認(rèn)行為,但是如果允許重復(fù),可以使用UNION ALL而不是UNION。如下圖所示:
當(dāng)我們需要對文本進(jìn)行匹配,可以使用LIKE+通配符,或正則表達(dá)式的方式來實現(xiàn),但是這樣會存在很多限制:
1.性能不高——通配符和正則表達(dá)式匹配通常要求MySQL嘗試匹配表中所有行(而且這些搜索極少使用表索引)。因此,由于被搜索行數(shù)不斷增加,這些搜索可能非常耗時。
2.不太靈活——使用通配符和正則表達(dá)式匹配,很難(而且并不總是能)明確地控制匹配什么和不匹配什么。例如,指定一個詞必須匹配,一個詞必須不匹配,而一個詞僅在第一個詞確實匹配的情況下才可以匹配或者才可以不匹配。
3.無法智能化——雖然基于通配符和正則表達(dá)式的搜索提供了非常靈活的搜索,但它們都不能提供一種智能化的選擇結(jié)果的方法。 例如,一個特殊詞的搜索將會返回包含該詞的所有行,而不區(qū)分包含單個匹配的行和包含多個匹配的行(按照可能是更好的匹配 來排列它們)。類似,一個特殊詞的搜索將不會找出不包含該詞但包含其他相關(guān)詞的行。所以就有了全文搜索,為了進(jìn)行全文本搜索,必須索引被搜索的列,而且要隨著數(shù)據(jù)的改 變不斷地重新索引。在對表列進(jìn)行適當(dāng)設(shè)計后,MySQL會自動進(jìn)行所有 的索引和重新索引。在索引之后,SELECT可與Match()和Against()一起使用以實際執(zhí)行 搜索。
啟用全文本搜索支持在建表時或者建表以后使用FULLTEXT語句指定全文搜索的列,MySQL根據(jù)子句FULLTEXT(note_text)的指示對它進(jìn)行索引,在之后該列增加、更新或刪除行時, 索引隨之自動更新
如下圖所示:
如果正在導(dǎo)入數(shù)據(jù)到一個新表, 此時不應(yīng)該啟用FULLTEXT索引。應(yīng)該首先導(dǎo)入所有數(shù)據(jù),然后再修改表,定義FULLTEXT,這樣花費的時間會更少。
進(jìn)行全文本搜索在索引之后,使用兩個函數(shù)Match()和Against()執(zhí)行全文本搜索,
Match() 指定被搜索的列
Against() 指定要使用的搜索表達(dá)式
如下圖所示:SELECT語句檢索單個列note_text,將包含rabbit的行進(jìn)行返回。(全文搜索默認(rèn)不區(qū)分大小寫,除非使用BINARY語句進(jìn)行修飾)
全文搜索還可以使用Rank對結(jié)果進(jìn)行排序,Match()和Against() 用來建立一個計算列(別名為rank),此列包含全文本搜索計算出的等級 值。等級由MySQL根據(jù)行中詞的數(shù)目、唯一詞的數(shù)目、整個索引中詞的 總數(shù)以及包含該詞的行的數(shù)目計算出來。不包含搜索詞的行等級為0(因此不被前一例子中的WHERE子句選擇)。確實包含搜索詞的兩個行每行都有一個等級值,文本中詞靠前的行的等級值比詞靠后的行的等級值高。如下圖所示:
如果指定多個搜索項,則包含多數(shù)匹配詞的 那些行將具有比包含較少詞(或僅有一個匹配)的那些行高的 等級值。
使用查詢擴(kuò)展查詢擴(kuò)展用來設(shè)法放寬所返回的全文本搜索結(jié)果的范圍,它可以先進(jìn)行一個基本的全文本搜索,找出與搜索條件匹配的所有行。其次,MySQL檢查這些匹配行并選擇所有有用的詞,再其次,MySQL再次進(jìn)行全文本搜索,這次不僅使用原來的條件, 而且還使用所有有用的詞。如下圖所示;
MySQL支持全文本搜索的另外一種形式,稱為布爾方式(boolean
mode)。可以指定要匹配的詞,要排斥的詞,排列提示(指定某些詞比其他詞更重要,更重要的詞等級更高),表達(dá)式分組等。即使沒有定義 FULLTEXT索引,也可以使用它。但這是一種非常緩慢的操作。
例如:
在下圖里面的查詢中,會匹配詞heavy,但-rope*明確地
分析指示MySQL排除包含rope*(任何以rope開始的詞,包括 ropes)的行。
除了布爾操作符-和,-排除一個詞,而 是截斷操作符(可想象為用于詞尾的一個通配符)。還有以下全文本布爾操作符:
下面是一些全文本布爾操作符使用案例:
全文本搜索的使用說明
1.在索引全文本數(shù)據(jù)時,短詞被忽略且從索引中排除。短詞定義為 那些具有3個或3個以下字符的詞(如果需要,這個數(shù)目可以更改)。
2.MySQL帶有一個內(nèi)建的非用詞(stopword)列表,這些詞在索引全文本數(shù)據(jù)時總是被忽略。如果需要,可以覆蓋這個列表(請參閱MySQL文檔以了解如何完成此工作)。
3.許多詞出現(xiàn)的頻率很高,搜索它們沒有用處(返回太多的結(jié)果)。因此,MySQL規(guī)定了一條50%規(guī)則,如果一個詞出現(xiàn)在50%以上的行中,則將它作為一個非用詞忽略。50%規(guī)則不用于IN BOOLEAN MODE。
4.如果表中的行數(shù)少于3行,則全文本搜索不返回結(jié)果(因為每個詞或者不出現(xiàn),或者至少出現(xiàn)在50%的行中)。
5.忽略詞中的單引號。例如,don"t索引為dont。
6.不具有詞分隔符(包括日語和漢語)的語言不能恰當(dāng)?shù)胤祷厝?br>本搜索結(jié)果。
7.如前所述,僅在MyISAM數(shù)據(jù)庫引擎中支持全文本搜索。
8.沒有鄰近操作符,鄰近搜索是許多全文本搜索支持的一個特 性,它能搜索相鄰的詞(在相同的句子中、相同的段落中或者 在特定數(shù)目的詞的部分中,等等。MySQL全文本搜索現(xiàn)在還不支持鄰近操作符。
第十九章 插入數(shù)據(jù)使用INSERT語句插入數(shù)據(jù),大家都很熟悉。
例如向 Customers 表插入一條name為tom,age為29的數(shù)據(jù)
一般有以下兩種方式:
INSERT INTO Customers VALUES("tom", "29"); INSERT INTO Customers(name, age) VALUES("tom", "29");
一般推薦第二張方式,因為第一種方式的數(shù)據(jù)順序必須與列在表中的數(shù)據(jù)保持一致,容易寫錯,其次是當(dāng)表結(jié)構(gòu)發(fā)生改變時,第一種方式需要變更數(shù)據(jù)順序,第二種方式不需要。
插入檢索出的數(shù)據(jù)INSERT一般用來給表插入一個指定列值的行。但是,INSERT還存在 另一種形式,可以利用它將一條SELECT語句的結(jié)果插入表中。如下圖所示,這個例子使用INSERT SELECT從custnew表中將所有數(shù)據(jù)導(dǎo)入customers表
使用UPDATE語句更新數(shù)據(jù),大家都很熟練了,一般UPDATE語句組成部分如下:
UPDATE 表名 SET 列名 = 新值 WHERE 過濾條件;
如下圖所示:
需要注意的是:
1.在使用UPDATE語句時,不要省略WHERE子句 ,否則就會更新表中所有行。
2.IGNORE關(guān)鍵字,如果用UPDATE語句更新多行,并且在更新這些行中的一行或多行時出一個現(xiàn)錯誤,則整個UPDATE操作被取消 (錯誤發(fā)生前更新的所有行被恢復(fù)到它們原來的值)。為即使是發(fā)生錯誤,也繼續(xù)進(jìn)行更新,可使用IGNORE關(guān)鍵字,如下所示: UPDATE IGNORE customers...
刪除數(shù)據(jù)使用DELETE語句更新數(shù)據(jù),大家也都很熟練了,一般DELETE語句組成部分如下:
DELETE FROM 表名
WHERE 過濾條件;
如下圖所示:
需要注意的是:
1.在使用DELETE語句時,不要省略DELETE子句 ,否則會刪除表中所有行。
2.DELETE語句從表中刪除行,甚至是刪除表中所有行。但是,DELETE不刪除表本身。
3.如果想從表中刪除所有行,不要使用DELETE。 可使用TRUNCATE TABLE語句,它完成相同的工作,但速度更快,因為TRUNCATE實際是刪除原來的表并重新創(chuàng)建一個表,而不是逐行刪除表中的數(shù)據(jù)
更新和刪除的指導(dǎo)原則
1.除非確實打算更新和刪除每一行,否則絕對不要使用不帶WHERE 子句的UPDATE或DELETE語句。
2.保證每個表都有主鍵(如果忘記這個內(nèi)容,請參閱第15章),盡可能 像WHERE子句那樣使用它(可以指定各主鍵、多個值或值的范圍)。
3.在對UPDATE或DELETE語句使用WHERE子句前,應(yīng)該先用SELECT進(jìn)行測試,保證它過濾的是正確的記錄,以防編寫的WHERE子句不正確。
4.使用強(qiáng)制實施引用完整性的數(shù)據(jù)庫(關(guān)于這個內(nèi)容,請參閱第15
章),這樣MySQL將不允許刪除具有與其他表相關(guān)聯(lián)的數(shù)據(jù)的行。
5.MySQL沒有撤銷(undo)按鈕。應(yīng)該非常小心地使用UPDATE和DELETE,否則你會發(fā)現(xiàn)自己更新或刪除了錯誤的數(shù)據(jù)。
第二十一章 創(chuàng)建和操縱表 創(chuàng)建表使用CREATE語句來創(chuàng)建一個表,大家都很熟悉了,如下圖所示
需要注意的有以下幾點:
1.在建表時,每一列要么是可為NULL列,要么是NOT NULL列,如果不指定,默認(rèn)為可為NULL列。
2.主鍵必須保證唯一,不能為NULL。如果使用一個列作為主鍵,值必須唯一,如果使用多個列作為主鍵,那么多個列組合的值必須唯一。
3.MySQL有一個具體管理和處理數(shù)據(jù)的內(nèi)部引擎,在執(zhí)行SQL語句時,可以使用ENGINE語句指定引擎,如果省略ENGINE=語句,則使用默認(rèn)引擎(很可能是MyISAM),以下為MySQL常見的幾個引擎:
InnoDB
是一個可 靠的事 務(wù) 處 理 引 擎 ( 參 見 第 26 章 ), 它 不 支 持 全 文 本搜索;
MEMORY
在功能等同于MyISAM,但由于數(shù)據(jù)存儲在內(nèi)存(不是磁盤) 中,速度很快,所以特別適合于臨時表;
MyISAM
是一個性能極高的引擎,它支持全文本搜索(參見第18章), 但不支持事務(wù)處理。
更新表在表建立以后,如果需要對表結(jié)構(gòu)進(jìn)行修改,我們可以使用ALTER TABLE語句對表進(jìn)行修改。例如:
復(fù)雜的表結(jié)構(gòu)更改一般需要手動刪除過程,它涉及以下步驟:
1.用新的列布局創(chuàng)建一個新表。
2.使用INSERT SELECT語句從舊表復(fù)制數(shù)據(jù)到新表。如果有必要,可使用轉(zhuǎn)換函數(shù)和計算字段。
3.檢驗包含所需數(shù)據(jù)的新表。
4.重命名舊表(如果確定,可以刪除它)。
5.用舊表原來的名字重命名新表。
6.根據(jù)需要,重新創(chuàng)建觸發(fā)器、存儲過程、索引和外鍵。
刪除表刪除表(刪除整個表而不是其內(nèi)容)非常簡單,使用DROP TABLE語,例如:
刪除customers2表
DROP TABLE customers2;重命名表
使用RENAME TABLE語句可以重命名一個表。
例如:
將表customers2名字改為customers
RENAME TABLE customers2 to customers;第二十二章 使用視圖
視圖為虛擬的表。它們包含的不是數(shù)據(jù)而是根據(jù)需要檢索數(shù)據(jù)的查 詢。視圖提供了一種MySQL的SELECT語句層次的封裝,可用來簡化數(shù)據(jù) 處理以及重新格式化基礎(chǔ)數(shù)據(jù)或保護(hù)基礎(chǔ)數(shù)據(jù)。
后面就可以把productcustomers視圖看成一個虛擬表進(jìn)行查詢,如下圖所示:
1.重用SQL語句。
2.簡化復(fù)雜的SQL操作。在編寫查詢后,可以方便地重用它而不必 知道它的基本查詢細(xì)節(jié)。
3.使用表的組成部分而不是整個表。
4.保護(hù)數(shù)據(jù)。可以給用戶授予表的特定部分的訪問權(quán)限而不是整個表的訪問權(quán)限。
5.更改數(shù)據(jù)格式和表示。視圖可返回與底層表的表示和格式不同的數(shù)據(jù)。
視圖的規(guī)則和限制:1.與表一樣,視圖必須唯一命名(不能給視圖取與別的視圖或表相 同的名字)。
2.對于可以創(chuàng)建的視圖數(shù)目沒有限制。
3.為了創(chuàng)建視圖,必須具有足夠的訪問權(quán)限。這些限制通常由數(shù)據(jù)庫管理人員授予。
4.視圖可以嵌套,即可以利用從其他視圖中檢索數(shù)據(jù)的查詢來構(gòu)造一個視圖。
5.ORDER BY可以用在視圖中,但如果從該視圖檢索數(shù)據(jù)SELECT中也含有ORDER BY,那么該視圖中的ORDER BY將被覆蓋。
6.視圖不能索引,也不能有關(guān)聯(lián)的觸發(fā)器或默認(rèn)值。
7.視圖可以和表一起使用。例如,編寫一條聯(lián)結(jié)表和視圖的SELECT語句。
常見的視圖操作語句1.視圖用CREATE VIEW語句來創(chuàng)建。
2.使用SHOW CREATE VIEW viewname;來查看創(chuàng)建視圖的語句。
3.用DROP刪除視圖,其語法為DROP VIEW viewname;。
4.更新視圖時,可以先用DROP再用CREATE,也可以直接用CREATE OR REPLACE VIEW。如果要更新的視圖不存在,則第2條更新語句會創(chuàng)建一個視圖;如果要更新的視圖存在,則第2條更新語句會替換原有視圖。
我們上面的例子中視圖的作用其實是簡化復(fù)雜SQL的使用,其實視圖還有其他的作用,例如:
用視圖重新格式化檢索出的數(shù)據(jù) 用視圖過濾不想要的數(shù)據(jù) 更新視圖視圖是可更新的(也就是可以對它們使用INSERT、UPDATE和DELETE)。更新一個視圖將更新其基表(可以回憶一下,視圖本身沒有數(shù)據(jù))。如果你對視圖增加或刪除行,實際上是對其基表增加或刪除行。但是當(dāng)視圖定義中有以下操作時,則不能進(jìn)行視圖的更新:
1.分組(使用GROUP BY和HAVING); 聯(lián)結(jié);
2.子查詢;
3.并;
4.聚集函數(shù)(Min()、Count()、Sum()等);
5.DISTINCT;
6.導(dǎo)出(計算)列。
第二十三章 使用存儲過程存儲過程,就是可以一條或多條MySQL語句的組合起來,并且可以加入一些業(yè)務(wù)邏輯。
創(chuàng)建和執(zhí)行存儲過程簡單的示例:
使用CREATE PROCEDURE語句創(chuàng)建一個存儲過程,對一個SELECT語句進(jìn)行封裝,之后可以使用CALL語句來執(zhí)行這個存儲過程。
需要注意的是,因為在存儲過程中會包含一些;分隔符,而在命令行實用程序中,使用;字符來作為語句分隔符,為了避免語法錯誤,可以使用DELIMITER語句來定義一個新的語句結(jié)束分隔符。如下圖所示:
可以使用DROP PROCEDURE 語句來刪除一個存儲過程,例如:
刪除名為productpricing的存儲過程
DROP PROCEDURE productpricing;使用參數(shù)
在創(chuàng)建存儲過程時,可以使用IN語句來存儲傳入?yún)?shù),OUT語句來存儲返回結(jié)果。
在下面這個例子中,20005是傳入?yún)?shù),@total是返回結(jié)果。傳入?yún)?shù)和返回結(jié)果也可以定義多個。
在創(chuàng)建存儲過程中,也可以使用IF,THEN,END IF語句來設(shè)置判斷條件,這是存儲過程與簡單的語句封裝最大的區(qū)別。
例如:
添加了另外一個 參數(shù)taxable,它是一個布爾值(如果要增加稅則為真,否則為假)。在 存儲過程體中,用DECLARE語句定義了兩個局部變量。DECLARE要求指定 變量名和數(shù)據(jù)類型,它也支持可選的默認(rèn)值(這個例子中的taxrate的默 認(rèn)被設(shè)置為6%)。SELECT語句已經(jīng)改變,因此其結(jié)果存儲到total(局部 變量)而不是ototal。IF語句檢查taxable是否為真,如果為真,則用另 一SELECT語句增加營業(yè)稅到局部變量total。最后,用另一SELECT語句將 total(它增加或許不增加營業(yè)稅)保存到ototal。
BOOLEAN值指定為1表示真,指定為0表示假(實際上,非零值 都考慮為真,只有0被視為假)。通過給中間的參數(shù)指定0或1,可以有條件地將營業(yè)稅加到訂單合計上。
可以使用 SHOW CREATE PROCEDURE 語句顯示用來創(chuàng)建一個存儲過程的 CREATE 語句也可以使用 SHOW PROCEDURE STATUS 列出所有存儲過程。為限制其輸出,可使用LIKE指定一個過濾模式,例如:SHOW PROCEDURE STATUS LIKE "ordertotal";
第二十四章 使用游標(biāo)游標(biāo)(cursor)是一個存儲在MySQL服務(wù)器上的數(shù)據(jù)庫查詢, 它不是一條SELECT語句,而是被該語句檢索出來的結(jié)果集。在存儲了游 標(biāo)之后,應(yīng)用程序可以根據(jù)需要滾動或瀏覽結(jié)果集中的數(shù)據(jù)。
創(chuàng)建游標(biāo)定義了一個名為ordernumbers的游標(biāo)
打開名為ordernumbers的游標(biāo)
OPEN ordernumbers;
關(guān)閉名為ordernumbers的游標(biāo)
CLOSE ordernumbers;
如果不明確關(guān)閉游標(biāo),MySQL將會在到達(dá)END語句時自動關(guān)閉它。
使用游標(biāo)數(shù)據(jù)
這個例子使用FETCH檢索當(dāng)前order_num到聲明的名為o的變量中。但與前一個例子不一樣的是,這個 例子中的FETCH是在REPEAT內(nèi),因此它反復(fù)執(zhí)行直到done為真(由UNTIL done END REPEAT;規(guī)定)。為使它起作用,用一個DEFAULT 0(假,不結(jié) 束)定義變量done。當(dāng)在 FETCH 語句中引用的游標(biāo)位置處于結(jié)果表最后一行之后時,SQLSTATE會為02000,這個時候done會為真,停止循環(huán)。
可以使用觸發(fā)器是在MySQL響應(yīng) INSERT UPDATE DELETE 語句前后自動執(zhí)行一條MySQL語句。
創(chuàng)建觸發(fā)器創(chuàng)建觸發(fā)器語句的格式一般是
CREATE TRIGGER 觸發(fā)器名稱 觸發(fā)時機(jī) 觸發(fā)操作 FOR EACH ROW 執(zhí)行操作;
例如:
CREATE TRIGGER newproduct AFTER INSERT FOR EACH ROW SELECT "Product added";
CREATE TRIGGER用來創(chuàng)建名為newproduct的新觸發(fā)器。觸發(fā)器
可在一個操作發(fā)生之前或之后執(zhí)行,這里給出了AFTER INSERT, 所以此觸發(fā)器將在INSERT語句成功執(zhí)行后執(zhí)行。這個觸發(fā)器還指定FOR EACH ROW,因此代碼對每個插入行執(zhí)行。在這個例子中,文本Product added將對每個插入的行顯示一次。
DROP TRIGGER newproduct;刪除名為newproduct的觸發(fā)器INSERT觸發(fā)器
在INSERT觸發(fā)器代碼內(nèi),可引用一個名為NEW的虛擬表,訪問被 插入的行;
在BEFORE INSERT觸發(fā)器中,NEW中的值也可以被更新(允許更改 被插入的值);
對于AUTO_INCREMENT列,NEW在INSERT執(zhí)行之前列的值會是0,在INSERT 執(zhí)行之后包含新的自動生成值。
上面的例子中創(chuàng)建一個名為neworder的觸發(fā)器,它按照AFTER INSERT ON orders執(zhí)行。在插入一個新訂單到orders表時,MySQL生 成一個新訂單號并保存到order_num中。觸發(fā)器從NEW. order_num取得這個值并返回它。
DELETE觸發(fā)器在DELETE語句執(zhí)行之前或之后執(zhí)行,在DELETE觸發(fā)器代碼內(nèi),你可以引用一個名為OLD的虛擬表,訪問被刪除的行。OLD中的值全都是只讀的,不能更新。
上面這個例子中,在任意訂單被刪除前將執(zhí)行此觸發(fā)器。它使用一條INSERT語句將OLD中的值(要被刪除的訂單)保存到一個名為archive_ orders的存檔表中(為實際使用這個例子,你需要用與orders相同的列 創(chuàng)建一個名為archive_orders的表)。
UPDATE觸發(fā)器在UPDATE語句執(zhí)行之前或之后執(zhí)行。在UPDATE觸發(fā)器代碼中,你可以引用一個名為OLD的虛擬表訪問 以前(UPDATE語句前)的值,引用一個名為NEW的虛擬表訪問新 更新的值。在BEFORE UPDATE觸發(fā)器中,NEW中的值可能也被更新(允許更改 將要用于UPDATE語句中的值)。OLD中的值全都是只讀的,不能更新。
上面面的例子保證州名縮寫總是大寫(不管UPDATE語句中給出的是大 寫還是小寫)
1.只有表才支持觸發(fā)器,視圖不支持(臨時表也不 支持)。
2.如果BEFORE觸發(fā)器失敗,則MySQL將不執(zhí)行請求的操作。此外,如果BEFORE觸發(fā)器或語句本身失敗,MySQL 將不執(zhí)行AFTER觸發(fā)器(如果有的話)。
3.與其他DBMS相比,MySQL 5中支持的觸發(fā)器相當(dāng)初級。未來的MySQL版本中有一些改進(jìn)和增強(qiáng)觸發(fā)器支持的計劃。
4.創(chuàng)建觸發(fā)器可能需要特殊的安全訪問權(quán)限,但是,觸發(fā)器的執(zhí)行是自動的。如果INSERT、UPDATE或DELETE語句能夠執(zhí)行,則相關(guān) 的觸發(fā)器也能執(zhí)行。
5.應(yīng)該用觸發(fā)器來保證數(shù)據(jù)的一致性(大小寫、格式等)。在觸發(fā)器中執(zhí)行這種類型的處理的優(yōu)點是它總是進(jìn)行這種處理,而且是透 明地進(jìn)行,與客戶機(jī)應(yīng)用無關(guān)。
6.觸發(fā)器的一種非常有意義的使用是創(chuàng)建審計跟蹤。使用觸發(fā)器, 把更改(如果需要,甚至還有之前和之后的狀態(tài))記錄到另一個 表非常容易。
7.遺憾的是,MySQL觸發(fā)器中不支持CALL語句。這表示不能從觸發(fā) 器內(nèi)調(diào)用存儲過程。所需的存儲過程代碼需要復(fù)制到觸發(fā)器內(nèi)。
第二十六章 管理事務(wù)處理事務(wù)處理可以用來維護(hù)數(shù)據(jù)庫的完整性,它保證一組SQL語句要么完全執(zhí)行,要么完全不執(zhí)行。利用事務(wù)處理,可以保證一組操作不會中途停止,它們 或者作為整體執(zhí)行,或者完全不執(zhí)行(除非明確指示)。如果沒有錯誤發(fā) 生,整組語句提交給(寫到)數(shù)據(jù)庫表。如果發(fā)生錯誤,則進(jìn)行回退(撤 銷)以恢復(fù)數(shù)據(jù)庫到某個已知且安全的狀態(tài)。
事務(wù)(transaction)指一組SQL語句;
回退(rollback)指撤銷指定SQL語句的過程;
提交(commit)指將未存儲的SQL語句結(jié)果寫入數(shù)據(jù)庫表;
保留點(savepoint)指事務(wù)處理中設(shè)置的臨時占位符(place-
holder),你可以對它發(fā)布回退(與回退整個事務(wù)處理不同)。
事務(wù)開始 START TRANSACTION使用ROLLBACK
MySQL的ROLLBACK命令用來回退(撤銷)MySQL語句。例如:
從顯示ordertotals表(此表在第24章中填充)的內(nèi)
容開始。首先執(zhí)行一條SELECT以顯示該表不為空。然后開始一 個事務(wù)處理,用一條DELETE語句刪除ordertotals中的所有行。另一條 SELECT語句驗證ordertotals確實為空。這時用一條ROLLBACK語句回退 START TRANSACTION之后的所有語句,最后一條SELECT語句顯示該表不為空。
ROLLBACK只能在一個事務(wù)處理內(nèi)使用(在執(zhí)行一條START TRANSACTION命令之后)。可以回退INSERT、UPDATE和 DELETE語句。不能回退SELECT,CREATE,DROP語句。
一般的MySQL語句都是直接針對數(shù)據(jù)庫表執(zhí)行和編寫的。這就是所謂的隱含提交(implicit commit),即提交(寫或保存)操作是自動進(jìn)行的。但是,在事務(wù)處理塊中,提交不會隱含地進(jìn)行。為進(jìn)行明確的提交, 使用COMMIT語句。
在這個例子中,從系統(tǒng)中完全刪除訂單20010。因為涉及更新
兩個數(shù)據(jù)庫表orders和orderItems,所以使用事務(wù)處理塊來 保證訂單不被部分刪除。最后的COMMIT語句僅在不出錯時寫出更改。如 果第一條DELETE起作用,但第二條失敗,則DELETE不會提交(會被自動撤銷)。
簡單的ROLLBACK和COMMIT語句就可以寫入或撤銷整個事務(wù)處理。但 是,只是對簡單的事務(wù)處理才能這樣做,更復(fù)雜的事務(wù)處理可能需要部 分提交或回退。為了支持回退部分事務(wù)處理,必須能在事務(wù)處理塊中合適的位置放 置占位符。這樣,如果需要回退,可以回退到某個占位符。
創(chuàng)建占位符SAVEPOINT delete1;創(chuàng)建一個名稱為delete1的占位符 ROLLBACK TO delete1;回退到delete1的占位符
保留點在事務(wù)處理完成(執(zhí)行一條ROLLBACK或 COMMIT)后自動釋放。自MySQL 5以來,也可以用RELEASE SAVEPOINT明確地釋放保留點。
更改默認(rèn)的提交行為默認(rèn)的MySQL行為是自動提交所有更改。換句話說,任何 時候你執(zhí)行一條MySQL語句,該語句實際上都是針對表執(zhí)行的,而且所做 的更改立即生效。為指示MySQL不自動提交更改,可以使用
SET autocommit=0;
autocommit標(biāo)志決定是否自動提交更改,不管有沒有COMMIT
語句。設(shè)置autocommit為0(假)指示MySQL不自動提交更改 (直到autocommit被設(shè)置為真為止)。
數(shù)據(jù)庫表被用來存儲和檢索數(shù)據(jù)。不同的語言和字符集需要以不同 的方式存儲和檢索。因此,MySQL需要適應(yīng)不同的字符集(不同的字母 和字符),適應(yīng)不同的排序和檢索數(shù)據(jù)的方法。
使用字符集和校對順序show CHARACTER SET;
可以展示可用的字符集,MySQL 默認(rèn)字符集是latin1,一般我們常用的就是utf8
show COLLATION;
可以展示所支持校對以及它們適用的字符集的完整列表,有的字符集具有不止一種校對。
通常系統(tǒng)管理在安裝時定義一個默認(rèn)的字符集和校對。此外,也可 以在創(chuàng)建數(shù)據(jù)庫時,指定默認(rèn)的字符集和校對。和校對,可以使用以下語句進(jìn)行查看:
show VARIABLES like "character%";查看字符集相關(guān)的配置 show VARIABLES like "collation%";查看校對相關(guān)的配置給表指定字符集和校對
這個例子中指定了CHARACTER SET和COLLATE兩者。一般,MySQL如
下確定使用什么樣的字符集和校對。
1.如果指定CHARACTER SET和COLLATE兩者,則使用這些值。
2.如果只指定CHARACTER SET,則使用此字符集及其默認(rèn)的校對(如SHOW CHARACTER SET的結(jié)果中所示)。
3.如果既不指定CHARACTER SET,也不指定COLLATE,則使用數(shù)據(jù)庫默認(rèn)。
對列指定字符集和校對 查詢時指定校對順序
此SELECT使用COLLATE指定一個備用的校對順序(在這個例子 中,為區(qū)分大小寫的校對)。除了這里看到的在ORDERBY子 句中使用以外,COLLATE還可以用于GROUP BY、HAVING、聚集 函數(shù)、別名等。
MySQL用戶賬號和信息存儲在名為mysql的MySQL數(shù)據(jù)庫中。
獲得所有用戶賬號列表
CREATE USER ben IDENTIFIED BY "passwOrd";
CREATE USER創(chuàng)建一個新用戶賬號。在創(chuàng)建用戶賬號時不一定需要密碼,不過這個例子用IDENTIFIED BY "passwOrd"給出了一個密碼。
RENAME USER ben TO bforta;刪除用戶賬號
DROP USER bforta;設(shè)置訪問權(quán)限
為看到賦予用戶賬號的權(quán)限,使用SHOW GRANTS FOR,如下圖所示:
輸出結(jié)果顯示用戶bforta有一個權(quán)限USAGE ON .。此結(jié)果表示在任意數(shù)據(jù)庫和任意表上對任何數(shù)據(jù)沒有權(quán)限。
用戶定義為user@host MySQL的權(quán)限將會把用戶名和主機(jī)名結(jié)合定義。如果不指定主機(jī)名,則使用默認(rèn)的主機(jī)名%(授予用戶訪問權(quán)限而不管主機(jī)名)。
GRANT語句的一般格式是
GRANT 權(quán)限 ON 范圍 TO 用戶;
例如:
GRANT SELECT ON crashhouse.* TO bforta;
GRANT允許用戶在crashcourse.*(crashcourse數(shù)據(jù)庫的所
有表)上使用SELECT語句。
SHOW GRANTS可以用來顯示bforta用戶的權(quán)限
GRANT的反操作為REVOKE,用它來撤銷特定的權(quán)限。
REVOKE SELECT ON crashhouse.* FROM bforta;
這條REVOKE語句取消剛賦予用戶bforta的SELECT訪問權(quán)限。被 撤銷的訪問權(quán)限必須存在,否則會出錯。
GRANT和REVOKE可在幾個層次上控制訪問權(quán)限:
1.整個服務(wù)器,使用GRANT ALL和REVOKE ALL;
2.整個數(shù)據(jù)庫,使用ON database.*;
3.特定的表,使用ON database.table;
4.特定的列;
5.特定的存儲過程。
下面是可以授予或撤銷的每個權(quán)限:
在使用GRANT和REVOKE時,用戶賬號必須存在, 但對所涉及的對象沒有這個要求。這允許管理員在創(chuàng)建數(shù)據(jù)庫 和表之前設(shè)計和實現(xiàn)安全措施。這樣做的副作用是,當(dāng)某個數(shù)據(jù)庫或表被刪除時(用DROP語 句),相關(guān)的訪問權(quán)限仍然存在。而且,如果將來重新創(chuàng)建該 數(shù)據(jù)庫或表,這些權(quán)限仍然起作用。
更改密碼更改特定用戶的密碼
SET PASSWORD FOR bforta = Password("123456");
更改當(dāng)前用戶的密碼
SET PASSWORD = Password("123456");第二十九章 數(shù)據(jù)庫維護(hù)
備份數(shù)據(jù)一般有以下幾種方案:
1.使用命令行實用程序 mysqldump
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/45127.html
摘要:主鍵唯一標(biāo)識表中每行的這個列稱為主鍵。不為空,每行數(shù)據(jù)必須具有一個主鍵值。主要負(fù)責(zé)與用戶進(jìn)行交互,接受用戶的指令,然后發(fā)出請求給,負(fù)責(zé)數(shù)據(jù)訪問和處理,然后將結(jié)果返回給。注意雖然似乎通配符可以匹配任何東西,但有一個例外,即。 為什么寫這篇文章 因為我最近的一些工作內(nèi)容跟數(shù)據(jù)分析比較密切,所以需要對SQL使用得比較熟練,所以便閱讀了《MySQL 必知必會》這本書,為了檢驗自己的閱讀效果及幫...
摘要:報文用于協(xié)議交互的信息被稱為報文?,F(xiàn)在出現(xiàn)的各種首部字段及狀態(tài)碼稍后會闡述。狀態(tài)碼響應(yīng)報文包含了多個范圍的內(nèi)容使用。如果服務(wù)器無法響應(yīng)范圍請求,則會返回狀態(tài)碼和完整的實體內(nèi)容。 showImg(https://segmentfault.com/img/bVbthNL?w=900&h=500); http報文 用于HTTP協(xié)議交互的信息被稱為HTTP報文。請求端的http報文叫做請求報文...
閱讀 891·2023-04-25 20:18
閱讀 2184·2021-11-22 13:54
閱讀 2637·2021-09-26 09:55
閱讀 4026·2021-09-22 15:28
閱讀 3049·2021-09-03 10:34
閱讀 1791·2021-07-28 00:15
閱讀 1702·2019-08-30 14:25
閱讀 1396·2019-08-29 17:16