目錄
MySQLR軟件提供了十分快速的多線程、多用戶、牢靠的SQL(結構化查詢語言)資料庫伺服器。 MySQL伺服器定位於任務關鍵型、重負荷生產系統,並能嵌入在大量部署的軟件中。MySQL是MySQL AB的註冊商標。
MySQL軟件採用雙授權方式。用戶可根據GNU通用公共授權(http://www.fsf.org/licenses/)條款,將MySQL軟件作為開放原始碼產品使用,或從MySQL AB公司購買標準的商業授權證。關於我方授權策略的更多訊息,請參見http://www.mysql.com/company/legal/licensing/。
在下面的清單中,介紹了本手冊感興趣的一些特殊部分。關於MySQL資料庫伺服器的討論,請參見1.4.2 「MySQL的的主要特性」。
關於安裝說明,請參見第2章:安裝MySQL。
關於從5.0版向上升級的更多訊息,請參見2.10.1節,「從5.0版升級」。
關於MySQL資料庫伺服器的教程說明,請參見第3章:教程。
關於SQL示範和標準程式訊息,請參見標準程式目錄(在本發佈版中,為sql-bench)。
關於新特性和問題更正的歷史訊息,請參見附錄D:MySQL變更史。
關於當前已知問題和錯誤特性的列資料表,請參見A.8 「MySQL中的已知事宜」。
關於未來計劃,請參見1.6 「MySQL發展大事記」。
關於本項目所有貢獻人的清單,請參見 附錄C:感謝。
重要說明:
請將錯誤報告(通常稱為問題)以及問題和評論發送到http://bugs.mysql.com。請參見1.7.1.3 「如何通報問題和問題」。如果在MySQL伺服器中發現敏感的安全問題,請使用電子郵件立刻通知我們:security@mysql.com。
這是關於5.1版至5.1.2-alpha版MySQL資料庫系統的參考手冊。該手冊不適用於舊版本MySQL軟件,這是因為在MySQL 5.1和以前的版本存在很多功能性差異和其他差異。如果正在使用MySQL軟件的較舊版本,請參閱MySQL 5.0參考手冊,該手冊涵蓋了MySQL 5.0,或參閱MySQL 4.1參考手冊,該手冊涵蓋了MySQL 3.22、3.23、4.0和4.1系列。在手冊的文本中,通過引用發佈版本號(5.1.x),註明了MySQL 5.1的二級版本。
由於本手冊是作為參考手冊而編製的,在本手冊中未提供關於SQL或關聯資料庫概念的一般說明。在本手冊中,也不包含如何使用作業系統或命令行解釋器方面的訊息。
MySQL資料庫軟件始終在發展,參考手冊也會相應地頻繁更新。本手冊的最新版本以線上方式提供,請使用http://dev.mysql.com/doc/上的搜索資料表單。也提供多重其他格式,包括HTML、PDF、和Windows CHM版本。
主要文檔是DocBook XML檔案的集合。對於HTML版本和其他格式,它們是使用DocBook XSL stylesheets自動生成的。
如果您有任何關於本手冊應增加內容或更正內容方面的建議,請將其發送給文檔編製團隊:docs@mysql.com。
本手冊最初是由David Axmark和Michael 「Monty」 Widenius編製的。由MySQL文檔編製團隊負責維護,團隊成員包括Paul DuBois、Stefan Hinz、Mike Hillyer和Jon Stephens。關於中多其他貢獻人,請參見附錄C:感謝。本手冊的版權歸瑞典公司MySQL AB所有。MySQLR和MySQL徽標均是MySQL AB的註冊商標。本手冊中引用的其他商標和註冊商標是相應所有人的財產,在本手冊中僅將其用於辨識目的。
· 這類風格的文本用於SQL語句,資料庫、資料表和列名稱,C和Perl代碼,以及環境變數。例如: 要想重新加載授權資料表,請使用FLUSH PRIVILEGES語句。
這類風格的文本用於指明鍵入的數如訊息。
· 這類風格的文本用於指明可執行程式和指令的名稱,例如mysql(MySQL命令行客戶端程式)和mysqld(MySQL伺服器執行程式)。
· 這類風格的文本用於變數輸入,應使用您選擇的值替換它。
· 檔案名和目錄名採取下述方式: 「全程my.cnf位於目錄/etc下」。
· 字元序列採取下述方式: 「要想使用通配符,請使用字元%」。
· 這類風格的文本用於強調。
· 這類風格的文本用於資料表頭,並用於傳遞強調訊息。
當出現準備在特定程式中執行的命令時,該程式將由位於命令前的提示符指明。例如,shell>指明命令將從註冊外殼程式中執行,mysql>指明命令將從mysql客戶端程式中執行:
shell> type a shell command here(在此輸入shell命令)
mysql> type a mysql statement here(在此輸入mysql語句)
「shell」是命令解釋程式。在Unix平台上,它通常是程式,如sh、csh或bash。在Windows平台下,等效程式為command.com或cmd.exe,通常運行在控制台窗口中。
輸入示範中顯示的命令或語句時,不要輸入示範中給出的提示符。
資料庫、資料表和;列名必須代入語句中。為了指明該代入是必要的,在本手冊中使用了db_name、tbl_name和col_name。例如,您將見到如下所示的語句:
mysql> SELECT col_name FROM db_name.tbl_name;
這意味著,如果您輸入了類似的語句,應提供您的資料庫、資料表和列名,如下例所示:
mysql> SELECT author_name FROM biblio_db.author_list;
SQL關鍵字不區分大小寫,因此即可為大寫也可為小寫。在本手冊中採用大寫。
在語法介紹中,方括號(「[」和「]」)用於指明可選字或子句。例如,在下面的語句中,IF EXISTS是可選的:
DROP TABLE [IF EXISTS] tbl_name
當某一語法成分由多個可選項組成時,可選項應用豎線「|」分開。當可能選擇一組選擇中的某一成員時,可選項將列在方括號(「[」和「]」)中。
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
當必須選擇一組選擇中的某一成員時,可選項將列在大括號(「{」和「}」)中。
{DESCRIBE | DESC} tbl_name [col_name | wild]
省略號(…)表明省略了語句的某一選擇,通常是為了提供複雜語法的簡短資料表述。例如,INSERT ... SELECT是後跟SLECT語句的INSERT語句的簡短形式。
省略號還能指明語句的前部分語法元素可重複。在下面的示範中,可給定多個reset_option值,第1個值後每一個可由逗號分開:
RESET reset_option [,reset_option] ...
對於用來設置shell變數的命令,採用Bourne shell語法給出。例如,用於設置環境變數的序列和運行命令的序列,與下述Bourne shell語法給出的類似:
shell> VARNAME=value some_command
如果您正在使用csh或tcsh,必須使用略有不同的命令。應執行與下例所示類似的序列:
shell> setenv VARNAME value
shell> some_command
MySQL AB是由MySQL創始人和主要開發人創辦的公司。MySQL AB最初是由David Axmark、Allan Larsson和Michael「Monty」Widenius在瑞典創辦的。
我們致力於開發MySQL資料庫軟件,並向新用戶宣傳推廣它。MySQL AB擁有MySQL源代碼、MySQL徽標和(註冊)商標、以及本手冊的版權。請參見這些核心價值取向規定了MySQL AB與MySQL伺服器軟件的協作方式:
· 成為世界上最好和使用最廣泛的資料庫。
· 面向所有人,而且所有人均能支付得起。
· 使用簡單。
· 在保持快速和安全的同時不斷改進。
· 使用和改進充滿樂趣。
· 不存在問題。
這就是MySQL AB公司及其僱員的核心價值取向。
· 我們同意開放原始碼理念,並支援開放原始碼群。
· 我們的目標是成為最佳公民。
· 我們傾向於那些與我們有共同價值取向和思想傾向的合作夥伴。
· 我們將回復電子郵件並提供支援。
· 我們是一家與其他方聯繫在一起的「虛擬」公司。
· 我們反對軟件專利。
在MySQL的網站(http://www.mysql.com/)上,給出了關於MySQL和MySQL的最新訊息。
順便提及一下,公司名中的「AB」是瑞典語「aktiebolag」或「股份公司」的首字母縮寫。可將其翻譯為「MySQL有限公司」。事實上,MySQL有限公司和MySQLGmbH均是MySQL AB子公司的名稱。它們分別位於美國和德國。MySQL是最流行的開放原始碼SQL資料庫管理系統,它是由MySQL AB公司開發、發佈並支援的。MySQL AB是由多名MySQL開發人創辦的一家商業公司。它是一家第二代開放原始碼公司,結合了開放原始碼價值取向、方法和成功的商業模型。
在MySQL的網站(http://www.mysql.com/)上,給出了關於MySQL和MySQL的最新訊息。
· MySQL是一種資料庫管理系統。
資料庫是數據的結構化集合。它可以是任何東西,從簡單的購物清單到畫展,或企業網絡中的海量訊息。要想將數據新增到資料庫,或訪問、處理計算機資料庫中保存的數據,需要使用資料庫管理系統,如MySQL伺服器。計算機是處理大量數據的理想工具,因此,資料庫管理系統在計算方面扮演著關鍵的中心角色,或是作為獨立的實用工具,或是作為其他應用程式的組成部分。
MySQL是一種關聯資料庫管理系統。
關聯資料庫將數據保存在不同的資料表中,而不是將所有數據放在一個大的倉庫內。這樣就增加了速度並提高了靈活性。MySQL的SQL指得是「結構化查詢語言」。SQL是用於訪問資料庫的最常用標準化語言,它是由ANSI/ISO SQL標準定義的。SQL標準自1986年以來不斷演化發展,有數種版本。在本手冊中,「SQL-92」指得是1992年發佈的標準,「SQL:1999」指得是1999年發佈的標準,「SQL:2003」指得是標準的當前版本。我們採用術語「SQL標準」標示SQL標準的當前版本。
MySQL軟件是一種開放原始碼軟件。
「開放原始碼」意味著任何人都能使用和改變軟件。任何人都能從Internet下載MySQL軟件,而無需支付任何費用。如果願意,您可以研究原始碼並進行恰當的更改,以滿足您自己的需求。MySQL軟件採用了GPL(GNU通用公共授權證),http://www.fsf.org/licenses/,定義了在不同情況下可以用軟件作的事和不可作的事。如果您對GPL不滿意,或需要在商業應用程式中嵌入MySQL代碼,可從我方購買商業授權版本。更多訊息,請參見MySQL授權概述(http://www.mysql.com/company/legal/licensing/)。
MySQL資料庫伺服器具有快速、可靠和易於使用的特點。
如果它正是您所尋找的,不妨一試。MySQL伺服器還有一套實用的特性集合,這些特性是通過與我們用戶的密切合作而開發的。在我們的基準測試主頁上,給出了MySQL伺服器和其他資料庫管理器的比較結果。請參見7.1.4 「MySQL基準套件」。
MySQL伺服器最初是為處理大型資料庫而開發的,與已有的解決方案相比,它的速度更快,多年以來,它已成功用於眾多要求很高的生產環境。儘管MySQL始終在不斷發展,但目前MySQL伺服器已能提供豐富和有用的功能。它具有良好的連通性、速度和安全性,這使的MySQL十分適合於訪問Internet上的資料庫。
MySQL伺服器工作在客戶端/伺服器模式下,或嵌入式系統中。
MySQL資料庫軟件是一種客戶端/伺服器系統,由支援不同後端的1個多線程SQL伺服器,數種不同的客戶端程式和庫,眾多管理工具和廣泛的應用編程接口API組成。
我們還能以嵌入式多線程庫的形式提供MySQL伺服器,您可以將其連結到您的應用程式,從而獲得更小、更快、和更易管理的產品。
有大量可用的共享MySQL軟件。
您所喜歡的應用程式和語言均支援MySQL資料庫伺服器,這種情況十分可能。
「MySQL」的正式發音是「My Ess Que Ell」(而不是「my sequel」),但我們並不介意您的發音方式是「my sequel」或其他當地方式。
我們最初的出發點是,使用mSQL來連接我們的資料表,這類資料表採用了我們的快速低層面(ISAM)子程式。然而,經過一些測試後,我們得出結論,mSQL的速度或靈活性不足以滿足我們的要求。其結果是,為我們的資料庫提供了新的SQL接口,但API接口與mSQL的幾乎一樣。設計該API的目的在於,允許將為mSQL編寫的第三方代碼方便地移植到MySQL。
MySQL名稱的起源不明。10多年來,我們的基本目錄以及大量庫和工具均採用了前綴「my」。不過,共同創辦人Monty Widenius的女兒名字也叫「My」。時至今日,MySQL名稱的起源仍是一個迷,即使對我們也一樣。
MySQL Dolphin(我方徽標)的名稱為「Sakila」,它是由MySQL AB公司的創辦人從用戶在「Dolphin命名」比賽中提供的眾多建議中選定的。該名稱是由來自非洲斯威士蘭的開放原始碼軟件開發人Ambrose Twebaze提出的。根據Ambrose的說法,按斯威士蘭的本地語言,女性化名稱Sakila源自SiSwati。Sakila也是坦桑尼亞、Arusha地區的一個鎮的鎮名,靠近Ambrose的母國烏干達。下面介紹了MySQL資料庫軟件的一些重要特性。關於當前特性和即將提供特性的更多訊息,,請參見1.6節,「MySQL發展大事記」 。
· 內部構件和可移植性
o 使用C和C++編寫
o 用眾多不同的編譯器進行了測試
o 能夠工作在眾多不同的平台上。請參見2.1.1 「MySQL支援的作業系統」。
o 使用GNU Automake、Autoconf和Libtool進行移植。
o 提供了用於C、C++、Eiffel、Java、Perl、PHP、Python、Ruby和Tcl的API。請參見第25章:API和庫。
o 採用核心線程的完全多線程 如果有多個CPU,它能方便地使用這些CPU。
o 提供了事務性和非事務性儲存引擎。
o 使用了極快的「B樹」磁盤資料表(MyISAM)和索引壓縮。
o 新增另一個儲存引擎相對簡單。如果打算為內部資料庫新增一個SQL接口,該特性十分有用。
o 極快的基於線程的內存分配系統。
o 通過使用最佳化的「單掃瞄多連接」,能實現極快的連接。
o 儲存器中的哈希資料表用作臨時資料表。
o SQL函數是使用高度最佳化的類庫實現的,運行很快。通常,在完成查詢初始化後,不存在儲存器分配。
o 採用Purify(商業內存溢出檢測器)以及GPL工具Valgrind(http://developer.kde.org/~sewardj/)測試了MySQL代碼。
o 伺服器可作為單獨程式運行在客戶端/伺服器聯網環境下。它也可作為庫提供,可嵌入(連結)到獨立的應用程式中。這類應用程式可單獨使用,也能在網絡環境下使用。
列類型
眾多列類型: 帶符號/無符號整數,1、2、3、4、8字節長,FLOAT,DOUBLE,CHAR,VARCHAR,TEXT,BLOB,DATE,TIME,DATETIME,TIMESTAMP,YEAR,SET,ENUM,以及OpenGIS空間類型。請參見第11章:列類型。
定長和可變長度記錄。
語句和函數
在SELECT和查詢的WHERE子句中,提供完整的操作符和函數支援。例如:
mysql> SELECT CONCAT(first_name, ' ', last_name) -> FROM citizen -> WHERE income/dependents > 10000 AND age > 30;
對SQL GROUP BY和ORDER BY子句的全面支援。支援聚合函數(COUNT(), COUNT(DISTINCT ...),AVG(),STD(),SUM(),MAX(),MIN()和GROUP_CONCAT())。
支援LEFT OUTER JOIN和RIGHT OUTER JOIN,採用標準的SQL和ODBC語法。
按照標準SQL的要求,支援資料表別名和列別名。
DELETE、INSERT、REPLACE和UPDATE返回更改(影響)的行數。連接到伺服器時,可通過設置標誌返回匹配的行數。
MySQL的SHOW命令可用於檢索關於資料庫、資料庫引擎、資料表和索引的訊息。EXPLAIN命令可用於確定最佳化器處理查詢的方式。
函數名與資料表名或列名不衝突。例如,ABS是有效的列名。唯一的限制在於,使用函數時,函數名和隨後的符號「(」之間不得有空格。請參見9.6 「MySQL中保留字的處理」。
可以將不同資料庫的資料表混合在相同的查詢中(就像MySQL 3.22中那樣)。
安全
十分靈活和安全的權限和密碼系統,允許基於主機的驗證。連接到伺服器時,所有的密碼傳輸均採用加密形式,從而保證了密碼安全。
可伸縮性和限制
處理大型資料庫: 我們使用了MySQL伺服器和含5千萬條記錄的資料庫。我們還聽說,有些用戶將MySQL用於含60000個資料表和約50億行的資料庫。
每個資料表可支援高達64條索引(在MySQL 4.1.2之前為32條)。每條索引可由1~16個列或列元素組成。最大索引寬度為1000字節(在MySQL 4.1.2之前為500)。索引可使用具備CHAR、VARCHAR、BLOB或TEXT列類型的列前綴。
連接性
在任何平台上,客戶端可使用TCP/IP協議連接到MySQL伺服器。在Windows系統的NT系列中(NT、2000、XP或2003),客戶端可使用命名管道進行連接。在Unix系統中,客戶端可使用Unix域套接字檔案建立連接。
在MySQL 4.1和更高的版本中,如果是以「--shared-memory」選項開始,Windows伺服器還支援共享內存連接。客戶端可使用「--protocol=memory」選項,通過共享內存建立連接。
Connector/ODBC (MyODBC)接口為使用ODBC(開放式資料庫連接性)連接的客戶端程式提供了MySQL支援。例如,可以使用MS Access連接到您的MySQL伺服器。客戶端可運行在Windows或Unix平台上。提供了MyODBC源。支援所有的ODBC 2.5函數,以及眾多其他函數。請參見第26章:連接器。
Connector/J接口為使用JDBC連接的Java客戶端程式提供了MySQL支援。客戶端可運行在Windows或Unix平台上。提供了Connector/J原始碼。請參見第26章:連接器。
本地化
伺服器可使用多種語言向客戶端提供錯誤消息。請參見5.10.2節,「設置錯誤消息語言」。
對數種不同字元編碼的全面支援,包括latin1 (cp1252)、german、big5、ujis等。例如,在資料表名和列名中允許使用斯堪的納維亞字元『a』、『a』和『o』。從MySQL 4.1開始,提供了Unicode支援。
所有數據均以所選的字元編碼保存。正常字串列的比較不區分大小寫。
分類是根據所選的字元編碼(預設情況下,使用瑞典校對)進行的。啟動MySQL伺服器時,可更改該項設置。要想查看高級分類的示範,請參見Czech分類代碼。MySQL伺服器支援眾多不同的字元編碼,這類字元編碼可在編譯時和運行時指定。
客戶端和工具
MySQL伺服器提供了對SQL語句的內部支援,可用於檢查、最佳化和修復資料表。通過mysqlcheck客戶端,可在命令行上使用這類語句。MySQL還包括myisamchk,這是一種很快的命令行實用工具,可用於在MyISAM資料表上執行這類操作。請參見第5章:資料庫管理。
對於所有MySQL程式,均能通過「-help」或「-?」選項使用,以獲取聯機幫助訊息。
本節回答了如下問題:「MySQL伺服器有多穩定?」,以及「在本項目中我能依靠MySQL伺服器嗎」? 我們將嘗試闡明這類問題,並回答很多潛在用戶關心的某些重要問題。本節所給出的訊息基於通過郵件列資料表收集的數據,在確定問題和通報使用類型方面,郵件列資料表十分有用。
最初的代碼可回溯至20世紀80年代初。它提供了穩定的編碼基數,最初儲存引擎使用的ISAM資料表格式仍保持向後相容性。在MySQL AB公司的前身TcX,自1996年中期以來,MySQL代碼在多個項目中工作良好,未出現任何問題。當MySQL資料庫軟件首次向更廣泛的公眾發佈時,我們的用戶很快發現了一些未經測試的代碼段。自那以後,儘管每個新版本具有很多新的特性,但每次新發佈的版本均存在少量的移植性問題。
每次發佈的MySQL伺服器均是可用的。僅當用戶嘗試源自「灰色區域」的代碼時才會出現問題。當然,新用戶不瞭解「灰色區域」是什麼。因此,在本節中,我們介紹了目前已知的這類區域。本節所作的介紹主要針對MySQL伺服器3.23版和更高版本。在最新的版本中,更正了所有已知和通報的問題,但「問題」一節所列的除外,這類問題與設計有關。請參見A.8節,「MySQL中的已知事宜」。
MySQL伺服器採用了多層設計和獨立模塊。在此列出了一些較新的模塊,並指明了它們的測試情況。
· Replication(穩定)
大量使用複製功能的伺服器均處於生產模式下,結果良好。在MySQL 5.x中,將繼續增強複製功能。
· InnoDB資料表(穩定)
自3.23.49版以來,InnoDB事務儲存引擎一直很穩定。InnoDB正用於大型、重負荷生產系統。
· BDB資料表(穩定)
Berkeley DB碼十分穩定,但在MySQL伺服器中,我們仍在改進BDB事務儲存引擎。
· 全文本搜索(穩定)
全文本搜索的使用範圍十分廣泛。在MySQL 4.0和4.1中,增加了重要的特性增強。
· MyODBC 3.51(穩定)
MyODBC 3.51採用了ODBC SDK 3.51,並廣泛用於生產活動中。某些出現的情況看上去與應用程式相關,與ODBC驅動程式或底層資料庫伺服器無關。
MySQL 3.22限制的資料表大小為4GB。由於在MySQL 3.23中使用了MyISAM儲存引擎,最大資料表尺寸增加到了65536TB(2567 – 1字節)。由於允許的資料表尺寸更大,MySQL資料庫的最大有效資料表尺寸通常是由作業系統對檔案大小的限制決定的,而不是由MySQL內部限制決定的。
InnoDB儲存引擎將InnoDB資料表保存在一個資料表空間內,該資料表空間可由數個檔案建立。這樣,資料表的大小就能超過單獨檔案的最大容量。資料表空間可包括原始磁盤分區,從而使得很大的資料表成為可能。資料表空間的最大容量為64TB。
在下面的資料表格中,列出了一些關於作業系統檔案大小限制的示範。這僅是初步指南,並不是最終的。要想瞭解最新訊息,請參閱關於作業系統的文檔。
作業系統 |
檔案大小限制 |
Linux 2.2-Intel 32-bit |
2GB (LFS: 4GB) |
Linux 2.4+ |
(using ext3 filesystem) 4TB |
Solaris 9/10 |
16TB |
NetWare w/NSS filesystem |
8TB |
win32 w/ FAT/FAT32 |
2GB/4GB |
win32 w/ NTFS |
2TB(可能更大) |
MacOS X w/ HFS+ |
2TB |
在Linux 2.2平台下,通過使用對ext2檔案系統的大檔案支援(LFS)補丁,可以獲得超過2GB的MyISAM資料表。在Linux 2.4平台下,存在針對ReiserFS的補丁,可支援大檔案(高達2TB)。目前發佈的大多數Linux版本均基於2.4內核,包含所有所需的LFS補丁。使用JFS和XFS,petabyte(千兆兆)和更大的檔案也能在Linux上實現。然而,最大可用的檔案容量仍取決於多項因素,其中之一就是用於儲存MySQL資料表的檔案系統。
關於Linux中LFS的詳細介紹,請參見Andreas Jaeger的「Linux中的大檔案支援」頁面:http://www.suse.de/~aj/linux_lfs.html。
Windows用戶請注意: FAT和VFAT (FAT32)不適合MySQL的生產使用。應使用NTFS。
在預設情況下,MySQL建立的MyISAM資料表允許的最大尺寸為4GB。您可以使用SHOW TABLE STATUS語句或myisamchk -dv tbl_name檢查資料表的最大尺寸。請參見13.5.4節,「SHOW語法」。
如果需要使用大於4GB的MyISAM資料表(而且您的作業系統支援大檔案),可使用允許AVG_ROW_LENGTH和MAX_ROWS選項的CREATE TABLE語句。請參見13.1.5節,「CREATE TABLE語法」。建立了資料表後,也可以使用ALTER TABLE更改這些選項,以增加資料表的最大允許容量。請參見13.1.2節,「ALTER TABLE語法」。
處理MyISAM資料表檔案大小的其他方式:
· 如果您的大資料表是只讀的,可使用myisampack壓縮它。myisampack通常能將資料表壓縮至少50%,因而,從結果上看,可獲得更大的資料表。此外,myisampack還能將多個資料表合併為1個資料表。請參見8.2節,「myisampack:生成壓縮、只讀MyISAM資料表」。
· MySQL包含一個允許處理MyISAM資料表集合的MERGE庫,這類MyISAM資料表具有與單個MERGE資料表相同的結構。請參見15.3節,「MERGE儲存引擎」。
MySQL伺服器本身不存在2000年(Y2K)相容性問題:
· MySQL伺服器採用了Unix的時間功能,對於TIMESTAMP值,可處理的日期至2037年。對於DATE和DATETIME值,可接受的日期可至9999年。
· 所有的MySQL日期函數均是在1個源檔案sql/time.cc中實現的,並經過了恰當編碼以確保2000年安全。
· 在MySQL 3.22和以後的版本中,YEAR列類型能夠在1個字節內保存0年以及1901~2155年,並能使用兩位或四位數字顯示它們。所有的兩位數字年份均被視為介於1970~2069年之間,這意味著,如果您在YEAR列中保存了01,MySQL伺服器會將其當作2001年。
通過下面的簡單演示示範,表明MySQL伺服器在處理直至9999年的DATE或DATETIME值方面不存在問題,在處理2030年以前的TIMESTAMP值方面也不存在問題:
mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE y2k (date DATE,
-> date_time DATETIME,
-> time_stamp TIMESTAMP);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO y2k VALUES
-> ('1998-12-31','1998-12-31 23:59:59',19981231235959),
-> ('1999-01-01','1999-01-01 00:00:00',19990101000000),
-> ('1999-09-09','1999-09-09 23:59:59',19990909235959),
-> ('2000-01-01','2000-01-01 00:00:00',20000101000000),
-> ('2000-02-28','2000-02-28 00:00:00',20000228000000),
-> ('2000-02-29','2000-02-29 00:00:00',20000229000000),
-> ('2000-03-01','2000-03-01 00:00:00',20000301000000),
-> ('2000-12-31','2000-12-31 23:59:59',20001231235959),
-> ('2001-01-01','2001-01-01 00:00:00',20010101000000),
-> ('2004-12-31','2004-12-31 23:59:59',20041231235959),
-> ('2005-01-01','2005-01-01 00:00:00',20050101000000),
-> ('2030-01-01','2030-01-01 00:00:00',20300101000000),
-> ('2040-01-01','2040-01-01 00:00:00',20400101000000),
-> ('9999-12-31','9999-12-31 23:59:59',99991231235959);
Query OK, 14 rows affected (0.01 sec)
Records: 14 Duplicates: 0 Warnings: 2
mysql> SELECT * FROM y2k;
+------------+---------------------+----------------+
| date | date_time | time_stamp |
+------------+---------------------+----------------+
| 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 |
| 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 |
| 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 |
| 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 |
| 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 |
| 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 |
| 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 |
| 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 |
| 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 |
| 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 |
| 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 |
| 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 |
| 2040-01-01 | 2040-01-01 00:00:00 | 00000000000000 |
| 9999-12-31 | 9999-12-31 23:59:59 | 00000000000000 |
+------------+---------------------+----------------+
14 rows in set (0.00 sec)
最後2個TIMESTAMP列的值為0,這是因為年份值(2040,9999)超出了TIMESTAMP的最大範圍。TIMESTAMP數據類型用於保存當前時間,在32位機器上,支援的取值範圍是19700101000000~20300101000000(帶符號值)。在64位機器上,TIMESTAMP能處理的值達2106(無符號值)。
儘管MySQL伺服器本身不存在2000年安全問題,但如果使用了存在Y2K問題的應用程式,也會遇到問題。例如,很多早期的應用程式採用2位數值(兩可性)而不是4位數值來保存和處理年份數據。這類問題可能會被使用「00」或「99」的應用程式合併為「丟失」值指示符。很不幸,這類問題或許很難更正,這是因為不同的應用程式是由不同的程式員編寫的,每位程式員可能使用了不同的慣例集和日期處理函數。
因此,儘管MySQL伺服器不存在Y2K問題,但應用程式須提供無歧義的輸入值。關於MySQL伺服器在處理含2位年份數值的兩可性日期輸入數據方面的作用,請參見11.3.4節,「Y2K事宜和日期類型」 。
MaxDB是一種大型高效的企業資料庫。資料庫管理通過了SAP認證。
MaxDB是資料庫管理系統的新名稱,以前稱為SAP DB。2003年,SAP AG和MySQL AB確立了合作夥伴關係,並將資料庫系統重命名為MaxDB。自此以後,MaxDB的開發一直由SAP開發者團隊負責,就像以前那樣。
MySQL AB與MaxDB團隊在SAP處保持著密切的合作,以不斷改進MaxDB產品。兩者的聯合努力包括:開發新的固有驅動程式,以便能夠在開發原始碼社區中更有效地使用MaxDB,並不斷改善各種文檔,以拓展MaxDB的用戶基數。此外,MySQL和MaxDB資料庫的協同性也被視為一項重要因素,例如,新的MaxDB同步管理器支援從MaxDB到MySQL的數據同步。
MaxDB資料庫管理系統和MySQL資料庫管理系統未共享公用編碼基數。MaxDB和MySQL資料庫管理系統是由MySQL AB公司提供的獨立產品。
MySQL AB為MaxDB提供了全面的專業服務組合。MaxDB是兼容ANSI SQL-92(入門級)、由SAP AG提供的關聯資料庫管理系統(RDBMS),也可由MySQL AB提供。MaxDB能夠滿足企業級應用的要求: 安全性,可伸縮性,高度並行性,以及強大的性能。它能運行在所有主要的作業系統下。多年的經歷表明,它能運行,並能在24x7的運作中運行數以TB計的數據。
資料庫開發是於1977年在柏林技術大學作為一個研究項目開始的。在20世紀80年代早期,它發展成為資料庫產品,隨後歸Nixdorf、Siemens Nixdorf、Software AG所有,目前歸SAP AG所有。在這一發展歷程中,它先後被命名為VDN、Reflex、Supra 2、DDB/4、Entire SQL-DB-Server和ADABAS D。1997年,SAP從軟件AP手中接管了該軟件,並將其重新命名為SAP DB。自2000年10月起,依GNU通用公共授權的名義發佈了眾多的SAP DB原始碼(請參見附錄J:GNU通用公共許可)。
2003年,SAP AG和MySQL AB確立了合作夥伴關係,並將資料庫系統重命名為MaxDB。MaxDB的歷史可追溯至SAP DB、SAP AG的DBMS,也就是說,MaxDB是SAP DB的重命名和增強版本。多年來,MaxDB已成功用於mySAP業務套件的小型、中性和大型安裝實例,以及需要企業級DBMS的其他要求苛刻的SQL應用(涉及用戶數、事務工作量、以及資料庫的大小)。
除了第三方資料庫系統外,如Oracle、Microsoft SQL Server以及IBM DB2,SAP DB意味著另一種選擇。2000年10月,SAP AG依 GNU GPL授權(請參見附錄J:GNU通用公共許可)發佈了SAP DB,從而使得其成為開放原始碼軟件。
目前,MaxDB已被世界各地約3500個SAP客戶使用。不僅如此,在SAP的IT部門內,大多數安裝在Unix和Linux平台上的DBMS均依賴於MaxDB。MaxDB正轉向重負荷聯機事務處理(OLTP),用戶數以千計,資料庫的大小從數百GB到數TB。
2003年,SAP和MySQL確立了合作夥伴關係,並達成了開發合作協議。作為其結果,自7.5版發佈以來(2003年11月),SAP的資料庫系統SAP DB以MySQL的MaxDB名義提供。
MaxDB 7.5版是SAP DB 7.4編碼基數的直接改進。因此,MaxDB軟件7.5版可用於SAP DB 7.2.04版和更高版本的直接升級。
與以往相同,目前,位於SAP AG的前SAP DB開發團隊仍負責MaxDB的開發和支援。MySQL AB與位於SAP的MaxDB團隊密切合作,致力於改進MaxDB產品,請參見1.5節,「MaxDB資料庫管理系統概述」。SAP AG和MySQL AB均負責MaxDB的銷售和分發。MaxDB和MySQL伺服器的提升促進了企業協作,從而使得兩種產品系列均從中受益。
與SAP解決方案一起提供之前,或放在MySQL站點供下載之前,MaxDB受SAP AG全面質量保證計劃的控制。
MaxDB是一種大型、通過SAP認證的開放原始碼資料庫,可用於OLTP和OLAP,它具有高的可靠性、可用性和可伸縮性,以及相當完善的特性集。它定位於大型mySAP商業套件環境,以及需要最大企業級資料庫功能的其他應用,此外,它還補充了MySQL資料庫伺服器。
MaxDB是採用客戶端/伺服器模式運作的產品。開發它的目的在於滿足OLTP和數據倉庫/OLAP/決策支援方面的安裝需求。優點:
· 簡單的配置和管理: 基於GUI(圖形化用戶界面)的安裝管理器和資料庫管理器,可作為DBMS操作的單個管理工具。
· 不間斷操作,無需計劃的停機時間,也不需要持久性維護:自動空間管理,無需重組。
· 精心設計的備份和恢復能力:聯機備份和增量備份,恢復嚮導以指導您完成整個恢復步驟。
· 支援大量用戶,數TB的資料庫大小,以及苛刻的工作量要求: 高的可靠性,性能和可伸縮性
· 高可用性: 叢集支援,待機配置,熱待機配置
MySQL AB負責為非SAP客戶提供MaxDB技術支援。MaxDB支援可在各種層面上提供(基本,銀質和金質),將無限的電子郵件/Web支援延伸為對業務關鍵系統的全天候電話支援。
當MaxDB與Sap應用程式(如SAP NetWeaver和mySAP商業套件)一起使用時,MySQL AB還能為其提供授權證和支援。關於能滿足您需求的授權和支援方面的更多訊息,請聯繫MySQL AB。
我們也提供咨詢和培訓服務。MySQL將定期提供MaxDB課程,關於課程資料表,請參見http://www.mysql.com/training/。
下面簡要介紹了MaxDB和MySQL的主要差別,但並不完全。
· MaxDB是採用客戶端/伺服器模式運作的系統。MySQL能夠作為客戶端/伺服器系統運行,也能作為嵌入式系統運行。
· MaxDB或許不能運行在MySQL支援的所有平台上。
· MaxDB採用了針對客戶端/伺服器通信的專有網絡協議。MySQL採用了TCP/IP(採用或未採用SSL加密)、套接字協議(類似Unix的系統下)或命名管道(Windows NT系列下)。
· MaxDB支援儲存程式。對於MySQL,在5.0版本中實現了儲存程式。MaxDB還支援通過SQL延伸進行的觸發程式編程,該功能計劃在MySQL 5.1中實現。MaxDB包含針對儲存程式語言的調試程式,能夠將多個嵌套式觸發程式串聯在一起,而且每個動作和行均支援多個觸發程式。
· MaxDB的發佈採用了基於文本、圖形或Web的用戶界面。MySQL的發佈僅採用基於文本的用戶界面:圖形化用戶界面(MySQL控制中心、MySQL管理器)與主發佈版本是單獨提供的。針對MySQL的基於Web的用戶界面是由第三方提供的。
· MaxDB支援多種也被MySQL支援的編程接口。為了使用MaxDB進行開發,還提供了MaxDB ODBC驅動程式,SQL資料庫連通(SQLDBC),JDBC驅動程式,Perl和Python模塊,以及MaxDB PHP延伸(通過使用PHP來訪問MySQL MaxDB資料庫)。第三方編程接口: 支援OLE DB、ADO、DAO、RDO、以及.NET和ODBC。MaxDB支援嵌入式SQL和C/C++。
· MaxDB包含MySQL不具備的管理特性: 按時間、事件和告警進行規劃安排,並能在達到告警閾值時將消息發送給資料庫管理器。
MaxDB裝載器可用於導出數據和對像定義。裝載器能夠以MaxDB內部二進制格式和文本格式(CSV)導出數據。對於以文本格式從MaxDB導出的數據,可使用mysqldump資料庫備份程式將其重新導入到MySQL中。要想將MySQL數據導入到MaxDB,可使用mysqldump建立INSERT語句或SELECT ... INTO OUTFILE語句以建立文本檔案(CSV)。使用MaxDB裝載器裝載由MySQL生成的數據檔案。
可以使用MaxDB裝載器和MySQL工具mysqldump,在系統間交換數據定義。由於兩種系統使用的SQL「方言」略有差異,而且MaxDB擁有目前尚不被MySQL支援的特性(如SQL約束),我們建議以手動方式調整定義檔案。Mysqldump工具提供了「--compatible-name = maxdb」選項來生成與MaxDB兼容的輸出,以便使移植更為簡單。
作為MaxDB 7.6的組成部份,發佈了MaxDB同步管理器。同步管理器支援數個MaxDB實例間的異步複製。但是,也設計規劃了協同特性,因此,同步管理器支援複製到MySQL伺服器的操作,以及來自MySQL伺服器的複製操作。
在首次發佈的版本中,同步管理器支援將數據插入到MySQL。這意味著,在開始時僅支援從MaxDB到MySQL的複製。在2005年的安排中,將增加把數據從MySQL伺服器導出到同步管理器的功能,因而增加了對從MySQL到MaxDB的複製支援。
除了本章給出的介紹外,MySQL參考手冊不含任何MaxDB文檔。MaxDB有自己的文檔,稱為MaxDB庫。MaxDB庫可從下述網址獲得:http://dev.mysql.com/doc/maxdb/index.html。
MySQL AB運行著一個關於MaxDB的社區郵件列資料表,請參見http://lists.mysql.com/maxdb。該列資料表給出了生動活潑的社區討論。很多核心開發人員均為其提供了相應的貢獻。產品發佈將被發送至該列資料表。
MaxDB的Web論壇網址是http://forums.mysql.com/。該論壇主要處理關於MaxDB的問題,而不是關於SAP應用程式的問題。
在本節中,介紹了MySQL發展歷程中的重要事件,包括各種MySQL版本中已實現的主要特性或規劃中的特性。在下節中,介紹了各發佈系列的相關訊息。
當前的生產版本系列是MySQL 5.0,據稱它能穩定地用於生產環境,如2005年10月發佈的5.0.15版。以前的生產版本系列是MySQL 4.1,據稱它也能穩定地用於生產環境,如2004年10月發佈的4.1.7版。「生產狀態」意味著未來的5.0和4.1開發僅限於修正問題。對於較早的MySQL 4.0和3.23系列,僅會對關鍵問題進行更正。
對於MySQL 5.0和5.1系列,相關的MySQL開發正在積極進行當中,並會為後者增加新的特性。
從1個版本系列升級到下一個版本系列之前,請參見2.10節,「升級MySQL」的介紹。
在下面的資料表格中,歸納了要求最迫切的特性,以及實施了這些特性或計劃實施這些特性的版本:
特性 |
MySQ系列 |
Foreign keys |
3.23(針對InnoDB儲存引擎) |
Unions |
4.0 |
Subqueries |
4.1 |
R-trees |
4.1(針對MyISAM 儲存引擎) |
Stored procedures |
5.0 |
Views |
5.0 |
Cursors |
5.0 |
XA transactions |
5.0 |
Foreign keys |
5.1(在3.23中實施,對於InnoDB) |
Triggers |
5.0和5.1 |
Full outer joins |
5.1 |
Constraints |
5.1(在3.23中實施,對於InnoDB) |
Partitioning |
5.1 |
Pluggable Storage Engine API |
5.1 |
Row-Based Replication |
5.1 |
關於我們打算在MySQL 5.1中增加的特性列資料表,請參見1.6節,「MySQL發展大事記」。隨著5.1版的不斷發展,我們將在本節增加更多詳細訊息。
在本節中介紹了MySQL郵件列資料表,並給出了使用郵件列資料表的指南。訂購郵件列資料表後,將以電子郵件消息的形式收到所有已記錄的訊息。您也可以將自己的問題和解答發送至郵件列資料表。
要想訂購本節所介紹的郵件列資料表或取消訂購,請訪問http://lists.mysql.com/。對於大多數郵件列資料表,可選擇能夠獲取單獨消息的正規列資料表版本,或選擇按天發佈的包含大量消息的文摘版本。
不要將訂購訊息或取消訂購的訊息發送到郵件列資料表,原因在於,這類消息將自動分發給數千位其他用戶。
在您的所在地,可能有很多MySQL郵件列資料表的訂戶。如果是這樣,該地點可能會有本地郵件列資料表,這樣,從lists.mysql.com發出的消息將被傳播到本地列資料表。在這類情形下,請與您的系統管理員聯繫,新增或刪除本地MySQL列資料表。
如果希望將郵件列資料表的訊息傳送到郵件程式的郵箱中,請根據消息標題設置過濾器。可以使用列資料表ID: 或投遞至: 識別列資料表消息的標題。
MySQL列資料表包含:
· 通告
該列資料表用於通告新的MySQL版本和相關程式。這是1種低容量列資料表,所有的MySQL用戶均應訂購它。
· mysql
這是關於一般MySQL討論的主要列資料表。請注意,對於某些主題來說,在更專門的列資料表中會得到更好地討論。如果將問題張貼到了錯誤的列資料表,可能不會得到回答。
· 問題
該列表面向那些希望隨時瞭解自上次MySQL版本發佈以來已通報事宜的人員,或希望積極參與問題尋找和更正程序的人員。請參見1.7.1.3節,「如何通報問題和問題」。
· 內部構件
該列表面向那些與MySQL代碼打交道的人員。它也是討論MySQL開發並張貼補丁的論壇。
· mysqldoc
該列表面向那些與MySQL文檔打交道的人員: MySQL AB公司的人員,譯者,以及其他社區成員。
· 基準
該列表面向任何對性能事宜感興趣的人員。討論主要集中在資料庫性能方面(不限於MySQL),也包括更廣的類別,如內核性能、檔案系統、磁盤系統等。
· packagers(包裝程式)
該列資料表主要討論包裝和分發MySQL方面的問題。這是供分發版維護人員交流MySQL打包事宜的論壇,為的是確保在所有支援的平台和作業系統上,MySQL的外觀和感覺盡可能類似。
· java
該列資料表主要討論MySQL伺服器和Java方面的問題。它主要討論JDBC驅動程式,包括MySQL Connector/J。
· win32
該列資料表涵蓋了在Microsoft作業系統環境下(如Windows 9x, Me, NT, 2000, XP和2003)與MySQL軟件有關的所有主題,
· myodbc
該列資料表涵蓋了與使用ODBC連接到MySQL伺服器有關的所有主題。
· gui-tools
該列資料表涵蓋了與MySQL GUI工具有關的所有主題,包括MySQL管理員以及MySQL控制中心圖形客戶端。
· cluster
該列資料表主要討論MySQL叢集。
· dotnet
該列資料表主要討論MySQL伺服器和.NET平台方面的問題。它與MySQL Connector/Net提供人的關係最密切。
· plusplus
該列資料表涵蓋了使用C++ API進行MySQL編程的所有主題。
· perl
該列資料表涵蓋了與Perl對MySQL支援、以及DBD::mysql有關的所有主題。
如果無法從MySQL郵件列資料表或論壇獲得問題解答,一種選擇是購買MySQL AB的支援服務。這樣,您就能與MySQL開發人員直接聯繫。
下面介紹了一些英語以外其他語言的MySQL郵件列資料表。這些郵件列資料表不是由MySQL AB運營的。
· <mysql-france-subscribe@yahoogroups.com>
法語郵件列資料表。
· <list@tinc.net>
朝鮮語郵件列資料表。發送電子郵件訂購mysql your@email.address。
· <mysql-de-request@lists.4t2.com>
德語郵件列資料表。發送電子郵件訂購mysql-de your@email.address。在http://www.4t2.com/mysql/站點上,可找到關於該郵件列資料表的更多訊息。
· <mysql-br-request@listas.linkway.com.br>
葡萄牙語郵件列資料表。發送電子郵件訂購mysql-br your@email.address。
西班牙語郵件列資料表。發送電子郵件訂購mysql your@email.address。
· 首先搜索MySQL線上手冊,http://dev.mysql.com/doc/。我們經常更新該手冊,以使該手冊保持最新,其中包含相應的解決方案和新發現的問題。變更史(http://dev.mysql.com/doc/mysql/en/News.html)可能更有用,原因在於,在較新的版本中可能包含對您所提出問題的解決方案。
· 搜索問題資料庫,http://bugs.mysql.com/,搜尋該問題是否已通報或更正。
· 搜索MySQL郵件列資料表檔案,http://lists.mysql.com/。
· 您也可以使用http://www.mysql.com/search/來搜索MySQL AB網站上的所有網頁(包含手冊)。
如果無法在手冊或檔案中找到答案,請與本地MySQL專家協商。如果仍無法獲得解答,在與我們聯繫之前,請按照介紹發送電子郵件至MySQL郵件列資料表,具體內容見下一節。
通報問題的正常地址是http://bugs.mysql.com/,它也是我方問題資料庫的地址。這是1個公共資料庫,任何人都能瀏覽它並進行相應的搜索。如果登錄到系統,可輸入新的報告。
編寫良好的問題報告需要耐心,但在第1時間正確地完成它不僅能節省我們的時間,也能節省您自己的時間。良好的問題報告應包含對問題的完整測試情況,以便我們能夠在下個版本中更正該問題。本節介紹的內容用於幫助您正確地編寫報告,從避免將您的時間浪費在對我們幫助不大或沒有幫助的事上,
我們鼓勵任何人使用mysqlbug指令來生成問題報告(或通報問題)。Mysqlbug可在指令目錄下找到(原始碼分發版),也能在MySQL安裝目錄的bin子目錄下找到(二進制分發版)。如果不能使用mysqlbug(例如,如果您正在Windows平台上運行),應包括本節所述的所有必要訊息(更重要的是,應介紹作業系統和MySQL版本),這點十分重要。
通過自動確定下述訊息,mysqlbug指令能夠幫助您生成報告,但是,如果遺漏了某些重要事項,請將其包含在消息中。請認真閱讀本節,並確保在您的報告中包含了本節所述的所有訊息。
在張貼問題前,最好使用MySQL伺服器的最新生產版或開發版對問題進行測試。通過在所含的測試範例上使用「mysql test < script_file」,或運行問題報告中所含的Shell或Perl指令,任何人均應能重複該問題。
對於在問題資料庫(http://bugs.mysql.com/)中張貼的所有問題,均會被納入或記錄在下一個MySQL版本中。如果只需要少量更改就能更正問題,我們或許會給出更正該問題的補丁。
如果發現MySQL中存在敏感的安全問題,請發送電子郵件至security@mysql.com。
如果有1份可重複的問題報告,請將其提交到問題資料庫,http://bugs.mysql.com/。注意,即使在該情況下,也應首先運行mysqlbug指令以找出與您的系統有關的訊息,這是一個不錯的習慣。對於任何我們能再現的問題,在下一個MySQL版本中修正它的機會很大。
要想通報其他問題,請使用MySQL郵件列資料表。
請注意,我們可能會對包含過多訊息的消息做出響應,但不太會對包含過少訊息的消息做出回應。人們常會省略掉一些事實,因為他們認為自己知道了故障的原因,並想當然地認為這類細節無關緊要。良好的原則是: 如果您對陳述某事猶豫不定,請陳述之。如果我們要求您提供初始報告中缺少的訊息,在報告中編寫多行資訊來源比等候回復要快,麻煩也更小。
在問題報告中,最常犯的錯誤包括:(a)未包含所使用MySQL的版本號,以及(b)未完全描述安裝了MySQL伺服器的平台(包括平台類型,以及版本號)。這是高度相關的訊息,如果沒有它,99%的問題報告無用。我們遇到這類問題,「為何它對我沒用」? 隨後,我們發現在該MySQL版本中,所請求的特性尚未實施,或在較新的MySQL版本中已更正了報告中描述的問題。有些時候,錯誤與平台相關,在這類情況下,如果不知道作業系統和平台的版本號,我們幾乎不可能更正任何問題。
如果您是從原始碼編譯MySQL的,如果與問題有關,還應提供有關編譯器的訊息。問題經常出在編譯器,但人們卻認為問題與MySQL有關。大多數編譯均處於不斷的開發過程中,並會變得越來越好。為了確定問題是否與您的編譯器有關,我們需要知道您所使用的編譯器。注意,所有的編譯問題均應被當作問題並予以通報。
在您的報告中包含良好的問題描述時,報告最有幫助。也就是說,應給出示範,指明導致問題的所有事項,並準確描述問題本身。最好的報告應包含完整的示範,這類示範應闡明再現問題或問題的方式。請參見E.1.6節,「如果出現資料表崩潰,請生成測試案例」。
如果程式產生了錯誤消息,也應將其包含在您的報告中,這點很重要。如果我們打算使用程式搜索檔案,最好是通報的錯誤消息與程式生成的錯誤消息準確匹配。(即使是字母的大小寫也應考慮在內)。永遠不要嘗試從記憶中再現錯誤消息,而是應將整個消息拷貝並粘貼到報告中。
如果遇到與Connector/ODBC (MyODBC)有關的問題,請生成1份跟蹤檔案,並與報告一起發送給我們。請參見26.1.1.9節,「如何通報MyODBC問題或問題」。
請記住,很多閱讀您報告的人員會使用80列的顯示器。使用mysql命令行工具生成報告或示範時,如果輸出內容可能會超過這類顯示器的可用寬度,應使用「--vertical」選項(或「\G」語句終結符),例如EXPLAIN SELECT語句,請參見本節後面給出的示範。
請在您的報告中包含下述訊息:
· 您所使用的MySQL分發版的版本號(例如MySQL 4.0.12)。通過執行mysqladmin version,即可瞭解正在運行版本。Mysqladmin程式位於MySQL安裝目錄的bin子目錄下。
· 出現問題的機器的製造商和型號。
· 作業系統的名稱和版本。如果您使用的是Windows作業系統,通常能通過雙擊「我的電腦」圖標並點擊「幫助/關於Windows」菜單來瞭解作業系統的名稱和版本。對於大多數Unix作業系統,可通過執行命令uname –a獲取這類訊息。
· 某些時候,內存容量(實際內存和虛擬內存)也有關係。如果懷疑它,也應包含這類數值。
· 如果您正在使用的是MySQL軟件的原始碼分發版,還須提供所使用編譯器的名稱和版本。如果使用的是二進制分發版,需要提供其名稱。
· 如果在編譯過程中出現問題,應給出準確的錯誤消息,出錯檔案中的不良代碼,以及該代碼附近的數行內容。
· 如果mysqld停止運行,還應通報導致mysqld崩潰的查詢。通常,能夠通過運行啟用了查詢日誌功能的mysqld找出它,然後在mysqld崩潰後搜尋日誌。請參見E.1.5節,「使用日誌檔案找出mysqld中的錯誤原因」。
· 如果資料庫資料表與問題有關,還應包含mysqldump --no-data db_name tbl_name的輸出。這是一種瞭解資料庫中資料表相關訊息的簡單易行而且功能強大的方式。該訊息能幫助我們建立與您所遇到的情況相匹配的場景。
· 對於與SELECT語句的速度有關的問題或問題,總應包含「EXPLAIN SELECT ...」的輸出,以及SELECT語句生成的行數(至少)。對於每個涉及的資料表,應包含SHOW CREATE TABLE tbl_name的輸出。您所提供的關於具體情況的訊息越多,得到幫助的可能性就越大。
下面給出了一個良好問題報告的示範。應使用mysqlbug指令張貼它。本例採用了mysql命令行工具。對於輸出內容可能會超過80列顯示器可用寬度的語句,應使用「\G」語句終結符。
mysql> SHOW VARIABLES;
mysql> SHOW COLUMNS FROM ...\G
<output from SHOW COLUMNS>
mysql> EXPLAIN SELECT ...\G
<output from EXPLAIN>
mysql> FLUSH STATUS;
mysql> SELECT ...;
<A short version of the output from SELECT,
including the time taken to run the query>
mysql> SHOW STATUS;
<output from SHOW STATUS>
· 如果在運行mysqld時出現錯誤或問題,應提供導致異常的輸入指令。該指令應包含任何所需的源檔案。越能再現具體情況的指令越好。如果能夠建立可再現的測試範例,請將其張貼到http://bugs.mysql.com/,它將得到優先對待。
如果您不能提供指令,至少應在您的郵件中包含mysqladmin variables extended-status processlist的輸出,以提供關於系統執行情況的某些訊息。
· 如果不能生成包含數行內容的測試範例,或者如果測試資料表過大以至於無法發送到郵件列資料表(超過10行),應使用mysqldump轉儲資料表,並建立描述問題的README檔案。
使用tar和gzip或zip建立檔案的壓縮包檔案,並使用FTP將檔案傳輸到ftp://ftp.mysql.com/pub/mysql/upload/。然後將問題提交到我們的問題資料庫中,http://bugs.mysql.com/。
· 如果您認為MySQL伺服器生成了奇怪的查詢結果,不僅應包含結果,還應給出您對該結果的看法,以及支援觀點的基礎。
· 提供問題的示範時,最好使用實際情況下已有的變數名、資料表名等,而不是新名稱。問題可能與變數名或資料表名有關。或許這類情況很罕見,但安全總比道歉強。歸根結底,對您來說,提供關於實際情況的示範要簡單些,當然對我們也更好。如果您的數據不打算展示給其他人,請使用FTP將其傳輸到ftp://ftp.mysql.com/pub/mysql/upload/。如果訊息是高度保密的,而且您甚至不打算向我們展示,請使用其他名稱給出示範,但請注意,這應是最後的選擇。
· 如果可能,應包含相關程式的所有選項。例如,應指明啟動mysqld伺服器時使用的選項,以及用來運行MySQL客戶端程式的選項。對於程式(如mysqld和mysql)選項以及configure指令的選項,通常是解答問題的關鍵,關係十分密切。包含它們總不是壞主意。如果使用了任何模塊,如Perl或PHP等,還應給出它們的版本。
· 如果您的問題與權限系統有關,請給出mysqlaccess的輸出,mysqladmin reload的輸出,以及進行連接時獲得的所有錯誤消息。測試權限時,首先應運行mysqlaccess。接下來,執行mysqladmin reload version,並與導致問題的程式相連。mysqlaccess可在MySQL安裝目錄的bin子目錄下找到。
· 如果您有關於某一問題的補丁,也請將它包含在內。但不要認為該補丁是我們所需的全部,如果未提供補丁所更正問題的必要訊息(如測試範例),不要假定我們會使用它。我們可能會通過補丁發現問題,或者不能理解該補丁,如果是這樣,我們不會使用該補丁。
如果我們不能準確核實補丁的目的,將不會使用它。測試範例會對我們有所幫助。請指明該補丁能處理所有的問題。如果我們發現補丁不能工作的臨界情況(即使很罕見),它可能是無用的。
· 關於問題是什麼、出現原因、以及問題導因的猜測通常是錯的。即使是MySQL團隊,在未使用調試器判定問題真實原因的情況下,也不能妄加猜測。
· 請在您的問題報告中指明,您已參閱了參考手冊並寄出了檔案,以便讓其他人知道您已作了自行解決問題的嘗試。
· 如果遇到解析錯誤,請仔細檢查語法。如果不能找出錯誤出現在那裡,很可能是因為您使用的MySQL伺服器版本不支援您使用的語法。如果您使用的是http://dev.mysql.com/doc/上提供的當前版本和手冊,不要包含您所使用的語法,MySQL伺服器不支援您的查詢。在這種情況下,唯一的選擇是自行實施語法,或發送電子郵件至<licensing@mysql.com>,並尋求實施方案。
如果手冊中涵蓋了您所使用的語法,但您使用的是舊版本MySQL伺服器,請檢查MySQL變更史,以查看語法的實施時間。在這種情況下,可以選擇升級到較新的MySQL伺服器版本。請參見附錄D:MySQL變更史。
· 如果問題在於數據崩潰,或訪問特殊資料表時出錯,首先應使用CHECK TABLE和REPAIR TABLE或myisamchk進行檢查並嘗試修復。請參見第5章:資料庫管理。
如果您使用的作業系統是Windows,請使用SHOW VARIABLES LIKE 'lower_case_table_names'命令核實「lower_case_table_names」的值。
· 如果經常獲得崩潰的資料表,請嘗試找出發生的時間和原因。在這種情況下,MySQL數據目錄下的錯誤日誌可能會包含關於它的一些訊息。(這是名稱中包含.err後綴的檔案)。請參見5.11.1節,「錯誤日誌」。在您的問題報告中,請包含該檔案提供的相關訊息。如果在更新期間,未殺死更新程序,正常情況下,mysqld不會造成資料表損壞。如果您能夠找到mysqld停止的原因,我們會更容易地為您提供更正它的補丁。請參見A.1節,「如何確定導致問題的原因」。
· 如果可能,請下載並安裝最新版本的MySQL伺服器,並檢查您的問題是否得到解決。所有版本的MySQL軟件均經過徹底測試,並應能無故障運行。我們致力於盡可能地向後兼容,您也應能夠毫不困難地在不同的MySQL版本間進行切換。請參見2.1.2節,「選擇要安裝的MySQL分發版」。
如果您是享受支援服務的客戶,請將問題報告交叉張貼在mysql-support@mysql.com,以獲得更高的優先級,並將其張貼到恰當的郵件列資料表,以查看是否有人遇到了類似問題(或解決了問題)。
關於通報MyODBC中存在問題的更多訊息,請參見26.1.1.9節,「如何通報MyODBC問題或問題」。
將答案單獨發送給您而不是發送到郵件列資料表時,良好的禮節是,對回答進行歸納總結並將結果發送到郵件列資料表,以便其他人也能從您所收到、並解決了問題的回應中受益。
在您的回復中,應盡量歸納問題的基本部分,沒有必要一定引用全部初始訊息。
在要在打開HTML模式的情況下從瀏覽器張貼郵件訊息。很多用戶不使用瀏覽器來閱讀郵件。
· Freenode(請參見http://www.freenode.net/以搜尋伺服器訊息)
o #mysql,主要針對MySQL問題,也歡迎其他資料庫和一般的SQL問題。與MySQL一起使用PHP、Perl或C方面的問題也很常見。
如果您正在尋找URC客戶端軟件,以便連接到IRC網絡,請訪問xChat(http://www.xchat.org/)。X-Chat(GPL授權)即能用於Unix平台,也適用於Windows平台(免費的面向Windows的X-Chat可從站點http://www.silverex.org/download/上下載)。
有各種可用論壇,分為以下大類:
· 移植
· MySQL用法
· MySQL連接器
· 編程語言
· 工具
· 第三方應用程式
· 儲存引擎
· MySQL技術
· SQL標準
在本節中,介紹了MySQL與ANSI/ISO SQL標準的關係。MySQL伺服器有很多對SQL標準的延伸之處,這裡介紹了它們是什麼,以及使用它們的方法。您也能瞭解關於MySQL伺服器缺失功能的訊息,以及如何處理某些差異的方法。
SQL標準自1986年以來不斷演化發展,有數種版本。在本手冊中,「SQL-92」指得是1992年發佈的標準,「SQL:1999」指得是1999年發佈的標準,「SQL:2003」指得是標準的當前版本。我們採用術語「SQL標準」標示SQL標準的當前版本。
我們的目標是在沒有良好理由的情況下不限制MySQL伺服器的可用性。即使我們沒有足夠的資源就每種可能的應用進行開發,我們始終願意幫助那些在新領域使用MySQL伺服器的人員,並向他們提供建議。
對於該產品,我們的一項主要目標是,繼續致力於與SQL標準的相容性,但不以犧牲速度和可靠性為代價。如果它們能顯著增加擁有大量用戶基數的MySQL伺服器的可用性,我們無懼於為SQL新增延伸,也無懼於為非SQL特性提供支援。MySQL伺服器4.0中的HANDLER接口即是該策略的例子。請參見13.2.3節,「HANDLER語法」。
我們將繼續支援事務性和非事務性資料庫,以滿足任務關鍵型全天候應用,以及高負載Web或日誌應用。
MySQL伺服器最初是為小型計算機系統上中等規模的資料庫設計的(100萬-1億行,或每個資料表的大小為100MB)。目前,MySQL伺服器能處理TB級別的資料庫,也能在針對便攜式設備或嵌入式設備的精簡版本中使用。MySQL伺服器的精簡設計使得雙向開發成為可能,不會在原始碼樹中產生任何衝突。
目前,我們並未定位於實時支援,雖說MySQL複製特性提供了強大的功能。
在眾多第三方叢集解決方案中均有資料庫叢集支援特性,自4.1.2版以來,對於我們所需的NDB叢集技術集成方案,同樣請參見第17章:MySQL叢集。
MySQL伺服器能夠工作在不同的SQL模式下,並能針對不同的客戶端以不同的方式應用這些模式。這樣,應用程式就能對伺服器操作進行量身定制以滿足自己的需求。
這類模式定義了MySQL應支援的SQL語法,以及應該在數據上執行何種確認檢查。這樣,就能在眾多不同的環境下、與其他資料庫伺服器一起更容易地使用MySQL。
可以使用「--sql-mode="modes"」選項,通過啟動mysqld來設置預設的SQL模式。從MySQL 4.1開始,也能在啟動之後,使用ET [SESSION|GLOBAL] sql_mode='modes'語句,通過設置sql_mode變數更改模式。
關於設置伺服器模式的更多訊息,請參見5.3.2節,「SQL伺服器模式」。
您可以使用「--ansi」啟動選項,要求mysqld使用ANSI模式。請參見5.3.1節,「mysqld命令行選項」。
在ANSI模式下運行伺服器與使用該選項啟動它的效果一樣(在一行上指定「--sql_mode」值):
--transaction-isolation=SERIALIZABLE
--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE
在MySQL 4.1中,能夠用下述兩條語句實現相同的效果(在一行上指定「sql_mode」值):
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET GLOBAL sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE';
請參見1.8.2節,「選擇SQL模式」。
在MySQL 4.1.1中,也能用下述語句設置sql_mode選項:
SET GLOBAL sql_mode='ansi';
在本例中,將sql_mode變數的值設置為與ANSI模式相關的所有選項。您可以檢查其結果,如下所示:
mysql> SET GLOBAL sql_mode='ansi';
mysql> SELECT @@global.sql_mode;
-> 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE,ANSI';
MySQL伺服器包含一些其他SQL DBMS中不具備的延伸。注意,如果使用了它們,將無法把代碼移植到其他SQL伺服器。在某些情況下,您可以編寫包含MySQL延伸的代碼,但仍保持其可移植性,方法是用「/*... */」註釋掉這些延伸。在本例中,MySQL伺服器能夠解析並執行註釋中的代碼,就像對待其他MySQL語句一樣,但其他SQL伺服器將忽略這些延伸。例如:
SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...
如果在字元「!」後新增了版本號,僅當MySQL的版本等於或高於指定的版本號時才會執行註釋中的語法:
CREATE /*!32302 TEMPORARY */ TABLE t (a INT);
這意味著,如果您的版本號為3.23.02或更高,MySQL伺服器將使用TEMPORARY關鍵字。
下面按類別介紹了各種MySQL延伸。
· 磁盤上的數據組織
MySQL伺服器會將每個資料庫映射到MySQL數據目錄下的1個目錄中,並將資料庫中的資料表映射到資料庫目錄下的檔案名。它具有下述含義:
o 如果作業系統的檔案名區分大小寫(如大多數Unix系統),當MySQL伺服器運行在這類作業系統上時,資料庫名和資料表名也區分大小寫。請參見9.2.2節,「識別符大小寫敏感性」。
o 您可以使用標準的系統命令來備份、重命名、移動、刪除、並拷貝由MyISAM或ISAM儲存引擎管理的資料表。例如,要想重命名MyISAM資料表,可重命名資料表對應的.MYD、.MYI、以及.frm檔案。
資料庫、資料表、索引、列或別名能夠以數字開頭(但或許不能全部由數字構成)。
· 通用語言語法
o 可以使用「」」或「』」括住字串,而不僅是「』」。
o 在字串中使用「\」作為轉義字元。
o 在SQL語句中,可以使用「db_name.tbl_name」語法訪問不同資料庫中的資料表。某些SQL伺服器提供了相同的功能,但使用該用戶空間除外。MySQL伺服器不支援資料表空間,如下述語句中使用的那樣: CREATE TABLE ralph.my_table...IN my_tablespace.
· SQL語句的語法
o ANALYZE TABLE,CHECK TABLE,OPTIMIZE TABLE,以及REPAIR TABLE語句。
o CREATE DATABASE和DROP DATABASE語句。請參見13.1.3節,「CREATE DATABASE語法」。
o DO語句。
o EXPLAIN SELECT獲取如何聯合資料表的介紹。
o FLUSH和RESET語句。
o SET語句。請參見13.5.3節,「SET語法」。
o SHOW語句。請參見13.5.4節,「SHOW語法」。
o 使用LOAD DATA INFILE。在很多情況下,該語法與Oracle的LOAD DATA INFILE兼容。請參見13.2.5節,「LOAD DATA INFILE語法」。
o RENAME TABLE的使用。請參見13.1.9節,「RENAME TABLE語法」。
o 使用REPLACE取代DELETE + INSERT。請參見13.2.6節,「REPLACE語法」。
o 在ALTER TABLE語句中使用CHANGE col_name、DROP col_name、或DROP INDEX、IGNORE或RENAME。在ALTER TABLE語句中使用多個ADD、ALTER、DROP或CHANGE子句。請參見13.1.2節,「ALTER TABLE語法」。
o 使用索引名,字段前綴上的索引,並在CREATE TABLE語句中使用INDEX或KEY。請參見13.1.5節,「CREATE TABLE語法」。
o 與CREATE TABLE一起使用TEMPORARY或IF NOT EXISTS。
o 與DROP TABLE一起使用IF EXISTS。
o 使用單個DROP TABLE語句,能夠捨棄多個資料表。
o UPDATE和DELETE語句的ORDER BY和LIMIT子句。
o INSERT INTO ... SET col_name = ... syntax.
o INSERT和REPLACE語句的DELAYED子句。
o INSERT、REPLACE、DELETE和UPDATE語句的LOW_PRIORITY子句。
o 在SELECT語句中使用INTO OUTFILE和STRAIGHT_JOIN。請參見13.2.7節,「SELECT語法」。
o SELECT語句中的SQL_SMALL_RESULT選項。
o
不需要在GROUP BY部分命名所有選擇的列。對於某些十分特殊但相當正常的查詢,它能提供更好的性能。請參見12.10節,「與GROUP BY子句同時使用的函數和修改程式」。
o 可以與GROUP BY一起指定ASC和DESC。
o 能夠在帶有「:=」賦值操作符的語句中設置變數。
o mysql> SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg
o -> FROM test_table;
o mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
· 列類型
o 列類型MEDIUMINT、SET、ENUM、以及不同的BLOB和TEXT類型。
o 列屬性AUTO_INCREMENT、BINARY、NULL、UNSIGNED以及ZEROFILL。
· 函數和操作符
o 為了使其他SQL環境下的用戶更容易入手,MySQL伺服器對很多函數均支援別名特性。例如,所有的字串函數均支援標準SQL語法和ODBC語法。
o MySQL伺服器能夠理解「||」和「&&」操作符,將其當作邏輯OR和AND,就像在C編程語言中那樣。在MySQL伺服器中,||和OR是同義詞,&&和AND也是同義詞。由於採用了該優異的語法體系,MySQL伺服器不支援SQL針對字串連接的「||」操作符,而採用了CONCAT()取而代之。由於CONCAT()能夠接受任意數目的參量,很容易將使用「||」操作符的情況轉換為MySQL伺服器支援的類型。
o 請在有多於1個元素的場合下使用COUNT(DISTINCT list)。
o 「%」操作符等同於MOD()。也就是說「N % M」等同於MOD(N,M)。Cyuyan的程式員支援「%」,而且它也是為了兼容PostgreSQL而使用的。
o 在列比較中,可在SELECT語句的FROM左側使用=、<>、<=、<、>=、>、<<、>>、<=>、AND、OR或LIKE操作符。例如:
o mysql> SELECT col1=1 AND col2=2 FROM tbl_name;
o 返回最近AUTO_INCREMENT值的LAST_INSERT_ID()函數。請參見12.9.3節,「訊息函數」。
o 允許在數值列上使用LIKE。
o REGEXP和NOT REGEXP延伸了常規的資料表達式操作符。
o 具有1個或2個以上參量的CONCAT()或CHAR()。(在MySQL伺服器中,這些函數可以有任意數目的參量)。
o BIT_COUNT()、CASE、ELT()、FROM_DAYS()、FORMAT()、IF()、PASSWORD()、ENCRYPT()、MD5()、ENCODE()、DECODE()、PERIOD_ADD()、PERIOD_DIFF()、TO_DAYS()、以及WEEKDAY()函數。
o 使用TRIM()來調整子字串。標準SQL僅支援單個字元的刪除。
GROUP BY函數STD()、BIT_OR()、BIT_AND()、BIT_XOR()、以及GROUP_CONCAT()。請參見12.10節,「與GROUP BY子句同時使用的函數和修改程式
」。我們試圖使MySQL伺服器遵從ANSI SQL標準和ODBC SQL標準,但在某些情況下MySQL伺服器執行的操作有所不同:
· 對於VARCHAR列,儲存值時刪除了尾部空間。(在MySQL 5.0.3中更正)。請參見A.8節,「MySQL中的已知事宜」。
· 在某些情況下,定義資料表或更改其結構時,將CHAR列轉換為VARCHAR列。(在MySQL 5.0.3中更正)。請參見13.1.5.1節,「沉寂的列規格變更」。
· 刪除資料表時,不自動取消關於資料表的權限。必須明確發出REVOKE語句,以撤銷針對資料表的權限。請參見13.5.1.3節,「GRANT和REVOKE語法」。
· CAST()函數不支援對REAL或BIGINT的拋棄。請參見12.8節,「Cast函數和操作符」。
· 標準SQL要求,SELECT語句中的HAVING子句能夠引用GROUP BY子句中的列。在MySQL 5.0.2之前,不能完成該功能。
MySQL 4.1支援子查詢和導出資料表。「子查詢」指的是嵌套在另一語句中的SELECT語句。「導出資料表」(未命名視圖)是另一語句的FROM子句中的子查詢。請參見13.2.8節,「Subquery語法」。
從MySQL 4.1版起,可以使用聯合或其他方法重寫大多數子查詢。關於如何完成該任務的更多訊息,請參見13.2.8.11節,「對於較早的MySQL版本,採用聯合方法重寫子查詢」。
MySQL伺服器不支援Sybase SQL延伸: SELECT ... INTO TABLE ....。但MySQL伺服器支援標準的SQL語法INSERT INTO ... SELECT ...,它基本上相同。請參見13.2.4.1節,「INSERT ... SELECT語法」。
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
作為備選方式,可以使用SELECT INTO OUTFILE ...或CREATE TABLE ... SELECT。
從5.0版開始,MySQL支援SELECT ... INTO,以及用戶變數。在使用光標和局部變數的儲存程式中也可以使用相同的語法。請參見20.2.9.3節,「SELECT ... INTO語句」。
MySQL伺服器(3.23至該系列的最高版本,所有4.0版本,以及更高版本)支援採用InnoDB和BDB事務儲存引擎的事務。InnoDB提供了全面的ACID相容性。請參見第15章:儲存引擎和資料表類型。
MySQL伺服器中的其他非事務性儲存引擎(如MyISAM)遵從不同的數據完整性範例,稱之為「原子操作」。按照事務術語,MyISAM資料表總能高效地工作在AUTOCOMMIT=1模式下。原子操作通常能提供可比較的完整性以及更好的性能。
由於MySQL伺服器支援兩種範例,因而您能決定是否利用原子操作的速度更好地服務於您的應用程式,或使用事務特性。該選擇可按資料表進行。
正如所闡述的那樣,事務性和非事務性資料表類型之間的權衡主要取決於性能。事務性資料表對內存和磁盤空間的要求更高,CPU開銷也更大。另一方面,多種事務性資料表類型,如InnoDB,也能提供很多顯著特性。MySQL伺服器的模塊化設計允許同時使用不同的儲存引擎,以滿足不同的要求,並在所有情形下,提供最佳性能。
但是,即便使用非事務性MyISAM資料表,您將如何使用MySQL伺服器的特性來保持嚴格的完整性呢?這些特性與事務性資料表類型相比又如何呢?
1. 如果應用程式採用了特定的編寫方式,依賴於在關鍵情況下能夠使用ROLLBACK而不是COMMIT,那麼事務性類型更方便。使用事務,還能確保未完成的更新或崩潰的活動不被提交到資料庫,能為伺服器提供自動回滾的機會,並保存您的資料庫。
如果使用非事務性資料表,MySQL伺服器幾乎在所有情況下均允許您解決潛在的問題,方式是在更新前進行簡單檢查,並運行檢查資料庫一致性的簡單指令,如果出現不一致性,該指令能自動修復它或給出告警。注意,僅使用MySQL日誌或增加額外日誌,通常能完美地更正資料表,同時不會造成數據完整性損失。
2. 在很多情況下,能夠對關鍵的事務更新進行重寫,使之成為「原子」類型。一般而言,所有由事務解決的完整性問題均能用LOCK TABLES或原子更新解決,從而確保了伺服器不會自動中斷,後者是事務性資料庫系統的常見問題。
3. 為了安全使用MySQL伺服器,無論是否使用事務性資料表,僅需啟用備份和二進制日誌功能。這樣,您就能解決使用其他事務性資料庫系統時遇到的任何問題。無論使用的資料庫系統是什麼,啟用備份總是個好主意。
事務范型有自己的優點和不足之處。很多用戶和應用程式開發人員喜歡這類簡單性,在出現問題時或必要時,通過代碼解決問題。但是,即使您是原子操作范型的新手,或更熟悉事務,也請考慮非事務性資料表的速度益處,與經過最佳化調整的最快的事務性資料表相比,它的速度快3~5倍。
在完整性具有最高重要性的情況下,即使是對非事務性資料表,MySQL也能提供事務級別的可靠性和安全性。如果使用LOCK TABLES鎖定了資料表,所有更新均將被暫時中止直至完整性檢查完成。如果您獲得了對某一資料表的READ LOCAL鎖定(與寫鎖定相對),該資料表允許在資料表尾執行並行插入,當其他客戶端執行插入操作時,允許執行讀操作。新插入的記錄不會被有讀鎖定屬性的客戶端看到,直至解除了該鎖定為止。使用INSERT DELAYED,能夠將插入項置於本地隊列中,直至鎖定解除,不會讓客戶端等待插入完成。請參見13.2.4.2節,「INSERT DELAYED語法」。
從我們賦與其名稱的意義上,「原子」絕非不可思議的。它僅意味著,您能確信在每個特性更新運行的同時,其他用戶不能干涉它,而且不會出現自動回滾(如果您不小心,對於事務性資料表,這種情況可能發生)。MySQL伺服器還能保證不存在髒讀。
下面列出了使用非事務性資料表的一些技術:
· 對於需要事務的循環,通常能使用LOCK TABLES進行編碼,不需要光標來更新正在處理的記錄。
· 要想避免使用ROLLBACK,可採取下述策略:
1. 使用LOCK TABLES鎖定所有希望訪問的資料表。
2. 執行更新前,測試必須為真的條件。
3. 如果一切正常,執行更新。
4. 使用UNLOCK TABLES解除鎖定。
與使用具有回滾可能性的事務性資料表相比,它通常具有更快的速度,雖然並非始終如此。該解決方案唯一不能處理的情形是,在更新中途殺死了線程。在這種情況下,將釋放所有鎖定,但某些更新可能尚未執行。
· 也可以使用函數在單一操作中更新記錄。採用下述技術,能獲得效率很高的應用程式。
o 根據其當前值更改列。
o 僅更新出現實際變化的列。
例如,當我們更新某些客戶訊息時,僅更新已更改的客戶數據,與原始行相比,僅測試已更改的數據或依賴於已更改數據的數據是否未出現變化。對於已更改數據的測試,它是通過UPDATE語句的WHERE子句完成的。如果記錄未更新,將向客戶端發出消息: 「一些您改變的數據已被其他用戶更改」。接下來,我們在窗口中給出了舊行和新行,以便用戶決定使用哪個版本。
這給出了與列鎖定類似的結果,但效果更好,使用相對於其當前值的值,僅更新了某些列。這意味著,典型的UPDATE語句與下面給出的類似:
UPDATE tablename SET pay_back=pay_back+125;
UPDATE customer
SET
customer_date='current_date',
address='new address',
phone='new phone',
money_owed_to_us=money_owed_to_us-125
WHERE
customer_id=id AND address='old address' AND phone='old phone';
它很有效,即使其他客戶端更改了pay_back或money_owed_to_us列中的值,也能使用。
· 在很多情況下,用戶希望將LOCK TABLES和/或ROLLBACK用於管理唯一ID。可以在不使用鎖定功能或回滾的情況下,使用AUTO_INCREMENT列以及LAST_INSERT_ID() SQL函數或mysql_insert_id() C API函數,更有效地處理之。請參見12.9.3節,「訊息函數」。請參見25.2.3.36節,「mysql_insert_id()」。
我們通常能使用代碼來處理行級鎖定方面的需求。在某些情況下,實際上不需要它,InnoDB資料表支援行級鎖定。通過MyISAM資料表,能夠在資料表中使用標誌列,並完成類似下面的操作:
UPDATE tbl_name SET row_flag=1 WHERE id=ID;
如果找到行,而且原始行中的row_flag不是1,對於受影響的行數,MySQL返回1。
您可以認為MySQL將前述查詢更改為:
UPDATE tbl_name SET row_flag=1 WHERE id=ID AND row_flag <> 1;
對於MySQL,在5.0版本中實現了儲存程式。請參見第20章:儲存程式和函數。
從5.0.2版開始,在MySQL中實現了基本的觸發器功能,計劃在MySQL 5.1中進一步發展它。請參見第21章:觸發程式。
在MySQL伺服器3.23.44和更高版本中,InnoDB儲存引擎支援對外部鍵約束的檢查功能,這些約束包括CASCADE、ON DELETE和ON UPDATE。請參見15.2.6.4節,「FOREIGN KEY約束」。
對於InnoDB之外的其他儲存引擎,MySQL伺服器能夠解析CREATE TABLE語句中的FOREIGN KEY語法,但不能使用或保存它。未來將進行延伸,能夠將這類訊息保存到資料表規範檔案中,以便能被mysqldump和ODBC檢索。稍後,還將為MyISAM資料表實現外部鍵約束。
外部鍵增強為資料庫開發人員提供了多項益處:
· 假定關聯設計恰當,外部鍵約束使得程式員更難將不一致性引入資料庫。
· 資料庫伺服器具有集中式約束檢查功能,因而沒有必要在應用程式一側執行這類檢查。這樣,就消除了不同應用程式使用不同方式檢查約束的可能性。
· 使用級聯更新和刪除,簡化了應用程式代碼。
· 設計恰當的外部鍵有助於以文檔方式記錄資料表間的關係。
請記住,這些好處是以資料庫伺服器為執行必要檢查而需的額外開銷為代價的。伺服器額外檢查會影響性能,對於某些應用程式,該特性不受歡迎,應盡量避免。(出於該原因,在一些主要的商業應用程式中,在應用程式級別上實施了外部鍵邏輯)。
MySQL允許資料庫開發人員選擇要使用的方法。如果您不需要外部鍵,並希望避免與強制引用完整性有關的開銷,可選擇另一種資料表類型取而代之,如MyISAM。(例如,MyISAM儲存引擎為僅執行INSERT和SELECT操作的應用程式提供了極快的性能,這是因為插入能和檢索同時進行)。請參見7.3.2節,「資料表鎖定事宜」。
如果您不打算利用引用完整性檢查具備的優點,請記住下述要點:
· 不存在伺服器端外部鍵關聯檢查時,應用程式本身必須處理這類關聯事宜。例如,將行按恰當順序插入資料表時應謹慎,並應避免產生孤立的子記錄。必須能夠在多記錄插入操作期間更正出現的錯誤。
· 如果ON DELETE是應用程式所需的唯一引用完整性功能,請注意,從MySQL伺服器4.0起,可以使用多資料表DELETE語句,用單一語句從多個資料表中刪除行。請參見13.2.1節,「DELETE語法」。
· 從具有外部鍵的資料表刪除記錄時,在缺少ON DELETE的情況下,一種解決方式是為應用程式增加恰當的DELETE語句。實際上,它與使用外部鍵同樣快,而且移植性更好。
注意,使用外部鍵在某些情況下會導致問題。
· 外部鍵支援能處理很多引用完整性事宜,但仍需要仔細設計鍵的關係,以避免循環規則或不正確的級聯刪除組合。
· DBA需要建立關聯拓撲,這會使從備份中恢復單獨資料表變得困難,該類情形並不罕見。(加載依賴其他資料表的資料表時,MySQL允許您臨時禁止外部鍵檢查,從而降低了該難度)。請參見15.2.6.4節,「FOREIGN KEY約束」。在MySQL 4.1.1以前。重新加載時,mysqldump能夠生成自動利用該性能的轉儲檔案。
注意,SQL中的外部鍵用於檢查和強制引用完整性,而不是聯合資料表。如果打算用SELECT語句獲取多個資料表的結果,可在資料表之間執行聯合操作:
SELECT * FROM t1, t2 WHERE t1.id = t2.id;
請參見13.2.7.1節,「JOIN語法」。請參見3.6.6節,「使用外部鍵」。
ODBC應用程式常使用不帶「ON DELETE ...」的FOREIGN KEY語法來生成自動WHERE子句。
在MySQL伺服器5.0版中實現了視圖功能(包括可更新視圖)。在5.0.1和更高版本中,提供了二進製版的視圖功能。請參見第22章:視圖。
View(視圖)十分有用,它允許用戶像單個資料表那樣訪問一組關係(資料表),而且僅允許對它們的這類訪問。視圖也能限制對行的訪問(特定資料表的子集)。對於列控制的訪問,可使用MySQL伺服器中的高級權限系統。請參見5.7節,「MySQL訪問權限系統」。
在設計視圖的過程中,我們的宏偉目標是,在SQL的範圍內盡可能與關聯資料庫系統的「Codd's Rule #6」兼容。「所有理論上可更新的視圖,實際上也應是可更新的」。
一些其他SQL資料庫採用「--」作為註釋開始標誌。MySQL伺服器採用「#」作為註釋起始字元。對於MySQL伺服器,也能使用C風格的註釋:/*該處為註釋*/。請參見9.5節,「註釋語法」。
MySQL伺服器3.23.3和更高版本支援「--」註釋風格,但要求註釋後面跟1空格(或控制字元,如新行)。之所以要求使用空格,是為了防止與自動生成SQL查詢有關的問題,它採用了類似下面的代碼,其中,自動為「!payment!」插入「payment」的值:
UPDATE account SET credit=credit-!payment!
考慮一下,如果「payment」的值為負數如「-1」時會出現什麼情況:
UPDATE account SET credit=credit--1
在SQL中「credit--1」是合法的資料表達式,但是,如果「--1」被解釋為註釋開始,部分資料表達式將被捨棄。其結果是,資料表達式的意義與預期的意義完全不同。
UPDATE account SET credit=credit
該語句不會對值作任何更改!這表明,允許註釋以「--」開始會產生嚴重後果。
採用MySQL伺服器3.23.3和更高版本中的這類註釋方法,「credit--1」實際上很安全。
另一個安全特性是,mysql命令行客戶端將刪除所有以「--」開頭的行。
僅當使用高於3.23.3的MySQL時,下述訊息才有意義:
如果有1個文本檔案形式的SQL程式,該檔案包含「--」註釋,應按下述方式使用replace實用工具,將其轉換為使用「#」字元的註釋:
shell> replace " --" " #" < text-file-with-funny-comments.sql \
| mysql db_name
而不是通常的:
shell> mysql db_name < text-file-with-funny-comments.sql
您也可以編輯註釋檔案,將「--」註釋更改為「#」註釋:
shell> replace " --" " #" -- text-file-with-funny-comments.sql
使用下述命令將其改回去:
shell> replace " #" " --" -- text-file-with-funny-comments.sql
使用MySQL,您可以使用允許回滾的事務資料表,以及不允許回滾的非事務資料表。因此,在MySQL中的約束處理功能與其他DBMS中的略有不同。在非事務性資料表中插入或更新大量行時,當出現錯誤以至於不能回滾所作的變更時,必須處理該情況。
其基本原理在於,在解析將要執行的語句的同時,MySQL伺服器會盡量為檢測到的問題生成錯誤訊息,並會在執行語句的同時盡量恢復出現的錯誤。在大多數情況下我們均是這樣作的,但不包括所有情況。
出現錯誤時,MySQL可選擇中途中止語句,或盡可能恢復並繼續執行語句。預設情況下,伺服器將採取後一種路線。這意味著,伺服器可能會強制將非法值變為最接近的合法值(例如)。
從MySQL 5.0.2開始,提供了數種SQL模式,使用它們,能夠對如何接受可能為不良數據值的方式進行更好的控制,也能在出現錯誤時,對是否繼續執行語句或放棄語句進行控制。使用這些選項,能夠將MySQL伺服器配置為更為傳統的風格,類似於拒絕不恰當輸入的其他DBMS。可以在運行時設置SQL模式,這樣,各客戶端就能選擇與其需求最為貼切的行為。請參見5.3.2節,「SQL伺服器模式」。
在以下部分,介紹了使用不同約束類型的情況。
通常情況下,當您試圖INSERT或UPDATE會導致主鍵、唯一鍵或外部鍵衝突的行時,將出現錯誤。如果您正在使用事務性儲存引擎時,如InnoDB,MySQL會自動回滾語句。如果您正在使用非事務性儲存引擎,MySQL將在出錯的行上停止執行語句,剩餘的行也不再處理。
如果您希望忽略這類鍵衝突,可使用MySQL支援的、用於INSERT和UPDATE的IGNORE關鍵字。在這種情況下,MySQL將忽略任何鍵衝突,並繼續處理下一行。請參見13.2.4節,「INSERT語法」。請參見3.2.10節,「UPDATE語法」。
使用mysql_info() C API函數,能夠獲取關於實際插入或更新行數的訊息。請參見25.2.3.34節,「mysql_info()」。在MySQL 4.1和更高版本中,也能使用SHOW WARNINGS語句。請參見13.5.4.22節,「SHOW WARNINGS語法」。
目前,只有InnoDB資料表支援外部鍵。請參見15.2.6.4節,「FOREIGN KEY約束」。計劃在MySQL 5.1中實施對MyISAM資料表的外部鍵支援。
在MySQL 5.0.2之前,MySQL對非法或不當值並不嚴厲,而且為了數據輸入還會強制將它們變為合法值。在MySQL 5.0.2和更高版本中,保留了以前的預設行為,但您可以為不良值選擇更傳統的處理方法,從而使得伺服器能夠拒絕並放棄出現不良值的語句。本節介紹了MySQL的預設行為(寬大行為),新的嚴格的SQL模式,以及它們的區別。
如果您未使用嚴格模式,下述情況是真實的。如果將「不正確」的值插入到列,如將NULL值插入非NULL列,或將過大的數值插入數值列,MySQL會將這些列設置為「最可能的值」,而不是生成錯誤訊息。
· 如果試圖將超範圍的值保存到數值列,MySQL伺服器將保存0(最小的可能值)取而代之,或最大的可能值。
· 對於字串,MySQL或保存空字串,或將字串盡可能多的部分保存到列中。
· 如果打算將不是以數值開頭的字串保存到數值列,MySQL將保存0。
· MySQL允許將特定的不正確日期值保存到DATE和DATETIME列(如「2000-02-31」或「2000-02-00」)。其觀點在於,驗證日期不是SQL伺服器的任務。如果MySQL能保存日期值並準確檢索相同的值,MySQL就能按給定的值保存它。如果日期完全不正確(超出伺服器能保存的範圍)將在列中保存特殊的日期值「0000-00-00」取而代之。
· 如果試圖將NULL值保存到不接受NULL值的列,對於單行INSERT語句,將出現錯誤。對於多行INSERT語句或INSERT INTO ... SELECT語句,MySQL伺服器會保存針對列數據類型的隱含預設值。一般情況下,對於數值類型,它是0,對於字串類型,它是空字串(''),對於日期和時間類型是「zero」。在13.1.5節,「CREATE TABLE語法」一節中,討論了隱含的預設值。
· 如果INSERT語句未為列指定值,如果列定義包含明確的DEFAULT子句,MySQL將插入預設值。如果在定義中沒有這類DEFAULT子句,MySQL會插入列數據類型的隱含預設值。
採用前述規則的原因在於,在語句開始執行前,無法檢查這些狀況。如果在更新了數行後遇到這類問題,我們不能僅靠回滾解決,這是因為儲存引擎可能不支援回滾。中止語句並不是良好的選擇,在該情況下,更新完成了「一半」,這或許是最差的情況。對於本例,較好的方法是「僅可能做到最好」,然後就像什麼都未發生那樣繼續。
在MySQL 5.0.2和更高版本中,可以使用STRICT_TRANS_TABLES或STRICT_ALL_TABLES SQL模式,選擇更嚴格的處理方式。請參見5.3.2節,「SQL伺服器模式」。
STRICT_TRANS_TABLES的工作方式:
· 對於事務性儲存引擎,在語句中任何地方出現的不良數據值均會導致放棄語句並執行回滾。
· 對於非事務性儲存引擎,如果錯誤出現在要插入或更新的第1行,將放棄語句。(在這種情況下,可以認為語句未改變資料表,就像事務資料表一樣)。首行後出現的錯誤不會導致放棄語句。取而代之的是,將調整不良數據值,並給出告警,而不是錯誤。換句話講,使用STRICT_TRANS_TABLES後,錯誤值會導致MySQL執行回滾操作,如果可以,所有更新到此為止。
要想執行更嚴格的檢查,請啟用STRICT_ALL_TABLES。除了非事務性儲存引擎,它與STRICT_TRANS_TABLES等同,即使當不良數據出現在首行後的其他行,所產生的錯誤也會導致放棄語句。這意味著,如果錯誤出現在非事務性資料表多行插入或更新過程的中途,僅更新部分結果。前面的行將完成插入或更新,但錯誤出現點後面的行則不然。對於非事務性資料表,為了避免這種情況的發生,可使用單行語句,或者在能接受轉換警告而不是錯誤的情況下使用STRICT_TRANS_TABLES。要想在第1場合防止問題的出現,不要使用MySQL來檢查列的內容。最安全的方式(通常也較快)是,讓應用程式負責,僅將有效值傳遞給資料庫。
有了嚴格的模式選項後,可使用INSERT IGNORE或UPDATE IGNORE而不是不帶IGNORE的INSERT或UPDATE,將錯誤當作告警對待。
ENUM和SET列提供了定義僅能包含給定值集合的列的有效方式。但是,從MySQL 5.0.2起,ENUM和SET不是實際約束。其原因與不重視NOT NULL的原因一樣。請參見1.8.6.2節,「對無效數據的約束」。
ENUM列總有1個預設值。如果未指定預設值,對於包含NULL的列,預設值為NULL;否則,第1個枚舉值將被當作預設值。
如果在ENUM列中插入了不正確的值,或者,如果使用IGNORE將值強制插入了ENUM列,會將其設置為保留的枚舉值0,對於字串情形,將顯示為空字串。請參見11.4.4節,「ENUM類型」。
如果在SET列中插入了不正確值,該值將被忽略。例如,如果列能包含值「a」、「b」和「c」,並賦值「a,x,b,y」,結果為「a,b」。請參見11.4.5節,「SET類型」。
從5.0.2開始,可以對伺服器進行配置,以使用嚴格的SQL模式。請參見5.3.2節,「SQL伺服器模式」。啟用嚴格模式後,ENUM或SET列的定義可作為對輸入至列的值的約束。如果值不滿足下述條件,將出現錯誤:
· ENUM值必須是在列定義中給出的值之一,或內部的數字等同物。該值不能是錯誤值(即,0或空字串)。對於定義為ENUM('a','b','c')的列,諸如''、'd'和'ax'等,均是非法的,並將被拒。
· SET值必須是空字串,或由1個或多個在列定義中給出的且用逗號隔開的值組成。 對於定義為SET('a','b','c')的列,諸如'd'和'a,b,c,d'等,均是非法的,並將被拒。
如果使用了INSERT IGNORE或UPDATE IGNORE,在嚴格模式下,可抑制無效值導致的錯誤。在這種情況下,將生成警告而不是錯誤。對於ENUM,值將作為錯誤成員(0)插入。對於SET,會將給定值插入,但無效的子字串將被刪除。例如,'a,x,b,y'的結果是'a,b',就像前面介紹的那樣。
這是MySQL參考手冊的翻譯版本,關於MySQL參考手冊,請訪問dev.mysql.com。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。