版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
MYSQL專題查詢優(yōu)化使用索引平安隱患事務(wù)與鎖鄺偉林梧桐網(wǎng)絡(luò)工作室MySQL優(yōu)化查詢操作數(shù)據(jù)庫最重要的一個(gè)環(huán)節(jié)就是查詢,如何優(yōu)化數(shù)據(jù)庫查詢加快查詢速度與最優(yōu)化數(shù)據(jù)庫空間顯得尤為重要,下面我將從多個(gè)方面以分析原理與具體采取怎樣的措施的方式進(jìn)行講解。
(一)給字段選取最適宜的數(shù)據(jù)類型
選擇CHAR還是VARCHAR?
我們知道,這兩個(gè)屬性都是給字符分配空間的,一個(gè)是定長,一個(gè)是變長,對于使用MyISAM數(shù)據(jù)存儲引擎的表,在能夠比擬事先確定長度的情況下,比方一個(gè)郵政編碼,最好使用CHAR類型,因?yàn)椴樵兌ㄩL的數(shù)據(jù)比查詢變長的數(shù)據(jù)要快,再那么,盡可能地將字段的寬度設(shè)得小些,以免增加不必要的空間;對于MEMORY數(shù)據(jù)表,由于目前都使用固定長度的數(shù)據(jù)行存儲,因此無論使用CHAR或VARCHAR列都沒有關(guān)系,兩者都是作為CHAR類型處理的。對于InnoDB數(shù)據(jù)表,內(nèi)部的行存儲格式?jīng)]有區(qū)分固定長度和可變長度列〔所有數(shù)據(jù)行都使用指向數(shù)據(jù)列值的頭指針〕,因此在本質(zhì)上,使用固定長度的CHAR列不一定比使用可變長度VARCHAR列簡單。因而,主要的性能因素是數(shù)據(jù)行使用的存儲總量。由于CHAR平均占用的空間多于VARCHAR,因此使用VARCHAR來最小化需要處理的數(shù)據(jù)行的存儲總量和磁盤I/O是比擬好的。需要注意的是,如果MySQL運(yùn)行在嚴(yán)格模式,使用CHAR類型時(shí)超過列長度的值將不被保存,并且會出現(xiàn)錯(cuò)誤;再那么,諸如CHAR(10)與VARCHAR(10)檢索到的值并不總是相同,因?yàn)镃HAR列會刪除尾部的空格,而VARCHAR列會保存尾部的空格。
在選擇FLOAT/DOUBLE/REAL〔浮點(diǎn)數(shù)〕時(shí)需要說明的是浮點(diǎn)數(shù)能夠表示更大的數(shù)據(jù)范圍,但會引起精度的問題,即,類型為浮點(diǎn)數(shù)的字段值比方123456.31,檢索出來時(shí)值可能會是123456.30,這時(shí)如果用于做數(shù)據(jù)的比擬時(shí)就可能出錯(cuò),要防止這個(gè)問題。
同理,給數(shù)值類型選擇字段屬性時(shí),盡可能地減小字段的寬度,如可以使用MEDIUMINT滿足要求的情況就不要將字段設(shè)置為BIGINT,以節(jié)省空間,而一旦表占用的空間越小,檢索的速度就會越快。
(二)BLOB與TEXT的問題
第一:在對設(shè)置為BLOB和TEXT字段屬性的值做大量的刪除或更新操作的時(shí),這種值會在數(shù)據(jù)表中留下很大的"空洞",以后填入這些"空洞"的記錄可能長度不同,為了提高性能,建議定期使用OPTIMIZETABLE功能對這類表進(jìn)行碎片整理.第二:在有BLOB或TEXT時(shí),盡可能地防止使用:select*...,這樣的查詢語句,因?yàn)檫@樣可能會引起大量的值在網(wǎng)絡(luò)上做無謂的傳輸,此時(shí),我的建議是你可以把有BLOB或TEXT的字段單獨(dú)拿出來用另外一個(gè)表來存儲,這樣就可以防止做無謂的檢索大型的值;還有一種方法就是使用合成的索引,它是根據(jù)其它的列的內(nèi)容〔或使用MD5,SHA1,CRC32等函數(shù)〕建立一個(gè)散列值,并把這個(gè)值存儲在單獨(dú)的數(shù)據(jù)列中,通過檢索散列值來找到數(shù)據(jù)行,用散列標(biāo)識符值查找的速度比搜索BLOB或TEXT列本身的速度快很多。
(三)使用NOTNULL
把數(shù)據(jù)列定義成不能為空〔NOTNULL〕,這樣有利于簡化查詢,因?yàn)椴恍枰獧z查值的NULL屬性,有利于檢索引擎做出判斷。
(四)使用ENUM
如果你擁有的某個(gè)數(shù)據(jù)列的基數(shù)很低〔包含的不同的值數(shù)量有限〕,那么可以考慮把它轉(zhuǎn)換為ENUM列。ENUM值可以被更快地處理,因?yàn)樗鼈冊趦?nèi)部表現(xiàn)為數(shù)值,通常,檢索數(shù)值要比檢索字符文本要快。
(五)優(yōu)化GROUPBY語句
默認(rèn)情況下,MySQL排序所有GROUPBY包含的字段,為了防止排序結(jié)果的消耗,你可以指定ORDERBYNULL禁止排序。
(六)優(yōu)化JOIN語句
Mysql4.1開始支持SQL的子查詢。這個(gè)技術(shù)可以使用SELECT語句來創(chuàng)立一個(gè)單列的查詢結(jié)果,然后把這個(gè)結(jié)果作為過濾條件用在另一個(gè)查詢中。使用子查詢可以一次性的完成很多邏輯上需要多個(gè)步驟才能完成的SQL操作,同時(shí)也可以防止事務(wù)或者表鎖死,并且寫起來也很容易。但是,有些情況下,子查詢可以被更有效率的連接(JOIN)替代。
假設(shè)我們要將所有沒有訂單記錄的用戶取出來,可以用下面這個(gè)子查詢方式完成:SELECT*FROMcustomerinfoWHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)如果使用連接(JOIN)來完成這個(gè)查詢工作,速度將會快很多。尤其是當(dāng)salesinfo表中對CustomerID建有索引的話,性能將會更好,查詢?nèi)缦拢篠ELECT*FROMcustomerinfo
LEFTJOINsalesinfoONcustomerinfo.CustomerID=salesinfo.CustomerID
WHEREsalesinfo.CustomerIDISNULL連接(JOIN)之所以更有效率一些,是因?yàn)镸ySQL不需要在內(nèi)存中創(chuàng)立臨時(shí)表來完成這個(gè)邏輯上的需要兩個(gè)步驟的查詢工作。
(七)使用查詢緩存(mysqlquerycache)
查詢緩存的功能在于存儲SELECT查詢的文本以及發(fā)送給客戶端的相應(yīng)結(jié)果。如果隨后收到一個(gè)相同的查詢,效勞器會從查詢緩存中重新得到查詢結(jié)果,而不再需要解析和執(zhí)行查詢,這樣可以大大提高那些重復(fù)執(zhí)行的SELECT語句的處理速度。
查詢緩存是基于效勞器所接收到的查詢字符串的文本內(nèi)容的。如果某些查詢的文本完全相同,那它就認(rèn)為這些查詢是相同的。如果某些查詢的字符不同,或者來自那些使用了不同的字符集或通訊協(xié)議的客戶端,那么它會認(rèn)為這些查詢是不同的。同樣,如果某些查詢采用其它的功能相當(dāng)、但實(shí)際上沒有指向相同的數(shù)據(jù)表〔例如引用了不同的數(shù)據(jù)庫中的同名數(shù)據(jù)表〕,那么它們也是不同的。
當(dāng)數(shù)據(jù)表被更新了之后,涉及到該數(shù)據(jù)表的任何緩存查詢都變成無效的,并且會被丟棄;這可以防止效勞器返回過期的結(jié)果。
在默認(rèn)情況下,MySQL對查詢緩存的支持是內(nèi)建的。如果你不希望使用這種緩存,并且想防止它所導(dǎo)致的性能開銷,可以使用--without-query-cache選項(xiàng)來運(yùn)行配置腳本建立效勞器。
關(guān)于查詢緩存的操作有一下幾個(gè)系統(tǒng)變量需要掌握:have_query_cache檢查效勞器是否支持查詢緩存使用語句:SHOWVARIABLESLIKE'have_query_cache';query_cache_type查詢緩存的操作模式它有三個(gè)模式值:
0:不要緩存查詢結(jié)果或檢索緩存的結(jié)果;
1:緩存查詢,除非它們以
SELECTSQL_NO_CACHE開頭;
2:根據(jù)需要只緩存那些以
SELECTSQL_CACHE開頭的query_cache_size決定分配給緩存的內(nèi)存數(shù)量,單位是字節(jié)說明:即使query_cache_type的值設(shè)置為零,query_cache_size指定內(nèi)存數(shù)量也會被分配。為了防止浪費(fèi)內(nèi)存,只有在希望激活緩存的時(shí)候才把大小設(shè)置成大于零。同時(shí),即使query_cache_type不為零,查詢緩存的大小設(shè)置為零也會禁用緩存。query_cache_limit設(shè)置被緩存的最大結(jié)果集大小,比這個(gè)值大的查詢結(jié)果不會被緩存說明:SELECTSQL_CACHE語句會讓查詢結(jié)果被緩存;SELECTSQL_NO_CACHE語句會使查詢結(jié)果不被緩存;它們并不會受到緩存模式的影響,前提是效勞器支持查詢緩存并分配了內(nèi)存大小。使用索引使用索引屬于優(yōu)化查詢的范疇,我把它單獨(dú)成章來講解,是為了突出它的重要性。
關(guān)于索引,我將以下面幾個(gè)方面來闡述:
(1)索引的工作原理
(2)索引的創(chuàng)立方式
(3)設(shè)計(jì)索引的要點(diǎn)
(4)控制MySQL對索引的使用
(5)正視使用索引的缺陷
(一)索引的工作原理
當(dāng)你在一張沒有索引的表里進(jìn)行某種查詢時(shí),效勞器會從表的第一行開始逐條進(jìn)行查找,即使在中間段就已經(jīng)找到了匹配的數(shù)據(jù)行,它仍然會繼續(xù)往下找,直到表尾。如果這張表的數(shù)據(jù)行數(shù)量很大,比方成千上萬條,那么,這種查詢肯定會耗去很大局部的時(shí)間。使用索引的表的查詢方式就不同,當(dāng)在某列上面使用索引后,該索引就包含了該列每行數(shù)值的有序排列和指向各自實(shí)際位置的"指針",查詢時(shí),效勞器不是逐行地查看數(shù)據(jù)表,而是首先掃描索引,掃描索引時(shí),也不必從索引頭進(jìn)行線性掃描,而是使用定位算法快速地找到第一條匹配的索引條目,由于索引是事先排序過的,所以,一旦發(fā)現(xiàn)了不匹配的記錄,就會終止對索引的掃描。通過索引便能夠快速地找到查找的數(shù)據(jù)行。
為什么索引能過快速地找到相應(yīng)的數(shù)據(jù)行呢?這是因?yàn)樗饕捎昧四撤N數(shù)據(jù)結(jié)構(gòu)進(jìn)行查找,不同的MySQL存儲引擎,索引采用的數(shù)據(jù)結(jié)構(gòu)也有所區(qū)別,對于MyISAM數(shù)據(jù)表,使用的是R樹索引,并且索引與數(shù)據(jù)使用單獨(dú)的文件存儲,即MYI與MYD文件;MEMORY(HEAP)存儲引擎使用hash索引,但也支持B-樹索引,其它的引擎大多使用B樹索引,只有MyISAM支持空間類型,使用了R樹。
舉例說明:現(xiàn)有三張表Table1,Table2,Table3,其中Name字段使用了索引,我們的查詢?nèi)蝿?wù)是查找出表1中在另外兩張表中都出現(xiàn)的的名字,查詢語句可能為:selectTable1.NamefromTable1,Table2,Table3whereTabl查詢流程如下列圖:
我們來比擬一下不使用索引與使用索引的查詢方式:
不使用索引時(shí),存儲引擎會掃描所有的數(shù)據(jù)行,即,如果每個(gè)表的行數(shù)都為1000行的情況下就得查找1000x1000x1000(10億!),可能是匹配記錄數(shù)量的上百萬倍,明顯的浪費(fèi)了大量的工作,導(dǎo)致性能下降;而使用索引時(shí),它的流程是這樣的:
(1)選擇表1中的第一行并查看該數(shù)據(jù)行的值.
(2)使用表2的索引,直接定位到與表1的值匹配的數(shù)據(jù)行;類似地,使用表3上的索引,直接定位到與表2的值匹配的數(shù)據(jù)行。
(3)處理表1的下一行并重復(fù)前面的過程。執(zhí)行這樣的操作直到t1中的所有數(shù)據(jù)行都被檢查過。
在這種情況下,我們?nèi)匀粚Ρ?執(zhí)行了完整的掃描,但是我們可以在表2和表3上執(zhí)行索引查找,從這些表中直接地獲取數(shù)據(jù)行。理論上采用這種方式運(yùn)行上面的查詢會快一百萬倍。
(二)創(chuàng)立索引的方式
索引有三種類型:
(1)主鍵索引,即primarykey,只能在創(chuàng)立表時(shí)創(chuàng)立;
(2)唯一值索引,即uniquekey,值不能重復(fù);
(3)普通索引,即key,值可以重復(fù)。
可以在創(chuàng)立表時(shí)就創(chuàng)立索引,方式為:[PRIMARY|UNIQUE]KEY(col_name);
比方:
createtablebook(
isbnintunsignednotnull,
titlevarchar(50)notnull,
authorchar(20)notnull,
uniquekeyisbn(isbn),
keyautor(author)
)engin=myisamdefaultcharset=utf8也可以在表創(chuàng)立完畢后創(chuàng)立索引:CREATE[UNIQUE]INDEXindex_nameONtable_name(col_name[(length)][,col_name[(lenght)]]);
比方:
createuniqueindexisbnonbook(isbn(5));
(三)設(shè)計(jì)索引時(shí)要考慮到的
1.索引所在列最好是出現(xiàn)在where,orderby等子句中的列,而不是出現(xiàn)在select關(guān)鍵字后選擇列表中的列,因?yàn)樗饕畲蟮奶攸c(diǎn)在于根據(jù)查詢條件快速定位到查詢的數(shù)據(jù)行中;
2.對于重復(fù)值少的列進(jìn)行索引,如果滿足查詢的結(jié)果占整個(gè)表記錄的30%以上時(shí)MySQL會自動放棄使用索引,所以這時(shí)你設(shè)置的索引并不能起到作用,比方你把一張表的性別字段設(shè)置為索引,那么,索引指向的數(shù)據(jù)行有可能是整個(gè)表數(shù)據(jù)行的50%,這是沒有意義的,何況這樣還會把時(shí)間浪費(fèi)在索引排序上;如果重復(fù)值少,索引指向的數(shù)據(jù)行范圍就會越窄,查詢速度就會大幅度加快。
3.利用短索引,即指定索引的前綴長度,例如,如果有一個(gè)CHAR(200)列,如果在前10個(gè)或20個(gè)字符內(nèi),多數(shù)值是惟一的,那么就不要對整個(gè)列進(jìn)行索引。對前10個(gè)或20個(gè)字符進(jìn)行索引能夠節(jié)省大量索引空間,也可能會使查詢更快。較小的索引涉及的磁盤I/O較少,較短的值比擬起來更快。更為重要的是,對于較短的鍵值,索引高速緩存中的塊能容納更多的鍵值。
4.不要過多地索引。不要認(rèn)為"索引越多,性能越高",不要對每個(gè)數(shù)據(jù)列都進(jìn)行索引。每個(gè)額外的索引都會花費(fèi)更多的磁盤空間,并降低寫操作的性能。當(dāng)你修改表的內(nèi)容的時(shí)候,索引就必須被更新,甚至可能重新整理。如果你的索引很少使用或永不使用,你就沒有必要減小表的修改操作的速度。此外,為檢索操作生成執(zhí)行方案的時(shí)候,MySQL會考慮采用哪一個(gè)索引,建立額外的索引會給查詢優(yōu)化器增加更多的工作量,如果索引太多,有可能〔未必〕出現(xiàn)MySQL選擇最優(yōu)索引失敗的情況,維護(hù)自己必須的索引可以幫助查詢優(yōu)化器來防止這類錯(cuò)誤。對于如何控制MySQL選擇最優(yōu)索引接下來我會談到。5.利用最左前綴。在創(chuàng)立一個(gè)n列的索引時(shí),實(shí)際是創(chuàng)立了MySQL可利用的n個(gè)索引。多列索引可起幾個(gè)索引的作用,因?yàn)榭衫盟饕凶钭筮叺牧屑瘉砥ヅ湫?。這樣的列集稱為最左前綴?!策@與索引一個(gè)列的前綴不同,索引一個(gè)列的前綴是利用該的前n個(gè)字符作為索引值?!忱绠?dāng)你準(zhǔn)備給索引過的表添加索引時(shí),你可以先考慮下將增加的索引是否是已有的多列索引的最左前綴,如果是這樣的,就不用再增加索引。
(四)控制MySQL對索引的使用
一般情況下,在查詢時(shí)MySQL將自己決定是否使用索引,使用哪一個(gè)索引。但在一些特殊情況下,我們希望MySQL只使用一個(gè)或幾個(gè)索引,或者不希望使用某個(gè)索引。這就需要使用MySQL的控制索引的一些查詢選項(xiàng)。
(1)限制使用索引的范圍:USEINDEX
有時(shí)我們在數(shù)據(jù)表里建立了很多索引,當(dāng)MySQL對索引進(jìn)行選擇時(shí),這些索引都在考慮的范圍內(nèi)。但有時(shí)我們希望MySQL只考慮幾個(gè)索引,而不是全部的索引,這就需要用到USEINDEX對查詢語句進(jìn)行設(shè)置;比方:SELECT*FROMTABLE1USEINDEX(FIELD1,FIELD2);這時(shí),無論在TABLE1中已經(jīng)建立了多少個(gè)索引,MySQL在選擇索引時(shí),只考慮在FIELD1和FIELD2上建立的索引。
(2)限制不使用索引的范圍:IGNOREINDEX
如果我們要考慮的索引很多,而不被使用的索引又很少時(shí),可以使用IGNOREINDEX進(jìn)行反向選取;比方:SELECT*FROMTABLE1IGNOREINDEX(FIELD1,FIELD2);這時(shí),TABLE1表中FIELD1和FIELD2上的索引不被使用。
(3)強(qiáng)迫使用某一個(gè)索引:FORCEINDEX
有時(shí)我們希望MySQL必須要使用某一個(gè)索引(由于MySQL在查詢時(shí)只能使用一個(gè)索引,因此只能強(qiáng)迫MySQL使用一個(gè)索引)。這就需要使用FORCEINDEX來完成這個(gè)功能;比方:SELECT*FROMTABLE1FORCEINDEX(FIELD1);這時(shí),只使用建立在FIELD1上的索引,而不使用其它字段上的索引。
(五)正視索引的缺陷
首先,索引加快了檢索的速度,但是減慢了插入和刪除的速度,同時(shí)還減慢了更新被索引的數(shù)據(jù)列中的值的速度。也就是說,索引減慢了大多數(shù)涉及寫操作的速度。發(fā)生這種現(xiàn)象的原因在于寫入一條記錄的時(shí)候不但需要寫入數(shù)據(jù)行,還需要改變所有的索引。數(shù)據(jù)表帶有的索引越多,需要做出的修改就越多,平均性能的降低程度也就越大;所以對于寫操作更頻繁而需檢索查詢很少的表,最好不要設(shè)置索引。
其次,索引會花費(fèi)磁盤空間,多個(gè)索引相應(yīng)地花費(fèi)更多的磁盤空間。這可能導(dǎo)致更快地到達(dá)數(shù)據(jù)表的大小限制.對于MyISAM表,頻繁地索引可能引起索引文件比數(shù)據(jù)文件更快地到達(dá)最大限制;對于BDB表,它把數(shù)據(jù)和索引值一起存儲在同一個(gè)文件中,添加索引引起這種表更快地到達(dá)最大文件限制;在InnoDB的共享表空間中分配的所有表都競爭使用相同的公共空間池,因此添加索引會更快地耗盡表空間中的存儲。但是,與MyISAM和BDB表使用的文件不同,InnoDB共享表空間并不受操作系統(tǒng)的文件大小限制,因?yàn)槲覀兛梢园阉渲贸墒褂枚鄠€(gè)文件。只要有額外的磁盤空間,你就可以通過添加新組件來擴(kuò)展表空間;使用單獨(dú)表空間的InnoDB表與BDB表受到的約束是一樣的,因?yàn)樗臄?shù)據(jù)和索引值都存儲在單個(gè)文件中;所以,如果你不需要使用特殊的索引幫助查詢執(zhí)行得更快,就不要建立索引。
到此,我們?yōu)椴樵儍?yōu)化與使用索引做一番總結(jié)
從上面的分析我們不難得出以下幾點(diǎn)優(yōu)化原那么:
第一:設(shè)置表的字段時(shí)要恰當(dāng),盡可能地減小字段占用空間;
第二:SQL查詢語句要采用優(yōu)化方式,并且防止對大宗量的數(shù)據(jù)段做無謂的檢索;
第三:使效勞器盡可能地從緩存區(qū)獲取數(shù)據(jù),少指向內(nèi)存或磁盤;
第四:合理地使用索引,可以極大地提高效勞器性能和查詢速度;
第五:對數(shù)據(jù)庫的操作,一定要注重優(yōu)化措施,特別是有大宗量的訪問時(shí)更是如此,當(dāng)然,關(guān)于優(yōu)化還有更多的細(xì)節(jié)需要我們掌握好。平安隱患數(shù)據(jù)庫的平安隱患來自多方面,比方權(quán)限設(shè)置不恰當(dāng),效勞器系統(tǒng)本身存在漏洞等等,下面我以SQL注入為例講解數(shù)據(jù)庫的平安隱患,以及如何采取防范措施。
什么是SQL注入?它是如何入侵?jǐn)?shù)據(jù)庫系統(tǒng)的?
首先用一個(gè)簡單的例如展示SQL如何注入的:如果程序員對用戶傳遞的數(shù)據(jù)沒有進(jìn)行處理,使用下面的查詢語句:$page=$_GET["p"];
$sql="select*fromtbwherepage_id='$page'";
...在正常輸入的情況下,用戶進(jìn)入查詢某條信息時(shí),地址欄可能是這樣的:這時(shí)你在該地址的后面參加SQL語句,比方簡單地輸入"and1=2",即地址欄里是這樣的:如果出現(xiàn)返回錯(cuò)誤信息的情況,就可以確定數(shù)據(jù)庫存在注入的漏洞,通過采取一系列有針對性的SQL盲注技術(shù),最終非法地獲取操控?cái)?shù)據(jù)庫系統(tǒng)的權(quán)限。
SQL注入是存在于常見的多連接的應(yīng)用程序中一種漏洞,攻擊者通過在應(yīng)用程序中預(yù)先定義好的查詢語句結(jié)尾加上額外的SQL語句元素,欺騙數(shù)據(jù)庫效勞器執(zhí)行非授權(quán)的任意查詢。這類應(yīng)用程序一般是網(wǎng)絡(luò)應(yīng)用程序,它允許用戶輸入查詢條件,并將查詢條件嵌入SQL請求語句中,發(fā)送到與該應(yīng)用程序相關(guān)聯(lián)的數(shù)據(jù)庫效勞器中去執(zhí)行。通過構(gòu)造一些畸形的輸入,攻擊者能夠操作這種請求語句去獲取預(yù)先未知的結(jié)果.
SQL注入攻擊利用的是SQL語法,這使得這種攻擊具有廣泛性。理論上說,對于所有基于SQL語言標(biāo)準(zhǔn)的數(shù)據(jù)庫軟件包括SQLServer,Oracle,MySQL,DB2,Informix等以及與之連接的網(wǎng)絡(luò)應(yīng)用程序包括Active/JavaServerPages,ColdFusionManagement,PHP或Perl等都是有效的。當(dāng)然各種軟件有自身的特點(diǎn),實(shí)際的攻擊代碼可能不盡相同。
SQL注入的一般步驟是這樣的:
第一步,首先像上述那樣簡單地在地址欄參加SQL語句判斷是否存在注入漏洞;
第二步,根據(jù)各種數(shù)據(jù)庫使用的SQL語句上的差異,如,不同的SQL效勞器連結(jié)字符串的語法不同,MSSQLServer使用符號"+"來連結(jié)字符串,Oracle使用符號"||"來連結(jié),MySQL使用符號".",進(jìn)行試探,得出數(shù)據(jù)庫的類型;
第三步,使用ORDERBY加數(shù)字的方式試探出字段數(shù),這是為了UNIONSELECT語句做準(zhǔn)備的;
第四步,通過ORDERBY得出字段數(shù)后,再用UNIONSELECT匹配字段數(shù)目n-1個(gè)NULL值,另外一個(gè)在字符,數(shù)值,時(shí)間類型的值里一一試探,直到可以確定每個(gè)字段的數(shù)據(jù)類型;
第五步,在明確了字段數(shù)與數(shù)據(jù)類型后,就可以大大地發(fā)揮UNIONSELECT語句的成效了,包括試探出管理員帳號,密碼所在表名字段名。
至于SQL注入的詳細(xì)過程我在此就點(diǎn)到為止了,我只是提醒網(wǎng)站開發(fā)程序員要注意對用戶傳遞過來的數(shù)據(jù)進(jìn)行嚴(yán)格的檢查,不能讓非法的語句成為SQL查詢條件的一局部。
防止SQL注入攻擊的防御手段
從上面談到的可以看出,SQL之所以能夠成功注入,就是讓注入者利用了SQL語法上的特點(diǎn)進(jìn)行攻擊的,如何讓傳遞的數(shù)據(jù)在SQL語句中平安使用,是我們采取防御手段的核心所在。
對此,我們可以從一下幾個(gè)方面防御SQL注入:
(1)在有必要的情況下,對提交的數(shù)據(jù)進(jìn)行客戶端與效勞器端兩重的的合法性檢驗(yàn),確保效勞器按我們指定的方式正常執(zhí)行;
(2)屏蔽出錯(cuò)信息,因?yàn)榇皱e(cuò)信息里大都包含了了一些重要信息,比方目錄,甚至與數(shù)據(jù)庫有關(guān)的信息都會因此出來;
(3)替換或刪除敏感的字符或字符串;
(4)對于潛在的而難以預(yù)料的錯(cuò)誤,比方可能是效勞器本身的問題,可以使用跳轉(zhuǎn)頁面的方式,以免因此暴露信息;
(5)對于PHP+MySQL,要充分利用好異常處理與錯(cuò)誤處理〔專題PHP對此做了講述〕.事務(wù)與鎖〔一〕事務(wù)(Transaction)
什么是事務(wù)?
事務(wù)〔transation〕指的是能夠使對數(shù)據(jù)庫的一系列操作,要么都成功,要么都失敗的一種機(jī)制。
事務(wù)有什么用?
它的作用就在于能夠保證彼此有制約有關(guān)聯(lián)的操作成為一個(gè)有機(jī)的整體,即使發(fā)生了錯(cuò)誤,或效勞器崩潰的情況下,也能保證數(shù)據(jù)庫一致的的狀態(tài)。舉個(gè)例子說明:最形象的例子莫過于轉(zhuǎn)賬時(shí)發(fā)生的情況,轉(zhuǎn)賬至少包括兩個(gè)操作,一個(gè)是從匯款人的卡里扣掉寄款,一個(gè)是收款人的卡要加上這個(gè)數(shù)目,如果由于某種原因,這其中有一個(gè)操作失敗了,可能就會造成比擬嚴(yán)重的后果,為了防止這單方面的失敗,我們就引入了事務(wù)這種機(jī)制,引入事務(wù)后,如果其中有一個(gè)操作失敗了,那么系統(tǒng)會自動回復(fù)到操作前的狀態(tài),也就是說,當(dāng)你的卡上匯出了款,而對方卡上又沒有增加款項(xiàng)時(shí),你卡上的款也不會少。
怎么創(chuàng)立事務(wù)?
在默認(rèn)狀態(tài)下,MySQL是使用自動提交(autocommit)的方式,也就是說,一旦有操作,它立刻就會執(zhí)行,并且不會有"撤銷"功能,因?yàn)樗呀?jīng)把執(zhí)行結(jié)果寫入物理磁盤上了。
為了實(shí)現(xiàn)事務(wù),首先就要取消自動提交的方式;當(dāng)然你可以先查看一下是否翻開了自動提交,語句為:select@@autocommit;如果返回值為非0,那么證明是自動提交方式,這時(shí)你可以使用:setautocommit=0;來關(guān)閉自動提交。
接著就開始啟動一個(gè)事務(wù):starttransation;
這時(shí)我們就可以寫入我們想要放到事務(wù)里的操作語句了。
比方:insertintotb1values(...);insertinto
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版智慧城市建設(shè)項(xiàng)目投資入股協(xié)議書范本3篇
- 2025年度工錢墊付與勞動保障政策執(zhí)行協(xié)議范本2篇
- 2025版國際能源合作習(xí)協(xié)議書3篇
- 2025版小麥種子進(jìn)出口貿(mào)易合同樣本3篇
- 2025年度個(gè)人房屋買賣綠色環(huán)保協(xié)議3篇
- 2025-2030全球一次性使用2D儲液袋行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025年全球及中國濕式無線遠(yuǎn)傳智能水表行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 2024年秋季江蘇七年級入學(xué)分班考試語文模擬卷2(解析版)
- 2024年煤礦安全生產(chǎn)知識競賽題庫及答案(共80題)
- 2025版新能源汽車租賃與保險(xiǎn)代理服務(wù)合同3篇
- JJF 2184-2025電子計(jì)價(jià)秤型式評價(jià)大綱(試行)
- GB/T 44890-2024行政許可工作規(guī)范
- 2024年安徽省中考數(shù)學(xué)試卷含答案
- 2025屆山東省德州市物理高三第一學(xué)期期末調(diào)研模擬試題含解析
- 2024年滬教版一年級上學(xué)期語文期末復(fù)習(xí)習(xí)題
- 兩人退股協(xié)議書范文合伙人簽字
- 2024版【人教精通版】小學(xué)英語六年級下冊全冊教案
- 汽車噴漆勞務(wù)外包合同范本
- 微項(xiàng)目 探討如何利用工業(yè)廢氣中的二氧化碳合成甲醇-2025年高考化學(xué)選擇性必修第一冊(魯科版)
- 廣東省廣州市黃埔區(qū)2024-2025學(xué)年八年級物理上學(xué)期教學(xué)質(zhì)量監(jiān)測試題
- 2024年重慶南開(融僑)中學(xué)中考三模英語試題含答案
評論
0/150
提交評論