3.9 MySQL不支持的功能
本節介紹其他數據庫中有而MySQL中無的功能。它介紹省略了什麼功能,以及在需要這些功能時怎麼辦。一般情況下, MySQL之所以忽略某些功能是因為它們有負面性能影響。有的功能正在開發者的計劃清單上,一旦找到一種方法可以實現相應的功能而又不致於影響
良好性能的目標,就會對它們進行實現。
■ 子選擇。子選擇是嵌套在另一個SELECT 語句內的SELECT 語句,如下面的查詢所示:
SELECT * FROM score
WHERE event_id IN (SELECT event_id FROM event WHERE type = "T")
子選擇打算在MySQL3.24 中給出,到那時它們就不會忽略了。但到那時,許多用子選擇撰寫的查詢也可以用連接來編寫。請參閱3 . 8 . 1節“將子選擇編寫為連接”。
■ 事務處理和提交/回退。事務處理是由其他客戶機作為一個整體不中斷執行的一組SQL語句。提交/回退功能允許規定數條語句作為一個整體執行或不執行。即,如果事務處理中的任何一條語句失敗,那麼直到該語句前執行的所有語句的作用都被撤消。
ySQL 自動進行單一SQL 語句的同步以免客戶機互相干擾。(例如,兩個客戶機不能對相同的表進行同時寫入。)此外,可利用LOCK TABLES 和UNLOCK TABLES將數條語句組成一個整體,這使您能夠完成單條語句的並發控制所不能滿足的操作。MySQL與事務處理有關的問題是,它不能自動對數條語句進行組織,而且如果這些語句中有某一條失敗後也不能對它們進行回退。
為了弄清事務處理為什麼有用,可舉例說明。假如您在服裝銷售業工作,無論何時,只要您的銷售人員進行了一次銷售,都要更新庫存數目。下面的例子說明了在多個銷售人員同時更新數據庫時可能出現的問題(假如初始的襯衫庫存數目為4 7):
t1銷售人員1賣出3件襯衫
t2 銷售人員檢索當前襯衫計數( 4 7):
SELECT quantity FROM inventory WHERE item = "shirt"
t3 銷售人員2賣出2件襯衫
t4 銷售人員2檢索當前襯衫計數( 4 7)
SELECT quantity FROM inventory WHERE item = "shirt"
t5 銷售人員1計算庫存的新數目為47 - 3 = 44 並設置襯衫計數為44:
UPDATE inventory SET quantity = 44 WHERE item = "shirt"
t6 銷售人員2計算庫存的新數目為47 - 2 = 45 並設置襯衫計數為45:
UPDATE inventory SET quantity = 45 WHERE item = "shirt"
在這個事件序列結束時,您已經賣掉了5 件襯衫,但庫存數目卻是45 而不是4 2。問題是如果在一條語句中查看庫存而在另一條語句中更新其值,這是一個多語句的事務處理。第二條語句中所進行的活動取決於第一條語句中檢索出的值。但是如果在重疊的時間范圍內出現獨立的事務處理,則每個事務處理的語句會糾纏在一起,並且互相干擾。在事務處理型的數據庫中,每個銷售人員的語句可作為一個事務處理執行,這樣,銷售人員2 的語句在銷售人員1的語句完成之前不會被執行。在MySQL中,可用兩種方法達到這個目的:
■ 方法1:作為一個整體執行一組語句。可利用LOCK TABLES 和UNLOCK TABLES將語句組織在一起,並將它們作為一個原子單元執行:鎖住所需使用的表,發布查詢,然後釋放這些鎖。這樣阻止了其他人在您鎖住這些表時使用它們。利用表同步,庫存情況如下所示:
t1銷售人員1賣出3件襯衫
t2 銷售人員1請求一個鎖並檢索當前襯衫計數(47)
LOCK TABLES inventory WRITE
SELECT quantity FROM inventory WHERE item = "shirt"
t3 銷售人員2賣出2件襯衫
t4 銷售人員2試圖取得一個鎖:這被阻塞,因為銷售人員1已經占住了鎖:
LOCK TABLES inventory WRITE
t5 銷售人員1計算庫存的新數目為47 - 3 = 44 並設置襯衫計數為44,然後釋放鎖:
UPDATE inventory SET quantity = 44 WHERE item = "shirt"
UNLOCK TABLES
t6 現在銷售人員2的鎖請求成功。銷售人員2檢索當前襯衫計數( 44)
SELECT quantity FROM inventory WHERE item = "shirt"
t7 銷售人員2計算庫存的新數目為44 - 2 = 42,設置襯衫計數為4 2,然後釋放鎖:
UPDATE inventory SET quantity = 42 WHERE item = "shirt"