日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql中以下正确的sql是_总结MySQL中SQL语法的使用

發(fā)布時(shí)間:2025/5/22 数据库 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql中以下正确的sql是_总结MySQL中SQL语法的使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

--where子句操作符:

where子句操作符

=

等于

<>

不等于(標(biāo)準(zhǔn)語法)

!=

不等于(非標(biāo)準(zhǔn)語法,可移植性差)

<

小于

<=

小于等于

>

大于

>=

大于等于

between

在指定的兩個(gè)值之間

IS NULL

空值檢查

IN(a, b)

在a與b之間

NOT

注意NOT在復(fù)雜語句中的應(yīng)用,比如NOT IN(A, B),在簡單語句中,NOT沒有什么特別之處,但是在復(fù)雜語句中,顯得很重要

在MySQL中使用NOT對(duì)IN、BETWEEN和EXISTS子句取反,這個(gè)多數(shù)其他DBMS允許使用NOT對(duì)各種條件取反有很大差別

--通配符:%與_

%與_

%

%s

s%

s%e

%匹配的是單個(gè)或多個(gè)字符

_

_s

s_

s_e

_匹配的是單個(gè)字符而不是多個(gè)字符

--正則表達(dá)式:注意[]是另一種形式的OR,比如[123]Ton是[1|2|3]Ton的縮寫,如果不使用[],則會(huì)匹配出其他行的數(shù)據(jù),

如:1|2|3 ton就會(huì)檢索出Jet 1000

[1-9]、[a-Z],如果是匹配一些特殊的字符要使用\\進(jìn)行轉(zhuǎn)義,如\\.表示查找.  \\\表示查找\

空白元字符:\\f換頁  \\n換行?   \\r回車?   \\t制表   \\v縱向制表

--匹配字符類:

匹配字符類

[:alnum:]

任意字母和數(shù)字(同[a-xA-Z0-9])

[:alpha:]

任意字符(同[a-zA-Z])

[:blank:]

空格和制表(同[\\t])

[:cntrl:]

ASCII控制字符(ASCII 0到31和127)

[:digit:]

任意數(shù)字(同[0-9])

[:graph:]

與[:print:]相同,但不包括空格

[:lower:]

任意小寫字母(同[a-z])

[:print:]

任意可打印的字符

[:punct:]

既不在[:alnum:]又不在[:cntrl:]中的任意字符

[:space:]

包括空格在內(nèi)的任意空白字符(同[\\f\\n\\r\\t\\v])

[:upper:]

任意大寫字母([A-Z])

[:xdigit:]

任意十六進(jìn)制數(shù)字(同[a-fA-F0-9])

匹配多個(gè)實(shí)例:

匹配多個(gè)實(shí)例

*

0個(gè)或多個(gè)匹配

+

1個(gè)或多個(gè)匹配

?

0個(gè)或1個(gè)匹配(等于{1,})

{n}

指定數(shù)目的匹配

{n,}

不少于指定數(shù)目的匹配

{n,m}

匹配數(shù)目的范圍(m不超過255)

--創(chuàng)建拼接字段

MySQL中使用concat(a,b)函數(shù)來拼接兩個(gè)列,但是多數(shù)DBMS使用+或||來實(shí)現(xiàn)拼接

Trim函數(shù)去掉串左右兩邊的空格,RTrim()函數(shù)去掉值右邊的所有空格,LTrim()函數(shù)去掉值左邊的所有空格

--使用別名

關(guān)鍵字是as,當(dāng)然as可以省略,但盡量不省略,根據(jù)經(jīng)驗(yàn),有時(shí)候普as不寫會(huì)報(bào)錯(cuò)

--執(zhí)行算術(shù)計(jì)算

操作符:+加-減*乘/除

select NOW()返回當(dāng)前日期和時(shí)間

--使用數(shù)據(jù)處理函數(shù)

文本處理函數(shù):

文本處理函數(shù)

Left()

返回串左邊的字符

Length()

返回串的長度

Locate()

找出串的一個(gè)字串

Lower()

將串轉(zhuǎn)換為小寫

LTrim()

去掉串左邊的空格

Right()

返回串右邊的字符

RTrim()

去掉串右邊的空格

Soundex()

返回串的SOUNDEX的值

SubString()

返回字串的字符

Upper()

將串轉(zhuǎn)換為大寫

日期和時(shí)間處理函數(shù):

日期和時(shí)間處理函數(shù)

AddDate()

增加一個(gè)日期(天、周等)

AddTime()

增加一個(gè)時(shí)間(時(shí)、分等)

CurDate()

返回當(dāng)前的日期

CurTime()

返回當(dāng)前的時(shí)間

Date()

返回日期時(shí)間的日期部分

DateDiff()

計(jì)算兩個(gè)日期之差

Date_Add()

高度靈活的日期運(yùn)算函數(shù)

Date_Format()

返回一個(gè)格式化的日期或時(shí)間串

Day()

返回一個(gè)日期的天數(shù)部分

DayOfWeek()

對(duì)于一個(gè)日期,返回對(duì)應(yīng)的星期幾

Hour()

返回一個(gè)時(shí)間的小時(shí)部分

Minute()

返回一個(gè)時(shí)間的分鐘部分

Month()

返回一個(gè)日期的月份部分

Now()

返回當(dāng)前日期和時(shí)間

Second()

返回一個(gè)時(shí)間的秒部分

Time()

返回一個(gè)日期時(shí)間的時(shí)間部分

Year()

返回一個(gè)日期的年份部分

數(shù)值處理函數(shù):

數(shù)值處理函數(shù)

Abs()

返回一個(gè)數(shù)的絕對(duì)值

Cos()

返回一個(gè)角度的余弦

Exp()

返回一個(gè)數(shù)的指數(shù)值

Mod()

返回一個(gè)除操作的余數(shù)

Pi()

返回圓周率

Rand()

返回一個(gè)隨機(jī)數(shù)

Sin()

返回一個(gè)角度的正弦

Sqrt()

返回一個(gè)數(shù)的平方根

Tan()

返回一個(gè)角度的正切

----匯總數(shù)據(jù)

--聚集函數(shù):

聚集函數(shù)

AVG()

返回某列的平均值

COUNT()

返回某列的行數(shù)

MAX()

返回某列的最大值

MIN()

返回某列的最小值

SUM()

返回某列值之和

--聚集不同值

上述的5個(gè)聚集函數(shù)都可以如下使用:

1、對(duì)所有的行執(zhí)行計(jì)算,指定ALL參數(shù)或不給參數(shù)(因?yàn)锳LL是默認(rèn)行為)

2、只包含不同的值,指定DISTINCT參數(shù)

如果指定列名,則DISTINCT只能用于COUNT(),按技術(shù)上來說,DISTINCT可以用于MAX()和MIN(),但是沒有意義

--組合聚集函數(shù)

意思就是select可以包含多個(gè)聚集函數(shù)

--分組數(shù)據(jù)

關(guān)鍵字GROUP BY

規(guī)定:

1、GROUP BY子句可以包含任意數(shù)目的列

2、如果在GROUP BY子句中嵌套了分組,數(shù)據(jù)將在最后規(guī)定的分組上進(jìn)行匯總,換句話說,在建立分組時(shí),指定的所有列都一起計(jì)算(所以不能從個(gè)別的列取回?cái)?shù)據(jù))

3、GROUP BY子句中列出的每個(gè)列都必須時(shí)檢索列或者有效的表達(dá)式(但不能是聚集函數(shù)),如果在select中使用表達(dá)式,則必須在GROUP BY子句中指定

相同的表達(dá)式,不能使用別名

4、除聚集計(jì)算語句外,select語句中的每個(gè)列都必須在GROUP BY子句中給出

5、如果分組列中具有NULL值,則NULL將作為一個(gè)分組返回。如果列中有多行NULL值,它們將分為一組

6、GROUP BY子句必須出現(xiàn)在WHERE子句之后,ORDER BY子句之前

使用ROLLUP,使用WITH ROLLUP關(guān)鍵字,可以得到每個(gè)分組以及每個(gè)分組匯總界別級(jí)別(針對(duì)每個(gè)分組)的值

過濾分組:

關(guān)鍵字HAVING

除了能用GROUP BY分組數(shù)據(jù)外,MySQL還允許使用過濾分組,規(guī)定包括哪些分組,排除哪些分組。因?yàn)閃HERE沒有分組的概念,所以WHERE過濾指定的是行而不是分組。

目前為止所學(xué)過的所有類型的WHERE子句都可以用HAVING來替代,唯一的差別是WHERE是過濾行,而HAVING過濾分組。過濾是基于分組聚集值而不是特定行值的。

另一種思維區(qū)分HAVING和WHERE:

WHERE在數(shù)據(jù)分組前進(jìn)行過濾,HAVING在數(shù)據(jù)分組后進(jìn)行過濾。這是一個(gè)重要區(qū)別,WHERE排除的行不包括在分組中,這可能會(huì)改變計(jì)算值,從而影響HAVING子句中基于這些值過濾掉的分組。

分組和排序:

ORDER BY和GOURP BY區(qū)別

ORDER BY

GROUP BY

排序產(chǎn)生的輸出

分組行。但輸出可能不是分組的順序

任意列都可以使用(甚至非選擇的列也可以使用)

只可能使用選擇列或表達(dá)式列,而且必須使用每個(gè)選擇列表達(dá)式

不一定需要

如果和聚集函數(shù)一起使用列(或表達(dá)式),則必須使用

PS:一般在使用GROUP BY子句時(shí),應(yīng)該也給出ORDER BY子句。這是保證數(shù)據(jù)正確排序的唯一方法,千萬不要依賴于GROUP BY排序數(shù)據(jù)

SELECT子句順序:

SELECT子句及其順序

子句

說明

是否必須使用

SELECT

要返回的列或表達(dá)式

FROM

從中檢索數(shù)據(jù)的表

僅在從表選擇數(shù)據(jù)時(shí)使用

WHERE

行級(jí)過濾

GROUP BY

分組說明

僅在按組計(jì)算聚集時(shí)使用

HAVING

組級(jí)過濾

ORDER BY

輸出排序順序

LIMIT

要檢索的行數(shù)

--使用子查詢

在select中創(chuàng)建多個(gè)select

利用子查詢進(jìn)行過過濾

作為計(jì)算字段使用子查詢,就是子查詢作為一個(gè)字段

----聯(lián)結(jié)表

PS:叉聯(lián)結(jié)(cross join),有時(shí)我們會(huì)聽到返回成為叉聯(lián)結(jié)的笛卡爾積的聯(lián)結(jié)類型

--內(nèi)部聯(lián)結(jié)

目前所用的聯(lián)結(jié)成為等值聯(lián)結(jié)(equijoin),基于兩個(gè)表之間的相等的測(cè)試,又稱為內(nèi)部聯(lián)結(jié)。

ANSI SQL規(guī)范首選INNER JOIN語法,此外盡管使用WHERE子句定義聯(lián)結(jié)的確比較簡單,但是使用明確的聯(lián)結(jié)語法能夠確保不會(huì)忘記聯(lián)結(jié)條件,有時(shí)候這樣做也能影響性能。

----創(chuàng)建高級(jí)聯(lián)結(jié)

除了使用別名引用唄檢索的表列,給列起別名的用法如下,寫的原因主要是沒見過這種concat的用法:

SELECT Concat(RTrim(vend_name), '(', RTrim(vend_country), ')')ASvend_titleFROMvendorsORDER BY vend_name

----使用不同類型的聯(lián)結(jié)

內(nèi)部聯(lián)結(jié)或等值聯(lián)結(jié)都是簡單聯(lián)結(jié),其實(shí)還有其他聯(lián)結(jié),分別是自聯(lián)結(jié)、自然聯(lián)結(jié)和外部聯(lián)結(jié)

--自聯(lián)結(jié)

用自聯(lián)結(jié)而不用子查詢:自然聯(lián)結(jié)通常作為外部語句用來替代從相同表中檢索數(shù)據(jù)時(shí)使用的子查詢語句。雖然最終的結(jié)果是一樣的,但有時(shí)候處理聯(lián)結(jié)遠(yuǎn)比處理子查詢快得多。應(yīng)該試一下兩種方法,以確定哪一種的性能更好。

selectprod_id,prod_name

fromproducts

where vend_id = (selectvend_id

fromproducts

where prod_id = 'DTNTR');

---------------------------------------------------

select p1.prod_id, p1.prod_name

from products as p1, products as p2

where p1.vend_id = p2.vend_id

and p2.prod_id = 'DTNTR';

--自然聯(lián)結(jié)

PS:事實(shí)上,迄今為止,我們建立的每個(gè)內(nèi)部聯(lián)結(jié)都是自然聯(lián)結(jié),很可能我們永遠(yuǎn)都不會(huì)用到不是自然聯(lián)結(jié)的內(nèi)部聯(lián)結(jié)

--外部聯(lián)結(jié)

聯(lián)結(jié)包含了那些在相關(guān)表中沒有關(guān)聯(lián)行的行,這種類型的聯(lián)結(jié)稱為外部聯(lián)結(jié)

selectcustomer.cust_id, orders.order_numfrom customers inner joinorderson customers.cust_id =orders.cust_id;selectcustomer.cust_id, orders.order_numfrom customers left joinorderson customers.cust_id = orders.cust_id;

PS:

1、沒有*=操作符,MySQL不支持簡化字符*=和=*的使用,這兩種操作符在其他DBMS中很流行

2、外部聯(lián)結(jié)的類型:存在兩種基本的外部聯(lián)結(jié)形式:左外部聯(lián)結(jié)和右外部聯(lián)結(jié)。它們之間的唯一差別是所關(guān)聯(lián)的表的順序不同。換句話說,左外部聯(lián)結(jié)可通過顛倒from或where子句中表的順序轉(zhuǎn)化為右外部聯(lián)結(jié)。因此,兩種類型的外部聯(lián)結(jié)可互換使用,而究竟使用哪一種純粹是根據(jù)方便而定。

--使用帶聚集函數(shù)的聯(lián)結(jié)

selectcustomer.cust_id,

customer.cust_name,count(orders.order_num) asnum_ordfromcustomerinner joinorderson customer.cust_id =orders.cust_idgroup by customer.cust_id

--使用聯(lián)結(jié)和聯(lián)結(jié)條件

要點(diǎn):

1、注意所使用的聯(lián)結(jié)類型。一般我們使用內(nèi)部聯(lián)結(jié),但使用外部聯(lián)結(jié)也是有效的

2、保證使用正確的聯(lián)結(jié)條件,否則將返回不正確的數(shù)據(jù)

3、應(yīng)該總是提供聯(lián)結(jié)條件,否則會(huì)得出笛卡爾積

4、在一個(gè)聯(lián)結(jié)中可以包含多個(gè)表,甚至對(duì)于每個(gè)聯(lián)結(jié)可以采取不同的聯(lián)結(jié)類型。雖然這樣做是合法的,一般也很有用,但應(yīng)該在一起測(cè)試它們前,分別測(cè)試每個(gè)聯(lián)結(jié)。這將是故障排除更為簡單。

----組合查詢

--組合查詢

MySQL允許執(zhí)行多個(gè)查詢(多條select語句),并將結(jié)果作為單位查詢結(jié)果集返回。這些組合查詢通常成為并(union)或復(fù)合查詢(compound query)。

有兩種基本情況,其中需要使用組合查詢:

1、在單個(gè)查詢中從不同的表返回類似結(jié)構(gòu)的數(shù)據(jù);

2、對(duì)單個(gè)表執(zhí)行多個(gè)查詢,按單個(gè)查詢返回?cái)?shù)據(jù)。

組合查詢和多個(gè)where條件:多數(shù)情況下,組合相同表的兩個(gè)查詢完成的工作與具有多個(gè)where子句條件的單條查詢完成的工作相同。換句話說,任何具有多個(gè)where子句的select語句都可以作為一個(gè)組合查詢給出,在以下段落中可以看到這一點(diǎn)。這兩種技術(shù)在不同的查詢中,性能也不同。因此,應(yīng)該試一下兩種技術(shù),以確定對(duì)特定的查詢哪一種性能更好。

--使用union創(chuàng)建組合查詢

給出每條select語句,在各條語句之間放上關(guān)鍵字union,下述寫法就是將兩個(gè)select查詢的東西合并在一起(3列)

selectvend_id, prod_id, prod_pricefromproductswhere prod_price <= 5

union

selectvend_id, prod_id, prod_pricefromproductswhere vend_id in (1001,1002)

簡單例子中,union比where復(fù)雜,但是遇到復(fù)雜的過濾條件,或者從多個(gè)表(而不是單個(gè)表)中檢索數(shù)據(jù)的情形,使用union可能會(huì)使處理更簡單。

--union規(guī)則

注意:

1、union必須由兩條以上的select語句組成,語句之間用關(guān)鍵字union分隔(因此,如果組合4條select語句,將要使用3個(gè)union關(guān)鍵字)

2、union中的每個(gè)查詢必須包含相同的列、表達(dá)式或聚集函數(shù)(不過各個(gè)列不需要以相同的次序列出)

3、列數(shù)據(jù)類型必須兼容:類型不必完全相同,但必須是DBMS可以隱含地轉(zhuǎn)換的類型(例如,不同的數(shù)值類型或不同的日期類型)

如果遵守了這些基本規(guī)則或限制,則可以將并用于任何數(shù)據(jù)檢索任務(wù)。

--包含或取消重復(fù)的行

在union的默認(rèn)行為中,是取消了重復(fù)行的,但是可以使用union all來返回所有匹配行

ps:union與where:union幾乎總是完成與多個(gè)where條件相同的工作。union all為union的一種形式,它完成where子句完成不了的工作。如果確實(shí)需要每個(gè)條件的匹配行全部出現(xiàn)(包括重復(fù)行),則必須使用union all而不是where。

--對(duì)組合查詢結(jié)果排序

在用union組合查詢時(shí),只能使用一條order by子句,它必須出現(xiàn)在最后一條select語句之后。對(duì)于結(jié)果集,不存在用一種方式排序一部分,而有用另一種方式排序另一部分的情況,因此不允許使用多條order by子句。

ps:組合不同的表:使用union的組合查詢可以應(yīng)用不同的表。

----全文本搜索

并非所有引擎都支持全文本搜索:MySQL支持幾種基本的數(shù)據(jù)庫引擎。并非所有的引擎都支持該文章所描述的全文本搜索。兩個(gè)最常使用的引擎為MyISAM和InnoDB。前者支持全文本搜索,而后者不支持。

like和正則表達(dá)式等搜索機(jī)制存在幾個(gè)重要的限制:

1、性能:通配符和正則表達(dá)式匹配通常要求MySQL嘗試匹配表中所有行(而且這些搜索極少使用)。因此,由于被搜索行數(shù)不斷增加,這些搜索可能非常耗時(shí)

2、明確控制:使用通配符和正則表達(dá)式匹配,很難(而且并不總是能)明確地控制匹配什么和不匹配什么。例如,指定一個(gè)詞必須匹配,一個(gè)詞必須不匹配,而一個(gè)詞僅在第一個(gè)詞確實(shí)匹配的情況下才可以匹配或者才可以不匹配

3、智能化的結(jié)果:雖然基于通配符和正則表達(dá)式的搜索提供了非常靈活的搜索,但它們都不能提供一種智能化的選擇結(jié)果的方法。例如,一個(gè)特殊詞的搜索將會(huì)返回多個(gè)包含該詞的所有行,而不區(qū)分包含單個(gè)匹配的行和包含多個(gè)匹配的行(按照可能時(shí)更好的匹配來排列它們)。類似,一個(gè)特殊詞的搜索將不會(huì)找出不包含該詞但包含其他相關(guān)詞的行。

所有這些限制以及更多的限制都可以用全文本搜索來解決。在使用全文本搜索時(shí),MySQL不需要分別查看每個(gè)行,不需要分別分析和處理每個(gè)詞。MySQL創(chuàng)建指定列中各詞的一個(gè)索引,搜索可以針對(duì)這些詞進(jìn)行。這樣,MySQL可以快速有效地決定哪些詞匹配(哪些行包含它們),哪些詞不匹配,它們匹配的頻率,等等。

--使用全文本搜索

為了進(jìn)行全文本搜索,必須索引被搜索的列,而且要隨著數(shù)據(jù)的改變不斷地重新搜索。在對(duì)表列進(jìn)行適當(dāng)設(shè)計(jì)后,MySQL會(huì)自動(dòng)進(jìn)行所有的索引和重新索引。

在索引之后,select可與match()和against()一起使用以實(shí)際執(zhí)行執(zhí)行搜索。

-------演示FULLTEXT子句的使用

create tableproductnotes

(

note_idint not nullauto_increment,

prod_idchar(10) not null,

note_datedatetime not null,PRIMARY KEY(note_id),FULLTEXT(note_text)

) ENGINE=MyISAM;

ps:不要在導(dǎo)入數(shù)據(jù)時(shí)使用FULLTEXT:更新索引要花時(shí)間,雖然不是很多,但畢竟要花時(shí)間。如果正在導(dǎo)入數(shù)據(jù)到一個(gè)新表,此時(shí)不應(yīng)該啟用FULLTEXT索引。應(yīng)該首先導(dǎo)入所有數(shù)據(jù),然后再修改表,定義FULLTEXT。這樣有助于更快地導(dǎo)入數(shù)據(jù)(而且使索引數(shù)據(jù)的總時(shí)間小于在導(dǎo)入每行時(shí)分別進(jìn)行索引所需要的總時(shí)間)。

--進(jìn)行全文本搜索

在索引之后,使用兩個(gè)函數(shù)match()和against()執(zhí)行全文本搜索,其中match()指定被搜索的列,against()指定要使用的搜索表達(dá)式。

關(guān)于match()和against()函數(shù)的解釋:

函數(shù) MATCH() 對(duì)照一個(gè)文本集(包含在一個(gè) FULLTEXT 索引中的一個(gè)或多個(gè)列的列集)執(zhí)行一個(gè)自然語言搜索一個(gè)字符串。搜索字符串做為 AGAINST() 的參數(shù)被給定。搜索以忽略字母大小寫的方式執(zhí)行。對(duì)于表中的每個(gè)記錄行,MATCH() 返回一個(gè)相關(guān)性值。即,在搜索字符串與記錄行在 MATCH() 列表中指定的列的文本之間的相似性尺度。當(dāng) MATCH() 被使用在一個(gè) WHERE 子句中時(shí) (參看上面的例子),返回的記錄行被自動(dòng)地以相關(guān)性從高到底的次序排序。相關(guān)性值是非負(fù)的浮點(diǎn)數(shù)字。零相關(guān)性意味著不相似。相關(guān)性的計(jì)算是基于:詞在記錄行中的數(shù)目、在行中唯一詞的數(shù)目、在集中詞的全部數(shù)目和包含一個(gè)特殊詞的文檔(記錄行)的數(shù)目。它也可以執(zhí)行一個(gè)邏輯模式的搜索。

ps:使用完整的match()說明:傳遞給match()的值必須與FULLTEXT()定義中的相同。如果指定多個(gè)列,則必須列出它們(而且次序正確);

搜索不區(qū)分大小寫:除非使用binary方式,否則全文本搜索不區(qū)分大小寫;

排序多個(gè)搜索項(xiàng):如果指定多個(gè)搜索項(xiàng),則包含多數(shù)匹配詞的那些行將具有比包含較少詞(或僅有一個(gè)匹配)的那些行高的等級(jí)值。

全文本搜索時(shí)對(duì)結(jié)果排序,具有較高等級(jí)的行先返回。全文本提供了簡單like搜索不能提供的功能。而且由于數(shù)據(jù)是索引,全文本搜索還相當(dāng)快。

--使用查詢擴(kuò)展

在使用查詢擴(kuò)展時(shí),MySQL對(duì)數(shù)據(jù)和索引進(jìn)行兩遍掃描來完成搜索:

1、首先,進(jìn)行一個(gè)基本的全文本搜索,找出與搜索條件匹配的所有行

2、其次,MySQL檢查這些匹配行并選擇所有有用的詞

3、再其次,MySQL再次進(jìn)行全文本搜索,這次不僅使用原來的條件,而且還使用所有有用的詞。

查詢擴(kuò)展增加了返回的行數(shù),,但這樣做也增加了實(shí)際上并不想要的數(shù)目。

ps:行越多越好:表中的行越多(這些行中的文本就越多),使用查詢擴(kuò)展返回的結(jié)果越好。

--布爾文本搜索

以布爾方式,可以提供關(guān)于如下內(nèi)容的細(xì)節(jié):

1、要匹配的詞

2、要排斥的詞(如果某行包含這個(gè)詞,則不反悔該行,即使它包含其他指定的詞也是如此)

3、排列提示(指定某些詞比其他詞更重要,更重要的詞等級(jí)更高)

4、表達(dá)式分組

5、另外一些內(nèi)容

ps:即使沒有FULLTEXT索引也可以使用:布爾方式不同于迄今為止使用的全文本搜索語法的地方在于,即使沒有定義FULLTEXT索引,也可以使用它。但這是一種非常緩慢的操作(其性能將隨著數(shù)據(jù)量的增加而降低)

IN BOOLEAN MODE的行為差異

全文本布爾操作符

布爾操作符

說明

+

包含,詞必須存在

-

排除,詞必須不出現(xiàn)

>

包含,而且增加等級(jí)值

<

包含,且減少等級(jí)值

()

把詞組成子表達(dá)式(允許這些子表達(dá)式作為一個(gè)組被包含、排除、排列等)

~

取下一個(gè)詞的排序值

*

詞尾的通配符

""

定義一個(gè)短語(與單個(gè)詞的列表不一樣,它匹配整個(gè)短語以便包含或排除這個(gè)短語)

ps:排列而不排序:在布爾方式中,不按等級(jí)值降序排序返回的行

-全文本搜索的使用說明

1、在索引全文本數(shù)據(jù)時(shí),短詞被忽略且從索引中排除。短語定義為那些具有3個(gè)或3個(gè)以下字符的詞(如果需要,這個(gè)數(shù)目可以更改)

2、MySQL帶有一個(gè)內(nèi)建的非用詞(stopword)列表,這些詞在索引全文本數(shù)據(jù)時(shí)總是被忽略。如果需要,可以覆蓋這個(gè)列表

3、許多詞出現(xiàn)的頻率很高,搜索它們沒有用處(返回太多的結(jié)果)。因此,MySQL規(guī)定了一條50%規(guī)則,如果一個(gè)詞出現(xiàn)在50%以上的行中,則將它作為一個(gè)非用詞忽略。50%規(guī)則不用于IN BOOLEAN MODE

4、如果表中的行數(shù)少于3行,則全文本搜索不返回結(jié)果(因?yàn)槊總€(gè)詞或者不出現(xiàn),或者至少出現(xiàn)在50%的行中)

5、忽略此中的單引號(hào)。例如,don't索引為dont

6、不具有詞分隔符(包括日語和漢語)的語言不能恰當(dāng)?shù)胤祷厝谋舅阉鹘Y(jié)果

7、僅在MyISAM數(shù)據(jù)庫引擎中支持全文本搜索

----插入數(shù)據(jù)

--數(shù)據(jù)插入

插入可以用幾種方式使用:

1、插入完整的行

2、插入行的一部分

3、插入多行

4、插入某些查詢的結(jié)果

插入及系統(tǒng)安全:可針對(duì)每個(gè)表或每個(gè)用戶,利用MySQL的安全機(jī)制機(jī)制禁止使用INSERT語句

--插入完整的行

insert intocustomersvalues (null,'LeeMichael','100 street','los angle',null,'USA');

-----------------------------------

insert intocustomers(

cust_name,

cust_addr,

cust_city,

cust_country)

values ('LeeMichael',

'100 street',

'los angle','USA');

ps:總是使用列的列表:一般不要使用沒有明確給出列的列表的INSERT語句。使用列的列表能使SQL代碼繼續(xù)發(fā)揮作用,即使表結(jié)構(gòu)發(fā)生了變化。

仔細(xì)地給出值:不管使用哪種INSERT語法,都必須給出values的正確數(shù)目。如果不提供列名,則必須給每個(gè)表列提供一個(gè)值。如果提供列名,則必須對(duì)梅格列出的列給出一個(gè)值。如果不這樣,將產(chǎn)生一條錯(cuò)誤信息,相應(yīng)的行插入不成功。

省略列:如果表的定義允許,則可以在INSERT操作中省略某些列。省略的列必須滿足以下某個(gè)條件:

1、該列定義為允許null值(無值或空值)

2、在表定義中給出默認(rèn)值。這表示如果不給出值,將使用默認(rèn)值

如果對(duì)表中不允許null值且沒有默認(rèn)值的列不給出值,則MySQL將產(chǎn)生一條錯(cuò)誤消息,并且相應(yīng)的行插入不成功。

提高整體性能:數(shù)據(jù)庫經(jīng)常被多個(gè)客戶訪問,對(duì)處理什么請(qǐng)求以及用什么次序處理進(jìn)行管理是MySQL的任務(wù)。INSERT操作可能很耗時(shí)(特別是有很多索引需要更新時(shí)),而且它可能降低等待處理的select語句的性能

如果數(shù)據(jù)檢索是最重要的(通常是這樣),則你可以通過在INSERT和INTO之間添加關(guān)鍵字LOW_PRIORITY,指示MySQL降低INSERT語句的優(yōu)先級(jí),如:INSERT LOW_PRIORITY INTO,這也適用于UPDATE和DELETE。

--插入多個(gè)行

insert intocustomers(

cust_name,

cust_addr,

cust_city,

cust_country)values('LeeMichael','100 street','los angle','USA');insert intocustomers(

cust_name,

cust_addr,

cust_city,

cust_country)values('LGQMichael','100 street','los angle','USA');

多個(gè)語句,用 ; 隔開

或者可以這樣(這樣寫可以提高性能):

insert intocustomers(

cust_name,

cust_addr,

cust_city,

cust_country)values('LeeMichael','100 street','los angle','USA'),

('LGQMichael','100 street','los angle','USA'),

ps:提高insert的性能:此技術(shù)可以提高數(shù)據(jù)庫處理的性能,因?yàn)镸ySQL用單條INSERT語句處理多個(gè)插入比使用多條INSERT語句快。

--插入檢索出的數(shù)據(jù)

新例子的說明:這個(gè)例子把一個(gè)名為custnew的表中的數(shù)據(jù)導(dǎo)入customers表中。為了試驗(yàn)這個(gè)例子,應(yīng)該首先創(chuàng)建和填充custnew表。custnew表的結(jié)構(gòu)于customers表相同。在填充custnew時(shí),不應(yīng)該使用已經(jīng)在customers中使用過的cust_id值(如果主鍵值重復(fù),后續(xù)的INSERT操作將會(huì)失敗)或僅省略這列值讓MySQL在導(dǎo)入數(shù)據(jù)的過程中產(chǎn)生新值。

insert intocustomers (cust_id,

cust_contact,

cust_email,

cust_name,

cust_addr,

cust_city)selectcust_id,

cust_contact,

cust_email,

cust_name,

cust_addr,

cust_cityfrom custnew

ps:INSERT SELECT中的別名:為簡單起見,這個(gè)例子在INSERT和SELECT語句中使用了相同的列名。但是,不一定要求列名匹配。事實(shí)上,MySQL甚至不關(guān)心SELECT返回的列名。它使用的是列的位置,因此SELECT中的第一列(不管其列名)將用來填充表列中指定的第一列,第二列將用來填充表列中指定的第二個(gè)列,如此等等。這對(duì)于從使用不同列名的表中導(dǎo)入數(shù)據(jù)時(shí)非常有用的。

INSERT SELECT中SELECT語句中可以包含where子句以過濾插入的數(shù)據(jù)。

----更新和刪除數(shù)據(jù)

--更新數(shù)據(jù)

為了更新(修改)表中的數(shù)據(jù),可使用UPDATE語句。可采用兩種方式使用UPDATE:

1、更新表中特定行

2、更新表總所有行

ps:不要省略WHERE子句:在使用UPDATE時(shí)一定要注意細(xì)心。因?yàn)樯圆蛔⒁?#xff0c;就會(huì)更新表中所有行。

UPDATE與安全:可以限制和控制UPDATE語句的使用。

基本的UPDATE語句由3個(gè)部分組成,分別是:

1、要更新的表

2、列名和它們的新值

3、確定要更新行的過濾條件

updatecustomersset cust_email = 'lgq@163.com'

where cust_id = 1005;

ps: 在UPDATE語句中使用子查詢:UPDATE語句中可以使用子查詢,使得能用SELECT語句檢索出的數(shù)據(jù)更新列數(shù)據(jù)

IGNORE關(guān)鍵字:如果能用UPDATE語句更新多行,并且在更新這些行中的一行

--刪除數(shù)據(jù)

為了從一個(gè)表中刪除(去掉)數(shù)據(jù),使用delete語句。分為兩種方式:

1、從表中刪除特定的行

2、從表中刪除所有行

ps:不要省略where子句:在使用delete時(shí)一定要注意細(xì)心。因?yàn)樯圆蛔⒁?#xff0c;就會(huì)錯(cuò)誤地刪除表中所有行。

delete與安全:可以限制和控制delete語句的使用

刪除表的內(nèi)容而不是表:delete語句從表中刪除行,甚至是刪除表中所有行。但是,delete不是刪除表本身。

更快的刪除:如果想從表中刪除所有行,不要使用delete。可以使用TRUNCATE TABLE語句,它完成相同的工作,但速度更快(TRUNCATE實(shí)際是刪除原來的 表并不重新創(chuàng)建一個(gè)表,而不是逐行刪除表中的數(shù)據(jù))

--更新和刪除的指導(dǎo)原則

許多SQL程序員使用UPDATE和DELETE時(shí)所遵循的習(xí)慣:

1、除非確實(shí)打算更新和刪除每一行,否則絕對(duì)不要使用不帶where子句的UPDATE和DELETE

2、保證每個(gè)表都有主鍵,盡可能想where子句那樣使用它(可以指定各主鍵、多個(gè)值或值的范圍)

3、在對(duì)UPDATE或DELETE語句使用where子句前,應(yīng)該先用SELECT進(jìn)行測(cè)試,保證它過濾的是正確的記錄,以防編寫的where子句不正確

4、使用強(qiáng)制實(shí)施引用完整性的數(shù)據(jù)庫,這樣MySQL將不允許刪除與其他相關(guān)聯(lián)的數(shù)據(jù)的行

ps:小心使用:MySQL沒有撤銷(undo)按鈕。應(yīng)該非常小心地使用UPDATE和DELETE,否則你會(huì)發(fā)現(xiàn)自己更新或刪除了錯(cuò)誤的數(shù)據(jù)。

----創(chuàng)建和操縱表

--創(chuàng)建表

方法:

1、使用具有交互式創(chuàng)建和管理表的工具

2、表也可以直接用MySQL語句操縱

--表創(chuàng)建基礎(chǔ)

1、新表的名字,在關(guān)鍵字create table之后給出

2、表列的名字和定義,用逗號(hào)分隔開

create tablecustomers

(

cust_idint not nullauto_increment,

cust_namechar(50) not null,primary key(cust_id)

)ENGINE=InnoDB;

語句格式化:MySQL語句中忽略空格。語句可以在一個(gè)長行上輸出,也可以分成許多行。它們的作用都相同。這允許你以最適合自己的方式安排語句的格式。強(qiáng)烈建議采用某種縮進(jìn)格式。

處理現(xiàn)有的表:在創(chuàng)建新表時(shí),指定的表名必須不存在,否則將出錯(cuò)。如果要防止意外覆蓋已有的表,SQL要求首先手工刪除該表,然后再重建它,而不是簡單地用創(chuàng)建表語句覆蓋它。如果你僅想在一個(gè)表不存在時(shí)創(chuàng)建它,應(yīng)該在表名后給出IF NOT EXISTS。這樣做不檢查已有表的模式是否與你打算創(chuàng)建的表模式相匹配。它只是查看表名是否存在,并且僅在表名不存在時(shí)創(chuàng)建它。

--使用NULL值

NULL值就是沒有值或缺值。允許NULL值的列也允許在插入行時(shí)不給出該列的值。不允許NULL值的列不接受該列沒有值的行,換句話說,在插入或更新行時(shí),該列必須有值。每個(gè)表列或者是NULL列,或者是NOT NULL列,這種狀態(tài)在創(chuàng)建時(shí)由表的定義規(guī)定。

理解NULL:不要把NULL值與空串相混淆。NULL值是沒有值,它不是空串。如果指定? ''? (兩個(gè)單引號(hào),其間沒有字符),這在NOT NULL列中是允許的。空串是一個(gè)有效的值,它不是無值。NULL值用關(guān)鍵字而不是空串指定。

--主鍵再介紹

主鍵值必須唯一。即,表中的每個(gè)行必須具有唯一的主鍵值。如果主鍵使用單個(gè)列,則它的值必須唯一。如果使用多個(gè)列,則這些列的組合值必須唯一。創(chuàng)建多個(gè)列組成的主鍵primary key(a, b)

主鍵可以在創(chuàng)建表時(shí)定義,或者在創(chuàng)建表之后定義

ps:主鍵和NULL值:主鍵為其值唯一標(biāo)識(shí)表中每個(gè)行的列。主鍵中只能使用不允許NULL值的列。允許NULL值的列不能作為唯一標(biāo)識(shí)。

--使用AUTO_INCREMENT

ATUO_INCREMENT告訴MySQL,本列每當(dāng)增加一行時(shí)自動(dòng)增量。每次執(zhí)行一個(gè)INSERT操縱時(shí),告訴MySQL自動(dòng)對(duì)該列增量(從而才有這個(gè)關(guān)鍵字),給該列賦予下一個(gè)可用的值。這樣給每個(gè)行分配一個(gè)唯一的id,從而可以用作主鍵。

每個(gè)表只允許一個(gè)AUTO_INCREMENT列,而且它必須被索引(如,通過使它成為主鍵)

ps:覆蓋AUTO_INCREMENT:如果一個(gè)列被指定為AUTO_INCREMENT,則它需要使用特殊的值嗎?你可以簡單地在INSERT語句中指定一個(gè)值,只要它是唯一的即可,該值將被用來替代自動(dòng)生成的值。后續(xù)的增量將開始使用該手工插入的值

確定AUTO_INCREMENT值:讓MySQL生成(通過自動(dòng)增量)主鍵的一個(gè)缺點(diǎn)是你不知道這些值都是誰。

--指定默認(rèn)值

create tableorderitems

(

order_numint not null,

order_itemint not null,

prod_idchar(10) not null,

quantityint not null default 1,

item_pricedecimal(8,2) not null,

primary_key(order_num, order_item)

)ENGINE=InnoDB;

上述代碼中就設(shè)置了quantity的默認(rèn)值位1.

ps:不允許函數(shù):與大多數(shù)DBMS不一樣,MySQL不允許使用函數(shù)作為默認(rèn)值,它只支持常量

使用默認(rèn)值而不是NULL值:許多數(shù)據(jù)庫開發(fā)人員使用默認(rèn)值而不是NULL值,特別是對(duì)用于計(jì)算或數(shù)據(jù)分組的列更是如此。

--引擎類型

與其他DBMS一樣,MySQL有一個(gè)具體管理和處理數(shù)據(jù)的內(nèi)部引擎。在你使用CREATE TABLE語句時(shí),該引擎具體創(chuàng)建表,而在你使用SELECT語句或進(jìn)行其他數(shù)據(jù)庫處理時(shí),該引擎在內(nèi)部處理你的請(qǐng)求。多數(shù)時(shí)候,此引擎都隱藏在DBMS內(nèi),不需要過多關(guān)注它

但MySQL與其他DBMS不一樣,它具有多種引擎。它打包多個(gè)引擎,這些引擎都隱藏在MySQL服務(wù)器內(nèi),全都能執(zhí)行CREATE TABLE和SELECT等命令。這些引擎具有各自不同的功能和特性,為不同的任務(wù)選擇正確的引擎能獲得良好的功能和靈活性。如果省略ENGINE=語句,則使用默認(rèn)引擎MyISAM,多數(shù)SQL語句都會(huì)默認(rèn)使用它。但并不是所有語句都默認(rèn)使用它,這就是為什么ENGINE=語句很重要的原因。

引擎介紹:

1、InnoDB是一個(gè)可靠的事務(wù)處理引擎,它不支持全文本搜索

2、MEMORY在功能等同于MyISAM,但由于數(shù)據(jù)存儲(chǔ)在內(nèi)存(不是磁盤)中,速度很快(特別適用于臨時(shí)表)

3、NyISAM是一個(gè)性能極高的引擎,它支持全文本搜索,但不支持事務(wù)處理。

引擎類型可以混用。

外鍵不能跨引擎:混用引擎類型有一個(gè)大缺陷。外鍵(用于強(qiáng)制實(shí)施引用完整性)不能跨引擎,即使用一個(gè)引擎的表不能引用具有使用不同引擎的表的外鍵。

--更新表

為更新表定義,可使用ALTER TABLE語句。但是,在理想狀態(tài)下,當(dāng)表中存儲(chǔ)數(shù)據(jù)之后,該表就不應(yīng)該再被更新。在表的設(shè)計(jì)過程中需要花費(fèi)大量時(shí)間來考慮,以便后期不對(duì)該表進(jìn)行大的改動(dòng)。

為了使用ALTER TABLE更改表結(jié)構(gòu),必須給出下面的信息:

1、在ALTER TABLE之后給出要更改的表名(該表必須存在,否則將出錯(cuò))

2、所作更改的列表

ALTER TABLEvendorsADD vend_phone char(20);--------------------------------------

ALTER TABLEvendorsDROP COLUMN vend_phone;

復(fù)雜表結(jié)構(gòu)更改一般需要手動(dòng)刪除過程,它設(shè)計(jì)以下步驟:

1、用新的列布局創(chuàng)建一個(gè)新表

2、使用INSERT SELECT語句從舊表復(fù)制數(shù)據(jù)到新表,如有必要可使用轉(zhuǎn)換函數(shù)和計(jì)算字段

3、檢驗(yàn)包含所需數(shù)據(jù)的新表

4、重命名舊表(如果確定,可以刪除它)

5、用舊表原來的名字重命名新表

6、根據(jù)需要,重新創(chuàng)建觸發(fā)器、存儲(chǔ)過程、索引和外鍵

ps:小心使用ALTER TABLE:使用ALTER TABLE要極為小心,應(yīng)該在進(jìn)行改動(dòng)前做一個(gè)完整的備份(模式和數(shù)據(jù)的備份)。數(shù)據(jù)庫表的更改不能撤銷,如果增加了不需要的列,可能不能刪除它們。類似的,如果刪除了不應(yīng)該刪除的列,可能會(huì)丟失該列中的所有數(shù)據(jù)。

--刪除表

DROP TABLE customers;

--重命名表

使用RENAME TABLE語句可以重命名一個(gè)表

RENAME TABLE backup_customers TOcustomers,

backup_vendorsTO vendors;

----使用視圖

視圖的一些常見應(yīng)用:

1、重用SQL語句

2、簡單復(fù)雜的SQL操作。在編寫查詢后,可以方便地重用它而不必知道它的基本查詢細(xì)節(jié)

3、使用表的組成部分而不是整個(gè)表

4、保護(hù)數(shù)據(jù)。可以給用戶授予表的特定部分的訪問權(quán)限而不是整個(gè)表的訪問權(quán)限

5、更改數(shù)據(jù)格式和表示。視圖可返回與底層表的表示和格式不同的數(shù)據(jù)。

重點(diǎn):視圖僅僅是用來查看存儲(chǔ)在別處的數(shù)據(jù)的一種設(shè)施。視圖本身不包含數(shù)據(jù),因此它們返回的數(shù)據(jù)是從其他表中檢索出來的。在添加或更改這些表中的數(shù)據(jù)時(shí),視圖將返回改變過的數(shù)據(jù)。

ps:性能問題:因?yàn)橐晥D不包含數(shù)據(jù),所以每次使用視圖時(shí),都必須處理查詢執(zhí)行時(shí)所需的任一個(gè)檢索。如果你用多個(gè)聯(lián)結(jié)和過濾創(chuàng)建一個(gè)復(fù)雜的視圖或者嵌套了視圖,可能會(huì)發(fā)現(xiàn)性能下降的很厲害。因此,在部署使用了大量視圖的應(yīng)用前,應(yīng)該進(jìn)行測(cè)試。

--視圖的規(guī)則和限制

1、與表一樣,視圖必須唯一命名(不能給視圖取與別的視圖或表相同的名字)

2、對(duì)于可以創(chuàng)建的視圖數(shù)目沒有限制

3、為了創(chuàng)建視圖,必須具有足夠的訪問權(quán)限。這些限制通常由數(shù)據(jù)庫管理人員授予

4、視圖可以嵌套,即可以利用從其他視圖中檢索數(shù)據(jù)的查詢來構(gòu)造一個(gè)視圖

5、ORDER BY可以用在視圖中,但如果從該視圖檢索數(shù)據(jù)的SELECT語句中也含有ORDER BY,那么該視圖中的ORDER BY將被覆蓋

6、視圖中不能索引,也不能有關(guān)聯(lián)的觸發(fā)器或默認(rèn)值

7、視圖可以和表一起使用。例如,編寫一條聯(lián)結(jié)表和視圖的SELECT語句。

--使用視圖

視圖的創(chuàng)建:

1、視圖用CREATE VIEW語句來創(chuàng)建

2、使用SHOW CREATE VIEW viewname;來查看創(chuàng)建視圖的語句

3、用DROP刪除視圖,可以先用DROP再用CREATE,也可以直接用CREATE OR REPLACE VIEW。如果要更新的視圖不存在,則第2條更新語句會(huì)創(chuàng)建一個(gè)視圖;如果要更新的視圖存在,則第2條更新語句會(huì)替換原有視圖。

--利用視圖簡化復(fù)雜的聯(lián)結(jié)

視圖最常見的應(yīng)用之一就是隱藏復(fù)雜的SQL,這通常會(huì)涉及到聯(lián)結(jié)。

CREATE VIEW productcustomers AS

SELECTcust_name, cust_contact, prod_idFROMcustomers, orders, orderitemsWHERE customer.cust_id =orders.cust_idAND orderitems.order_num = orders.order_num;

ps:創(chuàng)建可重用的視圖:創(chuàng)建不受特定數(shù)據(jù)限制的視圖是一種好辦法。

--用視圖重新格式化檢索出的數(shù)據(jù)

SELECT Concat(RTrim(vend_name), '(', RTrim(vend_country), ')')ASvend_titleFROMvendorsORDER BY vend_name;

-------------------------------------------------------------------

CREATE VIEW vendorlocations AS

SELECT Concat(RTrim(vend_name), '(', RTrim(vend_country), ')')

AS vend_title

FROM vendors

ORDER BY vend_name;

--用視圖過濾不想要的數(shù)據(jù)

視圖對(duì)于應(yīng)用普通的WHERE子句也很有用,過濾掉一些不用的字段。

ps:WHERE子句與WHERE子句:如果從視圖檢索數(shù)據(jù)時(shí)使用了一條WHERE子句,則兩組子句(一組在視圖中,另一組是傳遞給視圖的)將自動(dòng)組合。

--使用視圖與計(jì)算字段

SELECTprod_id, quantity, item_price,

quantity* item_price ASexpanded_priceFROMorderitemsWHERE order_num = 20005;

--更新視圖

迄今為止的所有視圖都是和SELECT語句使用的。然而,視圖的數(shù)據(jù)能否更新?答案視情況而定。

通常視圖是可更新的(即,可以對(duì)它們使用INSERT、UPDATE和DELET)。更新一個(gè)視圖將更新其基表(可以回憶一下,視圖本身沒有數(shù)據(jù))。如果你對(duì)視圖增加或刪除行,實(shí)際上是對(duì)其基表增加或刪除行。

但是,并非所有的視圖都是可更新的。基本可以說,如果MySQL不能正確地確定被更新的基數(shù)據(jù),則不允許更新(包括插入和刪除)。這實(shí)際上意味著,如果視圖定義中有以下操作,則不能進(jìn)行視圖的更新:

1、分組(使用GROUP BY和HAVING)

2、聯(lián)結(jié)

3、子查詢

4、并

5、聚集函數(shù)(Min()、Count()、Sum()等)

6、DISTINCT

7、導(dǎo)出(計(jì)算)列

要記住視圖主要是用于數(shù)據(jù)檢索。

ps:可能的變動(dòng):未來的MySQL很可能會(huì)取消某些限制

將視圖用于檢索:一般,應(yīng)該將視圖用于檢索(SELECT語句)而不用于更新(INSERtT、UPDATE和DELETE)

----使用存儲(chǔ)過程

--存儲(chǔ)過程

迄今位置,使用的大多數(shù)SQL語句都是針對(duì)一個(gè)或多個(gè)表的單條語句。并非所有操作都這么簡單,經(jīng)常會(huì)有一個(gè)完整的操作需要多條語句才能完成。

單獨(dú)編寫每條語句,并根據(jù)結(jié)果有條件地執(zhí)行另外的語句。在每次需要這個(gè)處理時(shí)(以及每個(gè)需要它的應(yīng)用中)都必須做這些工作。

可以創(chuàng)建存儲(chǔ)過程。存儲(chǔ)過程簡單來說,就是為以后的使用而保存的一條或多條MySQL語句的集合。可將其視為批文件,雖然它的作用不僅限于批處理。

--為什么要使用存儲(chǔ)過程

原因如下:

1、通過把處理封裝在容易使用的單元中,簡單復(fù)雜的操作

2、由于不要求反復(fù)建立一系列處理步驟,這保證了數(shù)據(jù)的完整性。如果所有開發(fā)人員和應(yīng)用程序都使用同一(試驗(yàn)和測(cè)試)存儲(chǔ)過程,則所使用的代碼都是相同的。這一點(diǎn)的延伸就是防止錯(cuò)誤。需要執(zhí)行的步驟越多,出錯(cuò)的可能性就越大。防止錯(cuò)誤保證了數(shù)據(jù)的一致性。

3、簡化對(duì)變動(dòng)的管理。如果表名、列名或業(yè)務(wù)邏輯(或別的內(nèi)容)有變化。只需要更改存儲(chǔ)過程的代碼。使用它的人員甚至不需要知道這些變化。

這一點(diǎn)的延伸就是為了安全性。通過存儲(chǔ)過程限制對(duì)基礎(chǔ)數(shù)據(jù)的訪問減少了數(shù)據(jù)訛誤(無意識(shí)的或別的原因所導(dǎo)致的數(shù)據(jù)訛誤)的機(jī)會(huì)。

1、提高性能。因?yàn)檫m應(yīng)存儲(chǔ)過程比使用單獨(dú)的SQL語句要快

2、存在一些只能用在單個(gè)請(qǐng)求中的MySQL元素和特性,存儲(chǔ)過程可以使用它們來編寫功能更強(qiáng)更靈活的代碼。

總的來說,使用存儲(chǔ)過程的3個(gè)主要好處就是,簡單、安全和高性能。

一般來說,編寫存儲(chǔ)過程需要安全訪問權(quán)限。

ps:MySQL將編寫存儲(chǔ)過程的安全和訪問與執(zhí)行存儲(chǔ)過程的安全和訪問區(qū)分開。即使你不能(或不想)編寫自己的存儲(chǔ)過程,也仍然可以在適當(dāng)?shù)臅r(shí)候執(zhí)行別的存儲(chǔ)過程。

--使用存儲(chǔ)過程

MySQL稱存儲(chǔ)過程的執(zhí)行為調(diào)用,因此MySQL執(zhí)行存儲(chǔ)過程的語句為CALL。CALL接受存儲(chǔ)過程的名字以及需要傳遞給它的任意參數(shù)。

----------執(zhí)行叫做productpricing的存儲(chǔ)過程

CALL productpricing

(@pricelow,@pricehigh,@priceaverage);

--創(chuàng)建存儲(chǔ)過程

CREATE PROCEDUREproductpricing()BEGIN

SELECT Avg(prod_price) ASpriceaverageFROMproducts;END

BEGIN和END是用來限定存儲(chǔ)過程體,過程僅是簡單的SELECT語句。

在MySQL處理這段代碼時(shí),它創(chuàng)建一個(gè)新的存儲(chǔ)過程product-pricing。沒有返回?cái)?shù)據(jù),因?yàn)檫@段代碼并未調(diào)用存儲(chǔ)過程,這里知識(shí)為了以后使用而創(chuàng)建。

ps:MySQL命令行客戶機(jī)的分隔符:如果你使用的是MySQL命令行使用程序,應(yīng)該仔細(xì)閱讀此說明。

默認(rèn)的MySQL語句分隔符為;(正如你已經(jīng)在迄今為止所使用的MySQL語句中所看到的那樣)。MySQL命令行實(shí)用程序也使用;作為語句分隔符。如果命令行實(shí)用程序要解釋存儲(chǔ)過程自身內(nèi)的;字符,則它們最終不會(huì)成為存儲(chǔ)過程的成分,這會(huì)使存儲(chǔ)過程中的SQL出現(xiàn)語法錯(cuò)誤。

解決辦法是臨時(shí)更改命令行使用程序的語句分隔符,如下所示:

DELIMITER //

CREATE PROCEDUREproductpricing()BEGIN

SELECT Avg(prod_price) ASpriceaverageFROMproducts;END //

DELIMITER;

其中,DELIMITER //告訴命令行實(shí)用程序使用 // 作為新的語句結(jié)束分隔符,可以看到標(biāo)志存儲(chǔ)過程結(jié)束的END定義為END //而不是END;。這樣,存儲(chǔ)過程體內(nèi)的;仍然保持不動(dòng),并且正確地傳遞給數(shù)據(jù)庫引擎。最后,為恢復(fù)為原來的語句分隔符,可使用DELIMITER? ;。

除 \ 符號(hào)外,任何字符都可以用作語句分隔符。

使用存儲(chǔ)過程關(guān)鍵字是CALL

CALL productpricing();

--刪除存儲(chǔ)過程

存儲(chǔ)過程創(chuàng)建之后,被保存在服務(wù)器上以供使用,直至被刪除。刪除命令從服務(wù)器中刪除存儲(chǔ)過程。

DROP PROCEDURE productpricing;

ps:僅當(dāng)存在時(shí)刪除:如果指定的國策灰姑娘不存在,則DROP PROCEDURE將產(chǎn)生一個(gè)錯(cuò)誤。當(dāng)過程存在想刪除它時(shí)(如果過程不存在也產(chǎn)生)可使用DROP PROCEDURE IF EXISTS。

--使用參數(shù)

存儲(chǔ)一般不顯示結(jié)果,而是把結(jié)果返回給你指定的變量。

變量(variable):內(nèi)存中一個(gè)特定的位置,用來臨時(shí)存儲(chǔ)過程。

以下時(shí)productpricing的修改版本(如果不先刪除此存儲(chǔ)過程,則不能再次創(chuàng)建它):

CREATE PROCEDUREproductpricing(

OUT plDECIMAL(8,2),

OUT phDECIMAL(8,2),

OUT paDECIMAL(8,2)

)BEGIN

SELECT Min(prod_price)INTOplFROMproducts;SELECT Max(prod_price)INTOphFROMproducts;SELECT Avg(prod_price)INTOpaFROMproducts;END;

ps:參數(shù)的數(shù)據(jù)類型:存儲(chǔ)過程的參數(shù)允許的數(shù)據(jù)類型與表中使用的數(shù)據(jù)類型相同。

注意,記錄集不是允許的類型,因此,不能通過一個(gè)參數(shù)返回多個(gè)行和列。這就是前面的例子為什么要使用3個(gè)參數(shù)的原因。

為調(diào)用此修改過的存儲(chǔ)過程,必須指定3個(gè)變量名:

CALL productpricing(@pricelow,@pricehigh,@priceaverage);----------------------------------------

SELECT @priceaverage;----------------------------------------

SELECT @pricelow, @pricehigh, @priceaverage;

變量名:所有MySQL變量都必須以@開始

----------------使用IN和OUT參數(shù)

CREATE PROCEDRUE ordertotal(

IN onumber INT,

OUT ototal DECIMAL(8,2)

)

BEGIN

SELECT Sum(item_price*quantity)

FROM orderitems

WHERE order_num=onumber

INTO ototal;

END;

onumber定義為IN,因?yàn)橛唵翁?hào)被傳入存儲(chǔ)過程。ototal定義為OUT,因?yàn)橐獜拇鎯?chǔ)過程中返回合計(jì)。SELECT語句使用這兩個(gè)參數(shù),WHERE子句使用onumber選擇正確的行,INTO使用ototal存儲(chǔ)計(jì)算出來的合計(jì)。

為調(diào)用這個(gè)新存儲(chǔ)過程,可以使用以下語句:

CALL ordertotal(20005, @total);

--建立智能存儲(chǔ)過程

只有在存儲(chǔ)過程內(nèi)包含業(yè)務(wù)規(guī)則和智能處理時(shí),它們的威力才能真正顯現(xiàn)出來。

以下的demo演示下面幾個(gè)事情:

1、獲得合計(jì);

2、把營業(yè)稅有條件地添加到合計(jì);

3、返回合計(jì)(帶或不帶稅)

create procedureordertotal(in onumber int,intaxable boolean,

out ototaldecimal(8,2)

)comment'obtain order total , optionally adding tax'

begin

declare total decimal(8,2);declare taxrate int default 6;select sum(item_price *quantity)fromorderitemswhere order_num =onumberintototalif taxable then

select total+(total/100*taxrate) intototal;end if;select total intoototal;end;

DECLARE語句定義局部變量,要求指定變量名和數(shù)據(jù)類型,也支持可選的默認(rèn)值。

ps:COMMENT關(guān)鍵字:不是必需的,但如果給出,將在SHOW PROCEDURE STATUS的結(jié)果中顯示。

--檢查存儲(chǔ)過程

為顯示用來創(chuàng)建一個(gè)存儲(chǔ)過程的create語句,使用show create procedure語句;

show create procedure ordertotal;

ps:限制過程狀態(tài)結(jié)果:SHOW PROCEDURE STATUS列出所有存儲(chǔ)過程。為限制其輸出,可使用LIKE指定一個(gè)過濾模式,

例如:show procedure status like 'ordertotal'

----使用游標(biāo)

--游標(biāo)

MySQL5增加了對(duì)游標(biāo)的使用。

MySQL檢索操作返回一組稱為結(jié)果集的行。這組返回的行都是與SQL語句相匹配的行(零行或者多行)。使用簡單的SELECT語句,例如,沒有辦法得到第一行、下一行或前10行,也不存在每次一行地處理所有行的簡單方法(相對(duì)于成批地處理它們)。

有時(shí),需要在檢索出來的行中前進(jìn)或后退一行或多行。這就是使用游標(biāo)的原因。游標(biāo)(cursor)是一個(gè)存儲(chǔ)在MySQL服務(wù)器上的數(shù)據(jù)庫查詢,它不是一條select語句,而是被該語句檢索出來的結(jié)果集。在存儲(chǔ)了游標(biāo)之后,應(yīng)用程序可以根據(jù)需要滾動(dòng)或?yàn)g覽器中的數(shù)據(jù)。

游標(biāo)主要用于交互式應(yīng)用,其中用戶需要滾動(dòng)屏幕上的數(shù)據(jù),并對(duì)數(shù)據(jù)進(jìn)行瀏覽或做出更改。

ps:只能用于存儲(chǔ)過程:不像多數(shù)DBMS,MySQL游標(biāo)只能用于存儲(chǔ)過程(和函數(shù))。

--使用游標(biāo)

使用游標(biāo)涉及幾個(gè)明確的步驟:

1、在能夠使用游標(biāo)前,必須聲明(定義)它。這個(gè)過程實(shí)際上沒有檢索數(shù)據(jù),它只是定義要使用的select語句。

2、一旦聲明后,必須打開游標(biāo)以供使用。這個(gè)過程用前面定義的select語句把數(shù)據(jù)實(shí)際檢索出來。

3、對(duì)于填有數(shù)據(jù)的游標(biāo),根據(jù)需要取出(檢索)各行。

4、在結(jié)束游標(biāo)使用時(shí),必須關(guān)閉游標(biāo)。

--創(chuàng)建游標(biāo)

游標(biāo)用DECLARE語句創(chuàng)建。DECLARE命名游標(biāo),并定義相應(yīng)的SELECT語句,根據(jù)需要帶WHERE和其他子句。例如,下面的語句定義了名為ordernumbers的游標(biāo),使用了可以檢索所有訂單的SELECT語句。

CREATE PROCEDUREprocessorders()BEGIN

DECLARE ordernumbers CURSOR

FOR

SELECT order_num FROMorders;END;

--打開和關(guān)閉游標(biāo)

游標(biāo)用OPEN CURSOR語句來打開。。

OPEN ordernumbers;

關(guān)閉用CLOSE CURSOR,close釋放游標(biāo)使用的所有內(nèi)部內(nèi)存和資源,因此在每個(gè)游標(biāo)不再需要時(shí)都用改關(guān)閉。

CLOSE ordernumbers;

ps:隱含關(guān)閉:如果你不明確關(guān)閉游標(biāo),MySQL將會(huì)在到達(dá)END語句時(shí)自動(dòng)關(guān)閉它。

--使用游標(biāo)數(shù)據(jù)

在一個(gè)游標(biāo)被打開后,可以使用FETCH語句分別訪問它的每一行。FETCH指定檢索什么數(shù)據(jù)(所需的列),檢索出來的數(shù)據(jù)存儲(chǔ)在什么地方。它還向前移動(dòng)游標(biāo)中的內(nèi)部行指針,使下一條(不重復(fù)讀取同一行)。

ps:DECLARE語句的次序:DECLARE語句的發(fā)布存在特定的次序。用DECLARE語句定義的局部變量必須在定義任意游標(biāo)或句柄之前定義,而句柄必須在游標(biāo)之后定義。不遵守此順序?qū)a(chǎn)生錯(cuò)誤信息。

重復(fù)或循環(huán)?“除這里使用的REPEAT語句外,MySQL還支持循環(huán)語句,它可用來重復(fù)執(zhí)行代碼,直到使用LEAVE語句手動(dòng)退出位置。通常REPEAT語句的語法使它更適合于對(duì)游標(biāo)進(jìn)行循環(huán)。

-----使用觸發(fā)器

--觸發(fā)器

需要MySQL5:對(duì)觸發(fā)器的支持是在MySQL5中增加的。因此,本章內(nèi)容適用于MySQL5或之后。

MySQL語句在需要時(shí)被執(zhí)行,存儲(chǔ)過程也是如此。但是,如果你想要某條語句(或某些語句)在事件發(fā)生時(shí)自動(dòng)執(zhí)行,就需要使用觸發(fā)器。

觸發(fā)器時(shí)MySQL響應(yīng)以下任意語句而自動(dòng)執(zhí)行的一條SQL語句(或位于BEGIN或END語句之間的一組語句):

DECLARE

INSERT

UPDATE

其他MySQL語句不支持觸發(fā)器。

--創(chuàng)建觸發(fā)器

在創(chuàng)建觸發(fā)器時(shí),需要給出4條信息:

1、唯一的觸發(fā)器名

2、觸發(fā)器關(guān)聯(lián)的表

3、觸發(fā)器應(yīng)該響應(yīng)的活動(dòng)(DECLARE、INSERT或UODATE)

4、觸發(fā)器何時(shí)執(zhí)行(處理之前或之后)

ps:保持每個(gè)數(shù)據(jù)庫的觸發(fā)器名唯一:在MySQL5中,觸發(fā)器名必須在每個(gè)表中的唯一,但不是在每個(gè)數(shù)據(jù)庫中唯一。這表示同一個(gè)數(shù)據(jù)庫中的兩個(gè)表可具有相同的名字的觸發(fā)器。這在其他每個(gè)數(shù)據(jù)庫觸發(fā)器名必須唯一的DBMS中是不允許的,而且以后的MySQL版本很可能會(huì)使命名規(guī)則更為嚴(yán)格。因此,現(xiàn)在最好是在數(shù)據(jù)庫范圍捏使用唯一的觸發(fā)器名。

CREATE TRIGGER newproduct AFTER INSERT ONproductsFOR EACH ROW SELECT 'Product added'

ps:僅支持表:只有表才支持觸發(fā)器,試圖不支持(臨時(shí)表也不支持)

觸發(fā)器按每個(gè)表每個(gè)事件每次地定義,每個(gè)表每個(gè)事件每次只允許一個(gè)觸發(fā)器。因此,每個(gè)表最多支持6個(gè)觸發(fā)器(每條INSERT、UPDATE和DELETE的之前和之后)。單一觸發(fā)器不能與多個(gè)事件或多個(gè)表關(guān)聯(lián),所以,如果你需要一個(gè)對(duì)INSERT和UPDATE操作執(zhí)行的觸發(fā)器,則應(yīng)該定義兩個(gè)觸發(fā)器。

ps:觸發(fā)器失敗:如果BEFORE觸發(fā)器失敗,則MySQL將不執(zhí)行請(qǐng)求的操作。此外,如果BEFORE觸發(fā)器或語句本身失敗,MySQL將不執(zhí)行AFTER觸發(fā)器(如果有的話)

--刪除觸發(fā)器

使用DROP TRIGGER語句

DROP TRIGGER newproduct;

--使用觸發(fā)器

-INSERT觸發(fā)器

INSERT觸發(fā)器在INSERT語句執(zhí)行之前或之后執(zhí)行。需要知道以下幾點(diǎn):

1、在INSERT觸發(fā)器代碼內(nèi),可引用一個(gè)名為NEW的虛擬表,訪問被插入的行

2、在BEFORE INSERT觸發(fā)器內(nèi),NEW中的值也可以被更新(允許更改被插入的值)

3、對(duì)于AUTO_INCREMENT列,NEW在INSERT執(zhí)行之前包含0,在INSERT執(zhí)行之后包含新的自動(dòng)生成值

以下代碼,創(chuàng)建一個(gè)名為neworder的觸發(fā)器,它按照AFTER INSERT ON orders執(zhí)行。在插入一個(gè)新訂單到orders表時(shí),MySQL生成一個(gè)新訂單號(hào)并保存到order_num中。觸發(fā)器從NEW.order_num取得這個(gè)值并返回它:

CREATE TRIGGER neworder AFTER INSERT ONordersFOR EACH ROW SELECT NEW.order_num;

ps:BEFORE或AFTER?:通常,將BEFORE用于數(shù)據(jù)驗(yàn)證和凈化(目的是保證插入表中的數(shù)據(jù)確實(shí)是需要的數(shù)據(jù))。本提示也適用于UPDATE觸發(fā)器。

--DELETE觸發(fā)器

DELETE觸發(fā)器在DELETE語句執(zhí)行之前或之后執(zhí)行。需要知道以下幾點(diǎn):

1、在DELETE觸發(fā)器代碼內(nèi),你可以引用一個(gè)名為OLD的虛擬表,訪問被刪除的行

2、OLD中的值全都是只讀的,不能更新

以下代碼,使用OLD保存將要被刪除的行到一個(gè)存檔表中:

CREATE TRIGGER deleteorder BEFORE DELETE ONordersFOREACH ROWBEGIN

INSERT INTOarchive_orders(order_num, order_date, cust_id)VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);END;

ps:多語句觸發(fā)器:正如所見,觸發(fā)器deleteorder使用BEGIN和END語句標(biāo)記觸發(fā)器體。這在此例子中并不是必需的,不過也沒有害處。使用BEGIN END塊的好處是觸發(fā)器能容納多條SQL語句(在BEGIN END塊中一條挨著一條)。

--UPDATE觸發(fā)器

UPDATE觸發(fā)器在UPDATE語句執(zhí)行之前或之后執(zhí)行。需要知道以下幾點(diǎn):

1、在UPDATE觸發(fā)器代碼中,你可以引用一個(gè)名為OLD的虛擬表訪問以前的值,引用一個(gè)名為NEW的虛擬表訪問更新的值

2、在BEFORE UPDATE觸發(fā)器中,NEW中的值可能也被更新(允許更改將要用于UPDATE語句的值)

3、OLD中的值全都是只讀的,不能更新

下面的例子是保證周明縮寫總是大寫(不管UPDATE語句中給出的是大寫還是小寫):

CREATE TRIGGER updatevendor BEFORE UPDATE ONvendorsFOR EACH ROW SET NEW.vend_state = Upper(NEW.vend_stats);

--關(guān)于觸發(fā)器的進(jìn)一步介紹

重點(diǎn):

1、與其他DBMS相比,MySQL5中支持的觸發(fā)器相當(dāng)初級(jí)。未來的MySQL版本中有一些改進(jìn)和增強(qiáng)觸發(fā)器支持的計(jì)劃

2、創(chuàng)建觸發(fā)器可能需要特殊的安全訪問權(quán)限,但是,觸發(fā)器的執(zhí)行是自動(dòng)的。如果INSERT、UPDATE或DELETE語句能夠執(zhí)行,則相關(guān)的觸發(fā)器也能執(zhí)行

3、應(yīng)該用觸發(fā)器來保證數(shù)據(jù)的一致性(大小寫、格式等)。在觸發(fā)器中執(zhí)行這種類型的處理的有點(diǎn)是它總是進(jìn)行這種處理,而且是透明地進(jìn)行,與客戶機(jī)應(yīng)用無關(guān)

4、觸發(fā)器的一種非常有意義的使用是創(chuàng)建審計(jì)跟蹤。使用觸發(fā)器,把更改(如果需要,甚至還有之前和之后的狀態(tài))記錄到另一個(gè)表非常容易

5、遺憾的是,MySQL觸發(fā)器中不支持CALL語句。這表示不能從觸發(fā)器內(nèi)調(diào)用存儲(chǔ)過程。所需的存儲(chǔ)過程代碼需要復(fù)制到觸發(fā)器內(nèi)。

----管理事務(wù)的處理

--事務(wù)處理

ps:并非所有引擎都支持事務(wù)處理:MySQL支持幾種基本的數(shù)據(jù)庫引擎。并非所有引擎都支持明確的事務(wù)處理管理。MyISAM和InnoDB是兩種最常使用的引擎。前者不支持明確的事務(wù)處理管理,而后者支持。如果你的應(yīng)用中需要事務(wù)處理功能,則一定要使用正確的引擎類型。

事務(wù)處理(transaction processing)可以用來維護(hù)數(shù)據(jù)庫的完整性,它保證成批的MySQL操作要么完全執(zhí)行,要么完全不執(zhí)行。

在使用事務(wù)和事務(wù)處理時(shí),有幾個(gè)關(guān)鍵字會(huì)反復(fù)出現(xiàn)。下面關(guān)于事務(wù)處理需要知道的幾個(gè)術(shù)語:

1、事務(wù)(transaction)指一組SQL語句

2、回退(rollbac)指撤銷指定SQL語句的過程

3、提交(commit)指將未存儲(chǔ)的SQL語句結(jié)果寫入數(shù)據(jù)庫表

4、保留點(diǎn)(savepoint)指事務(wù)處理中設(shè)置的臨時(shí)占位符(placeholder),你可以對(duì)它發(fā)布回退(與回退整個(gè)事務(wù)處理不同)

--控制事務(wù)處理

管理事務(wù)處理的關(guān)鍵在于將SQL語句組分解為邏輯塊,并明確規(guī)定數(shù)據(jù)何時(shí)應(yīng)該回退,何時(shí)不應(yīng)該回退。

MySQL使用下面的語句來標(biāo)識(shí)事務(wù)的開始:

START TRANSACTION;

--使用ROLLBACK

MySQL使用ROLLBACK命令用來回退(撤銷)MySQL語句:

SELECT * FROMordertotals;

STARTTRANSACTION;DELETE FROMordertotals;SELECT * FROMordertotals;ROLLBACK;SELECT * FROM ordertotals;

根據(jù)上述例子可知,ROLLBACK只能在一個(gè)事務(wù)處理內(nèi)使用(在執(zhí)行一條START TRANSACTION命令之后)。

ps:哪些語句可以回退:事務(wù)管理用來管理INSERT、UPDATE和DELETE語句。你不能回退SELECT語句(因?yàn)檫@么做沒有意義)。你不能回退CREATE和DROP操作。事務(wù)處理塊中可以使用這兩條語句,但如果你執(zhí)行回退,它們不會(huì)被撤銷。

--使用COMMIT

一般的MySQL語句都是直接針對(duì)數(shù)據(jù)庫表執(zhí)行和編寫的。這就是所謂的隱含提交(implict commit),即提交(寫或保存)操作是自動(dòng)進(jìn)行的。但是,在事務(wù)處理某塊中,提交不會(huì)隱含地進(jìn)行。為進(jìn)行明確的提交,使用COMMIT語句,如下所示:

START TRANSACTION;DELETE FROM orderitems WHERE order_num = 20010;DELETE FROM orders WHERE order_num = 20010;COMMIT;

ps:隱含事務(wù)關(guān)閉:當(dāng)COMMIT或ROLLBACK語句執(zhí)行后,事務(wù)會(huì)自動(dòng)關(guān)閉(將來的更改會(huì)隱含提交)

--使用保留點(diǎn)

為了支持回退部分事務(wù)處理,必須能在事務(wù)處理塊中合適的位置放置占位符。這樣,如果需要回退,可以回退到某個(gè)占位符。這些占位符稱為保留點(diǎn)。為了創(chuàng)建占位符,可如下使用SAVEPOINT語句:

SAVEPOINT delete1;

每個(gè)占位符都取標(biāo)識(shí)它的唯一名字,以便在回退時(shí),MySQL知道要回退到何處。為了回退到本例給出的保留點(diǎn),可如下進(jìn)行:

ROLLBACK TO delete1;

ps:保留點(diǎn)越多越好:可以在MySQL代碼中設(shè)置任意多的保留點(diǎn),越多越好。因?yàn)楸A酎c(diǎn)越多,你就越能按自己的意愿靈活地進(jìn)行回退。

釋放保留點(diǎn):保留點(diǎn)在事務(wù)處理完成(執(zhí)行一條ROLLBACK或COMMIT)后自動(dòng)釋放。自MySQL5以來,也可以用RELEASE SAVEPOINT明確地釋放保留點(diǎn)。

--更改默認(rèn)的提交行為

正如所述,默認(rèn)的MySQL行為是自動(dòng)提交所有更改。換句話說,任何時(shí)候你執(zhí)行一條MySQL語句,該語句實(shí)際上都是針對(duì)表執(zhí)行的,而且所做的更改立即生效。為提示MySQL不自動(dòng)提交更改,需要使用以下語句:

SET sutocommit=0;

autocommit標(biāo)志決定是都自動(dòng)提交更改,不管有沒有COMMIT語句。設(shè)置autocommit為0(假)只是MySQL不自動(dòng)提交更改(直到autocommit被設(shè)置為真為止)。

ps:標(biāo)志為連接專用:autocommit標(biāo)志是針對(duì)每個(gè)連接而不是服務(wù)器的。

----全球化和本地化

--字符集和校對(duì)順序

數(shù)據(jù)庫表被用來存儲(chǔ)和檢索數(shù)據(jù)。不同的語言和字符集需要以不同的方式存儲(chǔ)和檢索。因此,MySQL需要使用不同的字符集(不同的字母和字符),適應(yīng)不同的排序和檢索數(shù)據(jù)的方法。

重要屬于:

1、字符集為字母和符號(hào)的集合

2、編碼為某個(gè)字符集成員的內(nèi)部表示

3、校對(duì)為規(guī)定字符如何比較的指令

ps:校對(duì)很重要,因?yàn)椴煌淖址判蚍绞讲煌?#xff0c;比如大小寫就是一種校對(duì)順序,還有就是法文或德文等字符,情況更復(fù)雜,在不基于拉丁文的字符集(日文、希伯來語、俄文等)時(shí),情況就更為復(fù)雜了。

--使用字符集和校對(duì)順序

MySQL支持眾多的字符集。為查看所支持的字符集完整列表,使用以下語句:

--------這條語句顯示所有可用的字符集以及每個(gè)字符集的描述和默認(rèn)校對(duì)。

SHOW CHARACTER SET;

-------此語句顯示所有可用的校對(duì),以及它們適用的字符集

SHOW COLLATION;

通常系統(tǒng)管理在安裝定義時(shí)定義一個(gè)默認(rèn)的字符集和校對(duì)。此外,也可以在創(chuàng)建數(shù)據(jù)庫時(shí),指定默認(rèn)的字符集和校對(duì)。為了確定所用的字符集和校對(duì),可以使用以下語句:

SHOW VARIABLES LIKE 'character%';

SHOW VARIABLESLIKE 'collation%';

實(shí)際上,字符集很少是服務(wù)器范圍(甚至是數(shù)據(jù)庫范圍)的設(shè)置。不同的表,甚至不同的列都可能需要不同的字符集,而且兩者都可以在創(chuàng)建表時(shí)指定。

為了給表指定字符集和校對(duì),可使用帶子句的CREATE TABLE,以下語句創(chuàng)建包含兩列的表,并且指定一個(gè)字符集和一個(gè)校對(duì)順序,這個(gè)例子中指定了CHARACTER SET和COLLATE。一般,MySQL如下確定使用什么樣子的字符集和校對(duì)。

1、如果指定CHARACTER SET和COLLATE兩者,則使用這些值

2、如果只指定CHARACTER SET,則使用此字符集及其默認(rèn)的校對(duì)(如果SHOW CHARACTER SET的結(jié)果中所示)

3、如果既不指定CHARACTER SET,也不指定COLLATE,則使用數(shù)據(jù)庫默認(rèn)。

CREATE TABLEmytable

(

colum1INT,

colum2VARCHAR(10)

)DEFAULT CHARACTER SEThebrew

COLLATE hebrew_general_ci;

除了能指定字符集和校對(duì)的表范圍外,MySQL還允許對(duì)每個(gè)列設(shè)置它們,如下所示:

CREATE TABLEmytable

(

colum1INT,

colum2 VARCAHR(10),

colum3 VARCAHR(10) CHARACTER SETlatin1 COLLATE latin1_general_ci

)DEFAULT CHARACTER SEThebrew

COLLATE hebrew_general_ci;-------這里對(duì)整個(gè)表以及一個(gè)特定的列指定了CHARACTER SET和COLLATE

如前所述,校對(duì)在對(duì)用ORDER BY子句檢索出來的數(shù)據(jù)排序時(shí)起很重要的作用。如果你需要用與創(chuàng)建表時(shí)不同的校對(duì)順序排序特定的SELECT語句,可以在SELECT語句自身中進(jìn)行:

SELECT * FROMcustomersORDER BYlastname, fistname COLLATE latin1_general_cs;----此SELECT使用COLLATE指定一個(gè)備用的校對(duì)順序(在這個(gè)例子中,為區(qū)分大小寫的校對(duì))。這顯然會(huì)影響到結(jié)果排序的次序。

ps:臨時(shí)區(qū)分大小寫:上面的SELECT語句演示了在通常不區(qū)分大小寫的表上進(jìn)行區(qū)分大小寫搜索的一種技術(shù)。當(dāng)然,反過來也是可以的。

SELECT的其他COLLATE子句:除了這里可以看到的在ORDER BY子句中使用以外,COLLATE還可以用于GROUP BY、HAVING、聚集函數(shù)、別名等。

**值得注意的是,如果絕對(duì)需要,串可以在字符集之間進(jìn)行轉(zhuǎn)換。為此,使用Cast()或Convert()函數(shù)。

----安全管理

--訪問控制

MySQL服務(wù)器的安全基礎(chǔ)是:用戶應(yīng)該對(duì)他們需要的數(shù)據(jù)具有適當(dāng)?shù)脑L問權(quán),既不能多也不能少。換句話說,用戶不能對(duì)過多的數(shù)據(jù)具有過多的訪問權(quán)。

考慮以下內(nèi)容:

1、多數(shù)用戶只需要對(duì)表進(jìn)行讀和寫,但少數(shù)用戶甚至需要能創(chuàng)建和刪除表

2、某些用戶需要讀表,但可能不需要更新表

3、你可能想允許添加數(shù)據(jù),但不允許他們刪除數(shù)據(jù)

4、某些用戶(管理員)可能需要處理用戶賬號(hào)的權(quán)限,但多數(shù)用戶不需要

5、你可能想讓用戶通過存儲(chǔ)過程訪問數(shù)據(jù),但不允許他們直接訪問數(shù)據(jù)

6、你可能想根據(jù)用戶登錄的地點(diǎn)限制對(duì)某些功能的訪問

這些都只是例子,但有助于說明一個(gè)重要的事實(shí),即你需要給用戶提供他們所需的訪問權(quán),且僅提供他們所需的訪問權(quán)。這就是所謂的訪問控制,管理訪問控制需要?jiǎng)?chuàng)建和管理用戶賬號(hào)。

ps:使用MySQL Administrator:MySQL Administrator提供了一個(gè)圖形用戶界面,可用來管理用戶及賬戶權(quán)限。MySQL Administrator在內(nèi)部利用本章介紹的語句,使用能交互地、方便地管理訪問控制。

我們知道,為了執(zhí)行數(shù)據(jù)庫操作,需要登錄MySQL。MySQL創(chuàng)建一個(gè)名為root的用戶賬戶,它對(duì)整個(gè)MySQL服務(wù)器具有完全的控制。但在實(shí)際應(yīng)用中,應(yīng)該創(chuàng)建一系列的賬號(hào),有的用于管理,有的供用戶使用,有的供開發(fā)人員使用。

ps:防止無意的錯(cuò)誤:重要的是注意到,訪問控制的目的不僅僅是防止用戶的惡意企圖。數(shù)據(jù)夢(mèng)魘更為常見的是無意識(shí)錯(cuò)誤的結(jié)果,如打錯(cuò)MySQL語句,在不適合的數(shù)據(jù)庫中操作或其他一些用戶錯(cuò)誤。通過保證用戶不能執(zhí)行他們不應(yīng)該執(zhí)行的語句,訪問控制有助于避免這些情況的發(fā)生。

不要使用root:應(yīng)該嚴(yán)肅對(duì)待root登錄的使用。僅在絕對(duì)需要時(shí)使用它(或許在你不能登錄其他管理賬號(hào)時(shí)使用)。不應(yīng)該在日常的MySQL操作中使用root。

--管理用戶

MySQL用戶賬號(hào)和信息存儲(chǔ)在名為mysql數(shù)據(jù)表中。一般不需要直接訪問mysql數(shù)據(jù)庫和表,但有時(shí)需要直接訪問。需要直接訪問它的時(shí)機(jī)之一是在需要獲得所有用戶賬號(hào)列表時(shí)。為此,可使用以下代碼:

USEmysql;SELECT user FROM user;

ps:用多個(gè)客戶機(jī)進(jìn)行試驗(yàn):試驗(yàn)對(duì)用戶賬號(hào)和權(quán)限進(jìn)行更改的最好辦法是打開多個(gè)數(shù)據(jù)庫客戶機(jī)(如mysql命令行實(shí)用程序的多個(gè)副本),一個(gè)作為管理登錄,其他作為被測(cè)試的用戶登錄。

--創(chuàng)建用戶賬號(hào)

為創(chuàng)建一個(gè)新用戶賬號(hào),使用CREATE USER語句,如下所示:

CREATE USER ben IDENTIFIED BY 'p@$$w0rd';----CREATE USER創(chuàng)建一個(gè)新用戶賬號(hào)。在創(chuàng)建用戶賬號(hào)時(shí)不一定需要口令,不過這個(gè)例子用IDENTIFIED BY 'p@$$w0rd'給出了一個(gè)口令,如果你再次列出用戶賬號(hào),將會(huì)在輸出中看到新賬號(hào)。

ps:指定散列口令:IDENTIFIED BY指定的口令為純文本,MySQL將在保存到user表之前對(duì)其進(jìn)行加密。為了作為散列值指定口令,使用IDENTIFIED BY PASSWORD.

使用GRANT或INSERT:GRANT語句也可以創(chuàng)建用戶賬號(hào),但一般來說CREATE USER是最清楚和最簡單的句子。此外,也可以通過直接插入行到user表來增加用戶,不過為安全起見,一般不建議這么做。MySQL用來存儲(chǔ)用戶賬號(hào)信息的表(以及表模式等)極為重要,對(duì)他們的任何毀壞都可能嚴(yán)重地傷害到MySQL服務(wù)器。因此,相對(duì)于直接處理來說,最好是用標(biāo)記和函數(shù)來處理這些表。

為重新命名一個(gè)用戶賬號(hào),使用RENAME USER語句,如下所示:

RENAME USER ben TO bforta;

--刪除用戶賬號(hào)

為了刪除一個(gè)用戶賬號(hào)(以及相關(guān)的權(quán)限),使用DROP USER語句,如下所示:

DROP USER bforta;

ps:MySQL 5之前:自MySQL 5以來,DROP USER刪除用戶賬號(hào)和所有相關(guān)的賬號(hào)和權(quán)限。在MySQL5以前,DROP USER只能用來刪除用戶賬號(hào),不能刪除相關(guān)的 權(quán)限。因此,如果使用舊版本的MySQL,需要先用REVOKE刪除與賬號(hào)相關(guān)的權(quán)限,然后再用DROP USER刪除賬號(hào)。

--設(shè)置訪問權(quán)限

在創(chuàng)建用戶賬號(hào)后,必須接著分配訪問權(quán)限。新創(chuàng)建的用戶賬號(hào)沒有訪問權(quán)限。它們能登錄MySQL,但不能看到數(shù)據(jù),不能執(zhí)行任何數(shù)據(jù)庫操作。

為看到賦予用戶賬號(hào)的權(quán)限,使用SHOW GRANT FOR,如下所示:

SHOW GRANT FOR bforta;

輸出結(jié)果顯示用戶bforta有一個(gè)權(quán)限USAGE ON *.*。USAGE表示根本沒有權(quán)限,所以此結(jié)果表示在任意數(shù)據(jù)庫和任意表上對(duì)任何東西沒有權(quán)限。

ps:用戶定義為user@host:MySQL的權(quán)限用用戶名和主機(jī)名結(jié)合定義。如果不指定主機(jī)名,則使用默認(rèn)的主機(jī)名%(授予用戶訪問權(quán)限而不管主機(jī)名)。

為設(shè)置權(quán)限,使用GRANT語句。GRANT要求你至少給出以下信息:

1、要授予的權(quán)限

2、被授予訪問權(quán)限的數(shù)據(jù)庫或表

3、用戶名

以下給出GRANT的用法:

GRANT SELECT ON crashcourse.* TO bforta;

SHOW GRANT反應(yīng)這個(gè)更改:

SHOW GRANT FOE beforta;

GRANT的反操作為REVOKE,用它來撤銷特定的權(quán)限,舉個(gè)例子:

REVOKE SELECT ON crashcourse.* FROM bforta;

GRANT和REVOKE可在幾個(gè)層次上控制訪問權(quán)限:

1、整個(gè)服務(wù)器,使用GRANT ALL和REVOKE ALL

2、整個(gè)數(shù)據(jù)庫,使用ON database.*

3、特定的表,使用ON database.table

4、特定的列

5、特定的存儲(chǔ)過程

以下列出可以授予或撤銷的每個(gè)權(quán)限:

權(quán)限

權(quán)限

說明

ALL

除GRANT OPTION外的所有權(quán)限

ALTER ROUNTINE

使用ALTER TABLE

CREATE

使用ALTER PROCEDURE和DROP PROCEDURE

CREATE ROUTINE

使用CREATE PROCEDURE

CREATE TEMPORARY TABLES

使用CREATE TEMPORARY TABLE

CREATE USER

使用CREATE USER、DROP USER、RENAME USER和REVOKE ALL PRIVILEGES

CREATE VIEW

使用CREATE VIEW

DELETE

使用DELETE

DROP

使用DROP TABLE

EXECUTE

使用CALL和存儲(chǔ)過程

FILE

使用SELECT INTO OUTFILE和LOAD DATA INFILE

GRANT OPTION

使用GRANT和REVOKE

INDEX

使用CREATE INDEX和DROP INDEX

INSERT

使用INSERT

LOCK TABLES

使用LOCK TABLES

PROCESS

使用SHOW FULL PROCESSLIST

RELOAD

使用FLUSH

REPLICATION CLIENT

服務(wù)器位置的訪問

REPLICATION SLAVE

由復(fù)制從屬使用

SELECT

使用SELECT

SHOW DATABASES

使用SHOW DATABASES

SHOW VIEW

使用SHOW CREATE VIEW

SHUT DOWN

使用mysqladmin shutdown(用來關(guān)閉MySQL)

SUPER

使用CHANGE MASTER、KILL、LOGS、PURGE、MASTER和SER GLOBAL。還允許mysqladmin調(diào)試登錄

UPDATE

使用UPDATE

USAGE

無訪問權(quán)限

使用GRANT和REVOKE,在結(jié)合上表列出權(quán)限,你能用戶可以就你的寶貴數(shù)據(jù)做什么事情和不能做什么事情具有完全的控制。

ps:未來的授權(quán):在使用GRANT和REVOKE時(shí),用戶賬號(hào)必須存在,但對(duì)所涉及的對(duì)象沒有這個(gè)要求。還允許管理員在創(chuàng)建數(shù)據(jù)庫的和表之前設(shè)計(jì)和實(shí)現(xiàn)安全措施。這樣做的副作用是,當(dāng)某個(gè)數(shù)據(jù)庫或表被刪除時(shí)(用DROP語句),相關(guān)的訪問權(quán)限仍然存在,而且,如果將來重新創(chuàng)建該數(shù)據(jù)庫或表,這些權(quán)限仍然起作用。

簡化多次授權(quán):可通過列出各權(quán)限并用逗號(hào)分隔,將多條GRANT語句串在一起,如下所示:

GRANT SELECT, INSERT, ON crashcourse.* TO bforeta;

--更改口令

為了更改用戶口令,可使用SET PASSWORD語句。新口令必須如下加密:

SELECT PASSWORD FOR bforta = Password('n3w p@$$w0rd');

-----分析:SET PASSWORD更新用戶口令。新口令必須傳遞到Password()函數(shù)進(jìn)行加密。

SET PASSWORD還可以用來設(shè)置你自己的口令:

SET PASSWORD = Password('n3w p@$$w0rd');----在不指定用戶名時(shí),SET PASSWORD更新當(dāng)前登錄用戶的口令。

----數(shù)據(jù)庫維護(hù)

--備份數(shù)據(jù)

解決普通的文件副本不一定總是有效的方案:

1、使用命令行使用程序mysqldump轉(zhuǎn)儲(chǔ)所有數(shù)據(jù)庫內(nèi)容到某個(gè)外部文件。在進(jìn)行常規(guī)備份前這個(gè)實(shí)用程序應(yīng)該正常運(yùn)行,以便能正確地備份轉(zhuǎn)儲(chǔ)文件

2、可用命令行實(shí)用程序mysqlhotcopy從一個(gè)數(shù)據(jù)庫復(fù)制所有數(shù)據(jù)(并非所有數(shù)據(jù)庫引擎都支持這個(gè)實(shí)用程序)

3、可以使用MySQL的BACKUP TABLE或SELECT INTO OUTFILE轉(zhuǎn)儲(chǔ)所有數(shù)據(jù)到某個(gè)外部文件。這兩條語句都接受將要?jiǎng)?chuàng)建的系統(tǒng)文件名,此系統(tǒng)文件必須不存在,否則會(huì)出錯(cuò)。數(shù)據(jù)可以用RESTORE TABLE來復(fù)原

ps:首先刷新未寫數(shù)據(jù):為了保證所有數(shù)據(jù)被寫道磁盤(包括索引數(shù)據(jù)),可能需要在進(jìn)行備份前使用FLUSH TABLES語句。

--進(jìn)行數(shù)據(jù)庫維護(hù)

MySQL提供了一系列的語句,可以(應(yīng)該)用來保證數(shù)據(jù)庫正確和正常運(yùn)行。

-ANALYZE TABLE,用來檢查表鍵是否正確

ANALIZE TABLE orders;

-CHECK TABLE,用來針對(duì)許多問題對(duì)表進(jìn)行檢查。在MyISAM表上還對(duì)索引進(jìn)行檢查。CHECK TABLE支持一系列的用于MyISAM表的方式。CHANGED檢查自最后一次檢查以來改動(dòng)過的表。EXTENDED執(zhí)行最徹底的檢查,FAST只檢查未正常關(guān)閉的表,MEDIUM檢查所有被刪除的鏈接并進(jìn)行鍵檢查,QUICK只進(jìn)行快速掃描。如下所示,CHECK TABLE發(fā)現(xiàn)和修復(fù)問題:

CHECK TABLE orders, orderitems;

-如果MyISAM表訪問產(chǎn)生不正確和不一致的結(jié)果,可能需要用REPAIR TABLE來修復(fù)相應(yīng)的表。這條語句不應(yīng)該經(jīng)常使用,如果需要經(jīng)常使用,可能會(huì)有更大的問題要解決。

-如果從一個(gè)表中刪除大量數(shù)據(jù),應(yīng)該使用OPTIMIZE TABLE來收回所有的空間,從而優(yōu)化表的性能。

--診斷啟動(dòng)問題

服務(wù)器啟動(dòng)問題通常在對(duì)MySQL配置或服務(wù)器本身進(jìn)行更改時(shí)出現(xiàn)。MySQL在這個(gè)問題上發(fā)生時(shí)報(bào)告錯(cuò)誤,但由于多數(shù)MySQL服務(wù)器是作為系統(tǒng)進(jìn)程或服務(wù)自動(dòng)啟動(dòng)的,這些消息可能看不到。

在排除系統(tǒng)啟動(dòng)問題時(shí),首先應(yīng)該盡量用手動(dòng)啟動(dòng)服務(wù)器。MySQL服務(wù)器自身通過在命令行上執(zhí)行mysqld啟動(dòng)。下面是幾個(gè)重要的mysqld命令行選項(xiàng):

1、--help顯示幫助———一個(gè)選項(xiàng)列表

2、--safe-mode裝載減去某些最佳配置的服務(wù)器

3、--verbose顯示全文本消息(為獲得更詳細(xì)的幫助消息與--help聯(lián)合使用)

4、--version顯示版本信息然后退出

--查看日志文件

MySQL維護(hù)管理員依賴的一系列日志文件。主要的日志文件有以下幾種:

1、錯(cuò)誤日志。它包含啟動(dòng)和關(guān)閉問題以及任意關(guān)鍵錯(cuò)誤的細(xì)節(jié)。此日志通常名為hostname.err,位于data目錄中。此日志名可用--log-error命令行選項(xiàng)更改。

2、查詢?nèi)罩尽K涗浰蠱ySQL活動(dòng),在診斷問題時(shí)非常有用。此日志文件可能會(huì)很快地變得非常大,因此不應(yīng)該長期使用它。此日志文件通常名為hostname.log,位于data目錄中。此名字可以用--log命令行選項(xiàng)更改。

3、二進(jìn)制日志。它記錄更新過數(shù)據(jù)(或者可能更新過的數(shù)據(jù))的所有語句。此日志通常名為hostname-bin,位于data目錄內(nèi)。此名字可以用--log-bin命令行選項(xiàng)更改。注意,這個(gè)日志文件是MySQL5中添加的,以前的MySQL版本中使用的是更新日志。

4、緩慢查詢?nèi)罩尽4巳罩居涗泩?zhí)行緩慢的任何查詢。這個(gè)日志在確定數(shù)據(jù)庫何處需要優(yōu)化很有用。此日志通常名為hostname-slow.log,位于data目錄中。此名字可以用--log-slo-queries命令行選項(xiàng)更改。

在使用日志時(shí),可用FLUSH LOGS語句來刷新和重新開始所有日志文件。

----改善性能

1、首先,MySQL(與所有DBMS一樣)具有特定的硬件建議。在學(xué)習(xí)和研究MySQL時(shí),使用任何舊的計(jì)算機(jī)作為服務(wù)器都可以。但對(duì)用于生產(chǎn)的服務(wù)器來說,應(yīng)該堅(jiān)持遵循這些硬件建議

2、一般來說,關(guān)鍵的生產(chǎn)DBMS應(yīng)該運(yùn)行在自己的專用服務(wù)器上

3、MySQL是用一系列的默認(rèn)設(shè)置預(yù)先設(shè)置的,這些設(shè)置開始通常是很好的。但過一段時(shí)間后你可能需要調(diào)整內(nèi)存分配、緩沖區(qū)大小等。(為查看當(dāng)前設(shè)置,可使用SHOW VARIABLES;和SHOW STATUS;)

4、MySQL是一個(gè)多用戶多線程的DBMS,換言之,它經(jīng)常同時(shí)執(zhí)行多個(gè)任務(wù)。如果這些任務(wù)中的某一個(gè)執(zhí)行緩慢,則所有請(qǐng)求都會(huì)執(zhí)行緩慢。如果你遇到顯著的性能不良,可使用SHOW PROCESSLIST顯示所有活動(dòng)進(jìn)程(以及它們的線程ID和執(zhí)行時(shí)間)。你還可以用KILL命令終結(jié)某個(gè)特定的進(jìn)程(使用這個(gè)命令需要作為管理員登錄)

5、總是有不止一種方法編寫同一條SELECT語句。應(yīng)該試驗(yàn)聯(lián)結(jié)、并、子查詢等,找出最佳方法

6、使用EXPLAIN語句讓MySQL解釋它將如何執(zhí)行一條SELECT語句

7、一般來說,存儲(chǔ)過程執(zhí)行的比一條一條地執(zhí)行其中的各條MySQL語句快

8、應(yīng)該總是使用正確的數(shù)據(jù)類型

9、決不要檢索比需要還要多的數(shù)據(jù)。換言之,不要用SELECT *(除非你真正需要每個(gè)列)

10、有的操作(包括INSERT)支持一個(gè)可選的DELAYED關(guān)鍵字,如果使用它,將把控制立即返回給調(diào)用程序,并且一旦有可能就實(shí)際執(zhí)行該操作

11、在導(dǎo)入數(shù)據(jù)時(shí),應(yīng)該關(guān)閉自動(dòng)提交。你可能還想刪除索引(包括FULLTEXT索引),然后在導(dǎo)入完成后再重建它們

12、必須索引數(shù)據(jù)庫表以改善數(shù)據(jù)檢索的性能。確定索引什么不是一件微不足道的任務(wù),需要分析使用的SELECT語句以找出重復(fù)的WHERE和ORDER BY子句。如果一個(gè)簡單的WHERE子句返回結(jié)果所花的時(shí)間太長,則可以斷定其中使用的列(或幾個(gè)列)就是需要索引的對(duì)象

13、你的SELECT語句中有一系列復(fù)雜的OR條件嗎?通過使用多條SELECT語句和連接它們的UNION語句,你能看到極大的性能的改進(jìn)

14、索引改善數(shù)據(jù)索引的性能,但損害數(shù)據(jù)插入、刪除和更行的性能。如果你有一些表,它們收集數(shù)據(jù)且不經(jīng)常被搜索,則在有必要之前不要索引它們。(索引可根據(jù)需要添加和刪除)

15、LIKE很慢。一般來說,最好使用FULLTEXT而不是LIKE

16、數(shù)據(jù)庫是不斷變化的實(shí)體。一組優(yōu)化良好的表一會(huì)兒后可能就面目全非了。由于表的使用和內(nèi)容的更改,理想的優(yōu)化和配置也會(huì)改變

17?、最重要的規(guī)則就是,每條規(guī)則在某些條件下都會(huì)被打破

ps:瀏覽文檔:http://dev.mysql.com/doc,更多的內(nèi)容參考MySQL手冊(cè)

------------------------------------------------

本文章參考自《mysql必知必會(huì)》

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的mysql中以下正确的sql是_总结MySQL中SQL语法的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: yes4444视频在线观看 | 欧美色图一区二区三区 | av第一页 | 强行挺进白丝老师里呻吟 | 午夜国产一区二区 | 日本五十路在线 | 日本高清视频在线播放 | 纯爱无遮挡h肉动漫在线播放 | 欧美色乱 | 日本在线观看一区二区三区 | 国产精品成人午夜视频 | 精品久久久999 | 捆绑无遮挡打光屁股调教女仆 | 男人的天堂久久久 | 激情文学欧美 | 欧美 日韩 国产 一区 | 波多野吉衣久久 | 欧美国产日韩在线观看 | 情侣黄网站免费看 | 亚洲一区二区影视 | 亚洲综合国产精品 | 欧美另类videosbestsex | 天堂在线中文 | 草久在线观看视频 | 夜夜爽天天干 | 亚洲国产精品国自产拍久久 | 国产乱free国语对白 | 国产精品手机在线 | 亚洲毛片一级 | 国产人妖一区二区三区 | h视频亚洲| 日韩天堂一区 | 欧美,日韩,国产在线 | 视频一区二区三区精品 | 最新av在线 | 亚洲av无码国产精品久久久久 | 美女在线国产 | 美女毛片在线 | 亚洲2022国产成人精品无码区 | 精品国产一区二区三区四区阿崩 | 免费人成网 | 香蕉视频免费看 | 九九资源网 | 色女孩综合 | 国模人体一区二区 | 亚洲人成色777777精品音频 | 男生和女生操操 | 亚洲精品乱码久久久久久蜜桃麻豆 | 国产精品亚洲第一 | 永久黄色网址 | 精品国产欧美日韩 | 精品人妻少妇AV无码专区 | 三级精品在线观看 | 免费午夜视频在线观看 | 色女仆影院 | 亚洲天天在线 | 制服丝袜中文字幕在线 | 国产视频不卡 | 高清在线一区 | 另类专区欧美 | 国产白袜脚足j棉袜在线观看 | 欧美伊人网 | 亚洲精品国产精品国自产 | 人人插人人射 | 亚洲人成人 | 国产第一福利影院 | 久久黄网 | 国产免费专区 | 伊人狼人久久 | 亚洲熟妇无码av | 天天操夜夜夜 | 99国产精品一区二区 | 欧美综合在线视频 | 国产99免费视频 | 亚洲无限av | 亚洲av无码精品一区二区 | 五月婷婷激情四射 | 欧美a级肉欲大片xxx | 国产尤物视频在线 | 91香蕉视频在线 | 麻豆蜜桃91 | 4438全国成人免费 | 国产乱人乱偷精品视频 | 91久久精品日日躁夜夜躁欧美 | 三级大片在线观看 | 91微拍| 丝袜av网站| 欧美一级久久久 | 好色成人网 | 在线观看av网站 | 91丨九色丨丰满人妖 | 永久免费毛片 | 性大毛片视频 | 天天操天天操天天操天天操天天操 | 欧美 国产 综合 | 操欧美美女| 日本黄色精品 | 美女扒开腿免费视频 | 国产日韩在线视频 |