MySQL存儲引擎,優化,事務

1惟一約束unique和主鍵key的區別?
 
 

一、什麼是數據的存儲引擎?mysql

      存儲引擎就是如何存儲數據、如何爲存儲的數據創建索引和如何更新、查詢數據等技術的實現方法。由於在關係數據庫中數據的存儲是以表的形式存儲的,因此存儲引擎也能夠稱爲表類型(即存儲和操做該表的類型),在Oracle和SQL Server等數據庫中只有一種存儲引擎,全部數據存儲管理機制都是同樣的。而MySQL數據庫提供了多種存儲引擎。用戶能夠根據不一樣的需求爲數據表選擇不一樣的存儲引擎,用戶也能夠根據本身的需求編寫本身的存儲引擎。
MySql中有哪些存儲引擎?
      1 MyISAM:這種引擎是mysql最先提供的。這種引擎又能夠分爲靜態MyISAM、動態MyISAM 和壓縮MyISAM三種:
    靜態MyISAM:若是數據表中的各數據列的長度都是預先固定好的,服務器將自動選擇這種表類型。由於數據表中每一條記錄所佔用的空間都是同樣的,因此這種表存取和更新的效率很是高。當數據受損時,恢復工做也比較容易作。
    動態MyISAM:若是數據表中出現varchar、xxxtext或xxxBLOB字段時,服務器將自動選擇這種表類型。相對於靜態MyISAM,這種表存儲空間比較小,但因爲每條記錄的長度不一,因此屢次修改數據後,數據表中的數據就可能離散的存儲在內存中,進而致使執行效率降低。同時,內存中也可能會出現不少碎片。所以,這種類型的表要常常用optimize table 命令或優化工具來進行碎片整理。
    壓縮MyISAM:以上說到的兩種類型的表均可以用myisamchk工具壓縮。這種類型的表進一步減少了佔用的存儲,可是這種表壓縮以後不能再被修改。另外,由於是壓縮數據,因此這種表在讀取的時候要先時行解壓縮。
    可是,無論是何種MyISAM表,目前它都不支持事務,行級鎖和外鍵約束的功能。
    2 MyISAM Merge引擎:這種類型是MyISAM類型的一種變種。合併表是將幾個相同的MyISAM表合併爲一個虛表。常應用於日誌和數據倉庫。
    3 InnoDB:InnoDB表類型能夠看做是對MyISAM的進一步更新產品,它提供了事務、行級鎖機制和外鍵約束的功能。
    4 memory(heap):這種類型的數據表只存在於內存中。它使用散列索引,因此數據的存取速度很是快。由於是存在於內存中,因此這種類型常應用於臨時表中。
    5 archive:這種類型只支持select 和 insert語句,並且不支持索引。常應用於日誌記錄和聚合分析方面。
二、 各類存儲引擎特性比較:

在實際工做中,選擇一個合適的存儲引擎是一個很複雜的問題。每種存儲引擎都有各自的優點,不能籠統的說誰比誰更好。下面將詳解不一樣環境常常用到的存儲引擎和針對各個存儲引擎的特色進行對比,給出不一樣的選擇建議。web

  • InnoDB存儲引擎

InnoDB是Mysql數據庫的一種存儲引擎。InnoDB給Mysql的表提供了 事務、回滾、崩潰修復能力、多版本併發控制的事務安全、間隙鎖(能夠有效的防止幻讀的出現)、支持輔助索引、聚簇索引、自適應hash索引、支持熱備、行級鎖。還有InnoDB是Mysql上惟一一個提供了外鍵約束的引擎。sql

InnoDB存儲引擎中,建立的表的表結構是單獨存儲的而且存儲在.frm文件中。數據和索引存儲在一塊兒的而且存儲在表空間中。可是默認狀況下mysql會將數據庫的全部InnoDB表存儲在一個表空間中的。其實這種方式管理起來很是的不方便並且還不支持高級功能因此建議每一個表存儲爲一個表空間實現方式爲:使用服務器變量innodb_file_per_table = 1。數據庫

若是須要頻繁的進行更新、刪除操做的數據庫也可選擇InnoDB存儲引擎。由於該存儲引擎能夠實現事務提交和回滾。緩存

  • MyISAM存儲引擎

MyISAM存儲引擎是Mysql中常見的存儲引擎,MyISAM存儲引擎是基於ISAM存儲引擎發展起來的。MyISAM支持全文索引、壓縮存放、空間索引(空間函數)、表級鎖、延遲更新索引鍵。可是MyISAM不支持事務、行級鎖、更沒法忍受的是崩潰後不能保證徹底恢復(只能手動修復)。安全

MyISAM存儲引擎的表存儲成3個文件。文件的名字和表的名字相同。擴展名包含frm、MYD、MYI。其中frm爲擴展名的文件存儲表的結構;MYD爲擴展名的文件存儲數據,其是MYData的縮寫;MYI爲擴展名的文件存儲索引,其爲MYIndex的縮寫。服務器

MyISAM存儲引擎的插入數據很快,空間和內存使用比較低。若是表主要是用於插入新記錄和讀出記錄,那麼選擇MyISAM存儲引擎可以實現處理的高效率。若是應用的完整性、併發性要求很低,也能夠選擇MyISAM存儲引擎。網絡

  • ARCHIVE

ARCHIVE,見名之意可看出是歸檔,因此歸檔以後不少的高級功能就再也不支持了僅支持插入(insert)和查詢(select)兩種功能, ARCHIVE存儲引擎以前還不支持索引(在Mysql5.5之後開始支持索引了),可是它擁有很好的壓縮機制。一般用於作倉庫使用。數據結構

ARCHIVE存儲引擎適用於存儲日誌信息或其餘按時間序列實現的數據採集類的應用場景中。併發

  • CSV

CSV是將數據文件保存爲CSV格式的的文件的,能夠方便的導入到其餘數據庫中去(例如:excel表格,SQLserver等等),由此須要在數據庫間自由共享數據時才偶爾建議使用此存儲引擎。而且它也不支持索引;我的認爲僅適用於數據交換。

  • BLACKHOLE

BLACKHOLE叫作黑洞,也就是說沒有存儲機制,任何數據都會被丟棄,可是會記錄二進制日誌。通常在Mysql複製(中繼服務器)中常常用到,這個在Mysql複製博客中將詳細介紹,敬請關注。

  • FEDERATED

FEDERATED能夠實現跨服務器整理表,簡單說就是它能夠訪問遠程服務器上數據的存儲引擎,因此說它再也不本地建立數據只會自動的創建一個鏈接到其餘服務器上連接,有點相似於代理的功能,默認都是禁用的。

  • MEMORY存儲引擎

MEMORY存儲引擎是Mysql中的一類特殊的存儲引擎。其使用存儲在內存中的內存來建立表,並且全部數據保存在內存中。數據安全性很低,可是查找和插入速度很快。若是內存出現異常就會影響到數據的完整性,若是重啓或關機,表中的全部數據就會丟失,所以基於MEMORY存儲引擎的表的生命週期很短,通常都是一次性的。適用於某些特殊場景像查找和映射,緩存週期性的聚合數據等等。

  • MRG_MYISAM

MRG_MYISAM存儲引擎是合併MyISAM表的,就是將多個MyISAM合併爲一個(在用戶看來是一個進行工做,實際上是多個底層物理文件在運行工做)。


鎖定

  數據庫引擎中的鎖定功能決定了如何管理信息的訪問和更新。當數據庫中的一個對象爲信息更新鎖定了,在更新完成以前,其它處理不能修改這個數據(在某些狀況下還不容許讀這種數據)。

  鎖定不只影響許多不一樣的應用程序如何更新數據庫中的信息,並且還影響對那個數據的查詢。這是由於查詢可能要訪問正在被修改或者更新的數據。總的來講,這種延遲是很小的。大多數鎖定機制主要是爲了防止多個處理更新同一個數據。因爲向數據中插入信息和更新信息這兩種狀況都須要鎖定,你能夠想象,多個應用程序使用同一個數據庫可能會有很大的影響。

  不一樣的存儲引擎在不一樣的對象級別支持鎖定,並且這些級別將影響能夠同時訪問的信息。獲得支持的級別有三種:表鎖定、塊鎖定和行鎖定。支持最多的是表鎖定,這種鎖定是在MyISAM中提供的。在數據更新時,它鎖定了整個表。這就防止了許多應用程序同時更新一個具體的表。這對應用不少的多用戶數據庫有很大的影響,由於它延遲了更新的過程。

  頁級鎖定使用Berkeley DB引擎,而且根據上載的信息頁(8KB)鎖定數據。當在數據庫的不少地方進行更新的時候,這種鎖定不會出現什麼問題。可是,因爲增長几行信息就要鎖定數據結構的最後8KB,當須要增長大量的行,也別是大量的小型數據,就會帶來問題。

  行級鎖定提供了最佳的並行訪問功能,一個表中只有一行數據被鎖定。這就意味着不少應用程序可以更新同一個表中的不一樣行的數據,而不會引發鎖定的問題。只有InnoDB存儲引擎支持行級鎖定。

 

*修改存儲引擎,能夠用命令Alter table tableName engine =engineName

假如,若須要將表user的存儲引擎修改成archive類型,則可以使用命令alter table user engine=archive。

*建立數據庫表時設置存儲存儲引擎的基本語法是:
Create table tableName(
columnName(列名1)  type(數據類型)  attri(屬性設置),
columnName(列名2)  type(數據類型)  attri(屬性設置),
……..) engine = engineName

事物:

 

何爲數據庫事務 「一榮俱榮,一損俱損」這句話很能體現事務的思想,不少複雜的事物要分步進行,但它們組成一個總體,要麼總體生效,要麼總體失效。這種思想反映到數據庫上,就是多個SQL語句,要麼全部執行成功,要麼全部執行失敗。 數據庫事務有嚴格的定義,它必須同時知足四個特性:原子性(Atomic)、一致性(Consistency)、隔離性(Isolation)和持久性(Durabiliy),簡稱爲ACID。下面是對每一個特性的說明: 1. 原子性:表示組成一個事務的多個數據庫操做是一個不可分隔的原子單元,只有全部的操做執行成功,整個事務才提交,事務中任何一個數據庫操做失敗,已經執行的任何操做都必須撤銷,讓數據庫返回到初始狀態; 2. 一致性:事務操做成功後,數據庫所處的狀態和它的業務規則是一致的,即數據不會被破壞。如從A帳戶轉帳100元到B帳戶,無論操做成功與否,A和B的存款總額是不變的; 3. 隔離性:在併發數據操做時,不一樣的事務擁有各自數據空間,它們的操做不會對對方產生干擾。準確的說,並不是要求作到徹底無干擾,數據庫規定了多種事務隔離級別,不一樣隔離級別對應不一樣的干擾程度,隔離級別越高,數據一致性越好,但併發性越弱; 4. 持久性:一旦事務提交成功後,事務中全部的數據操做都必須被持久化到數據庫中,即便提交事務後,數據庫立刻崩潰,在數據庫重啓時,也必須能保證可以經過某種機制恢復數據。
在這些事務特性中,數據「一致性」是最終目標,其它的特性都是爲達到這個目標的措施、要求或手段。 數據庫管理系統通常採用重執行日誌保證原子性、一致性和持久性,重執行日誌記錄了數據庫變化的每個動做,數據庫在一個事務中執行一部分操做後發生錯誤退出,數據庫便可以根據重執行日誌撤銷已經執行的操做。此外,對於已經提交的事務,即便數據庫崩潰,在重啓數據庫時也可以根據日誌對還沒有持久化的數據進行相應的重執行操做。
和Java程序採用對象鎖機制進行線程同步相似,數據庫管理系統採用數據庫鎖機制保證事務的隔離性。當多個事務試圖對相同的數據進行操做時,只有持有鎖的事務才能操做數據,直到前一個事務完成後,後面的事務纔有機會對數據進行操做。Oracle數據庫還使用了數據版本的機制,在回滾段爲數據的每一個變化都保存一個版本,使數據的更改不影響數據的讀取。

數據併發的問題     一個數據庫可能擁有多個訪問客戶端,這些客戶端均可以併發方式訪問數據庫。數據庫中的相同數據可能同時被多個事務訪問,若是沒有采起必要的隔離措施,就會致使各類併發問題,破壞數據的完整性。這些問題能夠歸結爲5類,包括3類數據讀問題(髒讀、幻象讀和不可重複讀)以及2類數據更新問題(第一類丟失更新和第二類丟失更新)。下面,咱們分別經過實例講解引起問題的場景。

髒讀(dirty read)     在講解髒讀前,咱們先講一個笑話:一個有結巴的人在飲料店櫃檯前轉悠,老闆很熱情地迎上來:「喝一瓶?」,結巴連忙說:「我…喝…喝…」,老闆麻利地打開易拉罐遞給結巴,結巴終於憋出了他的那句話:「我…喝…喝…喝不起啊!」。在這個笑話中,飲料店老闆就對結巴進行了髒讀。 A事務讀取B事務還沒有提交的更改數據,並在這個數據的基礎上操做。若是恰巧B事務回滾,那麼A事務讀到的數據根本是不被認可的。來看取款事務和轉帳事務併發時引起的髒讀場景:

時間 轉帳事務A 取款事務B
T1   開始事務
T2 開始事務  
T3       查詢帳戶餘額爲1000元    
T4          取出500元把餘額改成500元
T5 查詢帳戶餘額爲500元(髒讀)  
T6   撤銷事務餘額恢復爲1000元
T7 匯入100元把餘額改成600元  
T8 提交事務  

在這個場景中,B但願取款500元然後又撤銷了動做,而A往相同的帳戶中轉帳100元,就由於A事務讀取了B事務還沒有提交的數據,於是形成帳戶白白丟失了500元。在Oracle數據庫中,不會發生髒讀的狀況。

不可重複讀(unrepeatable read)    不可重複讀是指A事務讀取了B事務已經提交的更改數據。假設A在取款事務的過程當中,B往該帳戶轉帳100元,A兩次讀取帳戶的餘額發生不一致:

 

時間 取款事務A 轉帳事務B
T1   開始事務
T2 開始事務                           
T3                                查詢帳戶餘額爲1000元     
T4 查詢帳戶餘額爲1000元                           
T5                    取出100元把餘額改成900元
T6   提交事務                  
T7 查詢帳戶餘額爲900元(和T4讀取的不一致)  

在同一事務中,T4時間點和T7時間點讀取帳戶存款餘額不同。

幻象讀(phantom read)     A事務讀取B事務提交的新增數據,這時A事務將出現幻象讀的問題。幻象讀通常發生在計算統計數據的事務中,舉一個例子,假設銀行系統在同一個事務中,兩次統計存款帳戶的總金額,在兩次統計過程當中,恰好新增了一個存款帳戶,並存入100元,這時,兩次統計的總金額將不一致:   若是新增數據恰好知足事務的查詢條件,這個新數據就進入了事務的視野,於是產生了兩個統計不一致的狀況。

幻象讀和不可重複讀是兩個容易混淆的概念,前者是指讀到了其它已經提交事務的新增數據,然後者是指讀到了已經提交事務的更改數據(更改或刪除),爲了不這兩種狀況,採起的對策是不一樣的,防止讀取到更改數據,只須要對操做的數據添加行級鎖,阻止操做中的數據發生變化,而防止讀取到新增數據,則每每須要添加表級鎖——將整個表鎖定,防止新增數據(Oracle使用多版本數據的方式實現)。 第一類丟失更新      A事務撤銷時,把已經提交的B事務的更新數據覆蓋了。這種錯誤可能形成很嚴重的問題,經過下面的帳戶取款轉帳就能夠看出來:      

時間 取款事務A 轉帳事務B
T1 開始事務  
T2   開始事務
T3 查詢帳戶餘額爲1000元      
T4   查詢帳戶餘額爲1000元
T5   匯入100元把餘額改成1100元
T6   提交事務
T7 取出100元把餘額改成900元  
T8 撤銷事務  
T9 餘額恢復爲1000元(丟失更新)  

A事務在撤銷時,「不當心」將B事務已經轉入帳戶的金額給抹去了。

第二類丟失更新  A事務覆蓋B事務已經提交的數據,形成B事務所作操做丟失:  

時間 轉帳事務A 取款事務B
T1   開始事務
T2 開始事務                          
T3                 查詢帳戶餘額爲1000元    
T4 查詢帳戶餘額爲1000元                          
T5   取出100元把餘額改成900元
T6   提交事務           
T7 匯入100元  
T8 提交事務  
T9 把餘額改成1100元(丟失更新)  

    上面的例子裏因爲支票轉帳事務覆蓋了取款事務對存款餘額所作的更新,致使銀行最後損失了100元,相反若是轉帳事務先提交,那麼用戶帳戶將損失100元。

數據庫鎖機制      數據併發會引起不少問題,在一些場合下有些問題是容許的,但在另一些場合下可能倒是致命的。數據庫經過鎖的機制解決併發訪問的問題,雖然不一樣的數據庫在實現細節上存在差異,但原理基本上是同樣的。      按鎖定的對象的不一樣,通常能夠分爲表鎖定和行鎖定,前者對整個表進行鎖定,然後者對錶中特定行進行鎖定。從併發事務鎖定的關係上看,能夠分爲共享鎖定和獨佔鎖定。共享鎖定會防止獨佔鎖定,但容許其它的共享鎖定。而獨佔鎖定既防止其它的獨佔鎖定,也防止其它的共享鎖定。爲了更改數據,數據庫必須在進行更改的行上施加行獨佔鎖定,INSERT、UPDATE、DELETE和SELECT FOR UPDATE語句都會隱式採用必要的行鎖定。下面咱們介紹一下ORACLE數據庫經常使用的5種鎖定:  行共享鎖定:通常經過SELECT FOR UPDATE語句隱式得到行共享鎖定,在Oracle中你也能夠經過LOCK TABLE IN ROW SHARE MODE語句顯式得到行共享鎖定。行共享鎖定並不防止對數據行進行更改的操做,可是能夠防止其它會話獲取獨佔性數據表鎖定。容許進行多個併發的行共享和行獨佔性鎖定,還容許進行數據表的共享或者採用共享行獨佔鎖定;  行獨佔鎖定:經過一條INSERT、UPDATE或DELETE語句隱式獲取,或者經過一條LOCK TABLE IN ROW EXCLUSIVE MODE語句顯式獲取。這個鎖定能夠防止其它會話獲取一個共享鎖定、共享行獨佔鎖定或獨佔鎖定;  表共享鎖定:經過LOCK TABLE IN SHARE MODE語句顯式得到。這種鎖定能夠防止其它會話獲取行獨佔鎖定(INSERT、UPDATE或DELETE),或者防止其它表共享行獨佔鎖定或表獨佔鎖定,它容許在表中擁有多個行共享和表共享鎖定。該鎖定可讓會話具備對錶事務級一致性訪問,由於其它會話在你提交或者回溯該事務並釋放對該表的鎖定以前不能更改這個被鎖定的表;  表共享行獨佔:經過LOCK TABLE IN SHARE ROW EXCLUSIVE MODE語句顯式得到。這種鎖定能夠防止其它會話獲取一個表共享、行獨佔或者表獨佔鎖定,它容許其它行共享鎖定。這種鎖定相似於表共享鎖定,只是一次只能對一個表放置一個表共享行獨佔鎖定。若是A會話擁有該鎖定,則B會話能夠執行SELECT FOR UPDATE操做,但若是B會話試圖更新選擇的行,則須要等待;  l 表獨佔:經過LOCK TABLE IN EXCLUSIVE MODE顯式得到。這個鎖定防止其它會話對該表的任何其它鎖定。 
事務隔離級別      儘管數據庫爲用戶提供了鎖的DML操做方式,但直接使用鎖管理是很是麻煩的,所以數據庫爲用戶提供了自動鎖機制。只要用戶指定會話的事務隔離級別,數據庫就會分析事務中的SQL語句,而後自動爲事務操做的數據資源添加上適合的鎖。此外數據庫還會維護這些鎖,當一個資源上的鎖數目太多時,自動進行鎖升級以提升系統的運行性能,而這一過程對用戶來講徹底是透明的。      ANSI/ISO SQL 92標準定義了4個等級的事務隔離級別,在相同數據環境下,使用相同的輸入,執行相同的工做,根據不一樣的隔離級別,能夠致使不一樣的結果。不一樣事務隔離級別可以解決的數據併發問題的能力是不一樣的。          表 1 事務隔離級別對併發問題的解決狀況 

隔離級別 髒讀
不可
重複讀
幻象讀 第一類丟失更新 第二類丟失更新
READ UNCOMMITED 容許 容許 容許 不容許 容許
READ COMMITTED 不容許 容許 容許 不容許 容許
REPEATABLE READ 不容許 不容許 容許 不容許 不容許
SERIALIZABLE 不容許 不容許 不容許 不容許 不容許

    事務的隔離級別和數據庫併發性是對立的,二者此增彼長。通常來講,使用READ UNCOMMITED隔離級別的數據庫擁有最高的併發性和吞吐量,而使用SERIALIZABLE隔離級別的數據庫併發性最低。
    SQL 92定義READ UNCOMMITED主要是爲了提供非阻塞讀的能力,Oracle雖然也支持READ UNCOMMITED,但它不支持髒讀,由於Oracle使用多版本機制完全解決了在非阻塞讀時讀到髒數據的問題並保證讀的一致性,因此,Oracle的READ COMMITTED隔離級別就已經知足了SQL 92標準的REPEATABLE READ隔離級別。
    SQL 92推薦使用REPEATABLE READ以保證數據的讀一致性,不過用戶能夠根據應用的須要選擇適合的隔離等級。 JDBC對事務的支持      並非全部的數據庫都支持事務,即便支持事務的數據庫也並不是支持全部的事務隔離級別,你能夠經過Connection# getMetaData()方法獲取DatabaseMetaData對象,並經過該對象的supportsTransactions()、supportsTransactionIsolationLevel(int level)方法查看底層數據庫的事務支持狀況。Connection默認狀況下是自動提交的,也即每條執行的SQL都對應一個事務,爲了可以將多條SQL當成一個事務執行,必須先經過Connection#setAutoCommit(false)阻止Connection自動提交,並可經過Connection#setTransactionIsolation()設置事務的隔離級別,Connection中定義了對應SQL 92標準4個事務隔離級別的常量。經過Connection#commit()提交事務,經過Connection#rollback()回滾事務。下面是典型的JDBC事務數據操做的代碼:     代碼清單 1 JDBC事務代碼

Connection conn ; try{ conn = DriverManager.getConnection();①獲取數據鏈接 conn.setAutoCommit(false); ②關閉自動提交的機制 conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); ③設置事務隔離級別 Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate( "INSERT INTO t_topic VALUES(1,’tom’) " ); rows = stmt.executeUpdate( "UPDATE t_user set topic_nums = topic_nums +1 "+"WHERE user_id = 1"); conn.commit();④提交事務 }catch(Exception e){ … conn.rollback();⑤提交事務 }finally{ … }
 
  

     在JDBC 2.0中,事務最終只能有兩個操做:要麼提交要麼回滾。可是,有些應用可能須要對事務進行更多的控制,而不是簡單地提交或回滾。JDBC 3.0(JDK 1.4及之後的版本)引入了一個全新的保存點特性,Savepoint 接口容許你將事務分割爲多個階段,你能夠指定回滾到事務的特定保存點,而非象JDBC 2.0同樣只回滾到開始事務的點,如圖 1所示:

                                                                                圖 1 帶Savepoint的事務 

    下面的代碼使用了保存點的功能,在發生特定問題時,回滾到指定的保存點,則非回滾整個事務,如代碼清單 2所示:  代碼清單 2使用保存點的事務代碼

… Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate( "INSERT INTO t_topic VALUES(1,’tom’) " ); Savepoint svpt = conn.setSavepoint("savePoint1");①設置一個保存點 rows = stmt.executeUpdate( "UPDATE t_user set topic_nums = topic_nums +1 "+"WHERE user_id = 1"); … conn.rollback(svpt); ②回滾到①處的savePoint1,①以前的SQL操做,在整個事務提交後依然提交,但①到②之間的SQL操做被撤銷了 … conn.commit();③提交事務
 
  

    並不是全部數據庫都支持保存點功能,你能夠經過DatabaseMetaData#supportsSavepoints()方法查看是否支持。
小結      數據一致性和訪問的併發性二者之間的最佳平衡永遠是數據庫應用程序開發所追求的終極目錄。數據事務是保證數據訪問一致性的不二法門,使用API進行數據庫事務應用開發時,必須深入瞭解事務控制屬性對應用性能和數據一致性二者的影響,並根據項目實際須要進行合理的設置。

 
 
存儲過程:存儲過程是SQL語句和控制語句的預編譯集合,以一個名稱存儲並做爲一個單元處理,存儲過程其實是存儲在數據庫內,能夠經過應用程序經過調用來執行,存儲過程能夠包括程序流、邏輯和對數據的查詢,它能夠接受參數,並存在多個返回值,它的效率比SQL語句高,覺得他只有在第一次進行語法分析和編譯,之後客戶端再次調用,直接調用編譯結果就能夠啦,因此它的效率比較高。
 優勢:加強SQL語句的功能和靈活性(由於在存儲過程當中能夠寫控制語句)。
           實現較快的執行速度。
           減小網絡流量(由於他經過參數傳遞,能夠減小傳送數據,因此相對應的減小了網絡流量)。
建立存儲過程:
          
     
存儲過程經過call來調用。
 
什麼叫存儲引擎
     MySQL能夠講數據以不一樣的技術存儲在文件或內存中,這種技術就叫存儲引擎。每一種存儲引擎數用不一樣的存儲機制,索引技巧,鎖定水平,最終提供普遍切不一樣的功能。
 
併發控制:當多個鏈接對記錄進行操做時保證數據的一致性和完整性。
 
鎖(是爲了解決併發問題)
   共享鎖(讀鎖):在同一時間段內,多個用戶能夠讀取同一個資源,讀取過程當中數據不會發生任何變化。
    排他鎖(寫鎖):在任什麼時候候只能有一個用戶寫入資源,當進行寫鎖時會阻塞其餘的讀鎖或者寫鎖操做。
鎖的力度(即所得顆粒)
      ---表鎖,是一種開銷最小的鎖策略。當用戶針對數據表操做時,用戶得到了這張表的寫鎖權限,寫鎖會禁止其餘用戶對這張表的讀寫操做。
      ---行鎖,是一種開銷最大的鎖策略。也是支持最大併發處理的一種策略。(對數據表的每一行都加鎖,因此它的開銷最大)
 
索引:是對數據表中一列或多列的值進行排序的一種結構。可快速定位。就至關於書的目錄。
修改存儲引擎的方法:
  1. 經過修改MySQL配置文件實現,在MySQL5.5中默認的存儲引擎是innoDB.
  2.  經過建立數據表命令實現:
           --create table table_name(
             、、、
              )ENGINE=engine;
 3.經過修改數據表命令實現
      --alter table table_name ENGINE[=] engine_name;
 
MySQL數據庫的優化
   數據庫優化的目的:
          一、避免出現頁面訪問錯誤(
                          因爲數據庫鏈接timeout產生的5XX錯誤
                          因爲慢查詢形成頁面沒法加載
                          因爲阻塞形成數據沒法提交)
          二、 增長數據庫的穩定性(不少數據庫問題都是因爲低低效查詢引發的)
          三、優化用戶體驗(
                 流暢頁面的訪問速度
                  良好的網站功能體
   能夠從如下幾個方面進行優化:SQL及索引,數據表結構,系統配置,硬件。其中SQL及索引最重要,首先咱們要根據咱們的需求寫出結構良好的SQL,另外要根據SQL在表中創建有效的索引,可是若是咱們的索引過多,不但會影響咱們寫入的效率,同時還會影響咱們查詢的效率,因此索引創建要適量有效。可是若是表結構設計不合理,咱們就很難寫出結構良好的SQL,因此要創建簡潔明瞭的表結構,因此說在設計表結構的時候,咱們要考慮怎樣對錶結構進行查詢,怎樣的表結構的設計纔是有利於表結構的查詢,而後是系統配置的優化,可是當前咱們大多數的MySQL都是在lnuix系統上,可是系統上是有一些自己的限制,好比說:TCP/IP鏈接數的限制,打開文件數的限制和一些安全上的限制,由於MySQL查詢是基於文件的,沒查詢一個表就要打開一個文件,若是文件數達到必定的限制,這個文件就沒法打開。硬件優化,就是咱們要選擇更適合數據庫的CPU,更快的IO,以及更多的內存,數據庫數據要放在內存中查詢修改,因此內存越大,對咱們數據庫的性能就越好,但CPU卻不是這樣的,CPU越大,不見得對數據庫性能越好,由於SQL會對CPU的可數有限制,好比說他並不會用到太多的核數,有的查詢他只用於單核,因此說CUP也對數據庫有影響,並非核數越多越好,而IO,目前因爲多新型IO設備,如 ssd,,但它並不能減小數據庫鎖的機制,由於鎖是數據庫保存完整性的一種機制,雖然IO很快,但它並不能減小阻塞,因此咱們說硬件上的優化是成本最高但效果最差的,因此說若是慢查詢不少,阻塞不少,那麼併發量就會上去,致使應用響應緩慢。
 
1.SQL及索引的優化:
    對Max(),Count()函數的優化,子查詢的優化,group by 的優化(目的是減小IO),limit優化(使用有索引的列或主鍵進行orderby操做以免IO)
 
     a. 如何選擇合適的列創建索引:
            在where從句,group by, order by,on從句中出現的列創建索引;索引字段越小越好;離散度大的列放到聯合索引的前面。
       b.索引的維護及優化------重複及冗餘索引和對不用索引的刪除
 2.數據庫結構的優化
    a. 選擇合適的數據類型,數據類型的選擇,重點在於合適,
     
     b.表的範式化和反範式化(範式化指的是表設計的規則) 
         反範式化是指爲了查詢效率的考慮把本來符合第三範式的表適當的增長冗餘,已達到優化效率的目的,反範式化是以空間換時間的作法。
     c.表的垂直拆分,解決了表的寬度問題。將不經常使用的字段拆分出來。
     d.表的水平拆分,解決表的數據量過大的問題。
3.系統配置的優化。及MySQL配置文件的優化   
 
SQL語句;
 
查找:select
       
別名:AS
     select id AS userId,username AS uname From users;
查詢結果分組:group by
   select sex from users group by sex;
  分組條件:HAVING +聚合函數、或者是having後的字段出如今select後面。
    select age,sex from users group by sex HAVING age>2;
  對分組結果進行排序:order by    DESC 表示降序 默認爲ASC升序
      select * from users order by id DESC; 
限制查詢結果返回的數量:limit
    select * from users LIMIT 2;/LIMIT 2,2 (指的是從第三條開始,限制2條)
插入insert:
    insert test(username) select username from users where age>27;
更新:update
子查詢:(not)in,(not)exists
向單表插入:insert table_user1(username) select age from table_user2 group by age;
鏈接類型:inner join,內鏈接
              在MySQL中,join,cross join 和 inner join 是等價的。
       left [outer] join,左外鏈接
       right [outer] join,右外鏈接
   select username,age,sex 
   inner join  user2;
函數:
select CONCAT(username,age) AS u FROM user;//字符串連接
聚合函數:Avg(),Count(),Max(),Min(),Sum()
加密函數:MD5(),Password()
相關文章
相關標籤/搜索