第1章:一般信息

MySQL?軟件提供了十分快速的多線程、多用戶、牢靠的SQL(結構化查詢語言)數據庫服務器。 MySQL服務器定位于任務關鍵型、重負荷生產系統,并能嵌入在大量部署的軟件中。MySQL是MySQL AB的注冊商標。

MySQL軟件采用雙許可方式。用戶可根據GNU通用公共許可(http://www.fsf.org/licenses/)條款,將MySQL軟件作為開放源碼產品使用,或從MySQL AB公司購買標準的商業許可證。關于我方許可策略的更多信息,請參見http://www.mysql.com/company/legal/licensing/

在下面的清單中,介紹了本手冊感興趣的一些特殊部分。

重要說明:

請將錯誤報告(通常稱為缺陷)以及問題和評論發送到http://bugs.mysql.com。請參見 1.7.1.3 “如何通報缺陷和問題”

如果在MySQL服務器中發現敏感的安全缺陷,請使用電子郵件立刻通知我們:security@mysql.com

1.1.?關于本手冊

這是關于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所有。MySQL?和MySQL徽標均是MySQL AB的注冊商標。本手冊中引用的其他商標和注冊商標是相應所有人的財產,在本手冊中僅將其用于辨識目的。

1.2.?本手冊采用的慣例

本手冊采用了特定的印刷慣例:

·???????? 這類風格的文本用于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平臺上,它通常是程序,如shcshbash。在Windows平臺下,等效程序為command.comcmd.exe,通常運行在控制臺窗口中。

輸入示例中顯示的命令或語句時,不要輸入示例中給出的提示符。

數據庫、表和;列名必須代入語句中。為了指明該代入是必要的,在本手冊中使用了db_nametbl_namecol_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=valuesome_command

如果你正在使用cshtcsh,必須使用略有不同的命令。應執行與下例所示類似的序列:

shell> setenv VARNAMEvalue
shell> some_command

1.3.?MySQL AB概述

MySQL AB是由MySQL創始人和主要開發人創辦的公司。MySQL AB最初是由David Axmark、Allan Larsson和Michael“Monty”Widenius在瑞典創辦的。

我們致力于開發MySQL數據庫軟件,并向新用戶宣傳推廣它。MySQL AB擁有MySQL源代碼、MySQL徽標和(注冊)商標、以及本手冊的版權。請參見

1.4 “MySQL數據庫管理系統概述”

MySQL的核心價值取向指明了我們對MySQL和開發源碼的貢獻。

這些核心價值取向規定了MySQL AB與MySQL服務器軟件的協作方式:

·???????? 成為世界上最好和使用最廣泛的數據庫。

·???????? 面向所有人,而且所有人均能支付得起。

·???????? 使用簡單。

·???????? 在保持快速和安全的同時不斷改進。

·???????? 使用和改進充滿樂趣。

·???????? 不存在缺陷。

這就是MySQL AB公司及其雇員的核心價值取向。

·???????? 我們同意開放源碼理念,并支持開放源碼群。

·???????? 我們的目標是成為最佳公民。

·???????? 我們傾向于那些與我們有共同價值取向和思想傾向的合作伙伴。

·???????? 我們將回復電子郵件并提供支持。

·???????? 我們是一家與其他方聯系在一起的“虛擬”公司。

·???????? 我們反對軟件專利。

在MySQL的網站(http://www.mysql.com/)上,給出了關于MySQL和MySQL的最新信息。

順便提及一下,公司名中的“AB”是瑞典語“aktiebolag”或“股份公司”的首字母縮寫。可將其翻譯為“MySQL有限公司”。事實上,MySQL有限公司和MySQLGmbH均是MySQL AB子公司的名稱。它們分別位于美國和德國。

1.4.?MySQL數據庫管理系統概述

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”或其他當地方式。

1.4.1.?MySQL的歷史

我們最初的出發點是,使用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的母國烏干達。

1.4.2.?MySQL的的主要特性

下面介紹了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字節長,FLOATDOUBLECHARVARCHARTEXTBLOBDATETIMEDATETIMETIMESTAMPYEARSETENUM,以及OpenGIS空間類型。請參見第11章:列類型

    • 定長和可變長度記錄。

  • 語句和函數

    • 在SELECT和查詢的WHERE子句中,提供完整的操作符和函數支持。例如:

      mysql> SELECT CONCAT(first_name, ' ', last_name)
          -> FROM citizen
          -> WHERE income/dependents > 10000 AND age > 30;
    • 對SQL GROUP BYORDER BY子句的全面支持。支持聚合函數(COUNT(), COUNT(DISTINCT ...)AVG()STD()SUM()MAX()MIN()GROUP_CONCAT())。

    • 支持LEFT OUTER JOINRIGHT OUTER JOIN,采用標準的SQL和ODBC語法。

    • 按照標準SQL的要求,支持表別名和列別名。

    • DELETE、INSERTREPLACE和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)。索引可使用具備CHARVARCHARBLOBTEXT列類型的列前綴。

  • 連接性

    • 在任何平臺上,客戶端可使用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)、germanbig5ujis等。例如,在表名和列名中允許使用斯堪的納維亞字符‘?’、‘?’和‘?’。從MySQL 4.1開始,提供了Unicode支持。

    • 所有數據均以所選的字符集保存。正常字符串列的比較不區分大小寫。

    • 分類是根據所選的字符集(默認情況下,使用瑞典校對)進行的。啟動MySQL服務器時,可更改該項設置。要想查看高級分類的示例,請參見Czech分類代碼。MySQL服務器支持眾多不同的字符集,這類字符集可在編譯時和運行時指定。

  • 客戶端和工具

    • MySQL服務器提供了對SQL語句的內部支持,可用于檢查、優化和修復表。通過mysqlcheck客戶端,可在命令行上使用這類語句。MySQL還包括myisamchk,這是一種很快的命令行實用工具,可用于在MyISAM表上執行這類操作。請參見第5章:數據庫管理

    • 對于所有MySQL程序,均能通過“-help”或“-?”選項調用,以獲取聯機幫助信息。

1.4.3.?MySQL穩定性

本節回答了如下問題:“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驅動程序或底層數據庫服務器無關。

1.4.4.?MySQL表最大能達到多少

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_LENGTHMAX_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存儲引擎”

1.4.5.?2000年兼容性

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年的DATEDATETIME值方面不存在問題,在處理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位機器上,支持的取值范圍是1970010100000020300101000000(帶符號值)。在64位機器上,TIMESTAMP能處理的值達2106(無符號值)

盡管MySQL服務器本身不存在2000年安全問題,但如果使用了存在Y2K問題的應用程序,也會遇到問題。例如,很多早期的應用程序采用2位數值(兩可性)而不是4位數值來保存和處理年份數據。這類問題可能會被使用“00”或“99”的應用程序合并為“丟失”值指示符。很不幸,這類問題或許很難更正,這是因為不同的應用程序是由不同的程序員編寫的,每位程序員可能使用了不同的慣例集和日期處理函數。

因此,盡管MySQL服務器不存在Y2K問題,但應用程序須提供無歧義的輸入值。關于MySQL服務器在處理含2位年份數值的兩可性日期輸入數據方面的作用,請參見11.3.4節,“Y2K事宜和日期類型”

1.5.?MaxDB數據庫管理系統概述

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提供了全面的專業服務組合。

1.5.1.?什么是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。

1.5.2.?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全面質量保證計劃的控制。

1.5.3.?MaxDB的特性

MaxDB是一種大型、通過SAP認證的開放源碼數據庫,可用于OLTP和OLAP,它具有高的可靠性、可用性和可伸縮性,以及相當完善的特性集。它定位于大型mySAP商業套件環境,以及需要最大企業級數據庫功能的其他應用,此外,它還補充了MySQL數據庫服務器。

MaxDB是采用客戶端/服務器模式運作的產品。開發它的目的在于滿足OLTP和數據倉庫/OLAP/決策支持方面的安裝需求。優點:

·???????? 簡單的配置和管理: 基于GUI(圖形化用戶界面)的安裝管理器和數據庫管理器,可作為DBMS操作的單個管理工具。

·???????? 不間斷操作,無需計劃的停機時間,也不需要持久性維護:自動空間管理,無需重組。

·???????? 精心設計的備份和恢復能力:聯機備份和增量備份,恢復向導以指導你完成整個恢復步驟。

·???????? 支持大量用戶,數TB的數據庫大小,以及苛刻的工作量要求: 高的可靠性,性能和可伸縮性

·???????? 高可用性: 簇支持,待機配置,熱待機配置

1.5.4.?許可和支持

使用MySQL AB提供的其他產品的許可證,可使用MaxDB。因此,可在GNU通用公共許可下以及商業許可下使用MaxDB。關于許可的更多信息,請訪問http://www.mysql.com/company/legal/licensing/

MySQL AB負責為非SAP客戶提供MaxDB技術支持。MaxDB支持可在各種層面上提供(基本,銀質和金質),將無限的電子郵件/Web支持擴展為對業務關鍵系統的全天候電話支持。

當MaxDB與Sap應用程序(如SAP NetWeaver和mySAP商業套件)一起使用時,MySQL AB還能為其提供許可證和支持。關于能滿足您需求的許可和支持方面的更多信息,請聯系MySQL AB。

我們也提供咨詢和培訓服務。MySQL將定期提供MaxDB課程,關于課程表,請參見http://www.mysql.com/training/

1.5.5.?MaxDB和MySQL之間的特性差異

MaxDB是MySQL AB公司通過SAP認證的數據庫。MaxDB數據庫服務器補充了MySQL AB產品系列。某些MaxDB特性在MySQL數據庫服務器上不可用,反之亦然。

下面簡要介紹了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不具備的管理特性: 按時間、事件和告警進行規劃安排,并能在達到告警閾值時將消息發送給數據庫管理器。

1.5.6.?MaxDB和MySQL之間的協同性

MaxDB和MySQL是獨立的數據庫管理服務器。系統間的協同性是可能的,通過相應的方式,系統能夠彼此交換數據。要想在MaxDB和MySQL之間交換數據,可使用系統的導入和導出工具,或MaxDB同步管理器。對于導入和導出工具,可在手動模式下傳輸數據(很少出現)。MaxDB同步管理器提供了更快的數據傳輸功能。

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的復制支持。

1.5.7.?與MaxDB有關的鏈接

關于MaxDB信息的主頁位于http://www.mysql.com/products/maxdb。在該頁面上,詳細介紹了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應用程序的問題。

1.6.?MySQL發展大事記

在本節中,介紹了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.05.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

1.6.1.?MySQL 5.1的新特性

關于我們打算在MySQL 5.1中增加的特性列表,請參見1.6節,“MySQL發展大事記”。隨著5.1版的不斷發展,我們將在本節增加更多詳細信息。

另請參見第18章:分區

1.7.?MySQL信息源

1.7.1.?MySQL郵件列表

在本節中介紹了MySQL郵件列表,并給出了使用郵件列表的指南。訂購郵件列表后,將以電子郵件消息的形式收到所有已記錄的信息。你也可以將自己的問題和解答發送至郵件列表。

1.7.1.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.addresshttp://www.4t2.com/mysql/站點上,可找到關于該郵件列表的更多信息。

·???????? <mysql-br-request@listas.linkway.com.br>

葡萄牙語郵件列表。發送電子郵件訂購mysql-br your@email.address

·???????? <mysql-alta@elistas.net>

西班牙語郵件列表。發送電子郵件訂購mysql your@email.address

1.7.1.2.?請教問題或通報缺陷

張貼缺陷報告或問題之前,請:

·???????? 首先搜索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郵件列表,具體內容見下一節。

1.7.1.3.?如何通報缺陷和問題

通報缺陷的正常地址是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_nametbl_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文件。

使用targzipzip創建文件的壓縮包檔案,并使用FTP將檔案傳輸到ftp://ftp.mysql.com/pub/mysql/upload/。然后將問題提交到我們的缺陷數據庫中,http://bugs.mysql.com/

·???????? 如果你認為MySQL服務器生成了奇怪的查詢結果,不僅應包含結果,還應給出你對該結果的看法,以及支持觀點的基礎。

·???????? 提供問題的示例時,最好使用實際情況下已有的變量名、表名等,而不是新名稱。問題可能與變量名或表名有關。或許這類情況很罕見,但安全總比道歉強。歸根結底,對你來說,提供關于實際情況的示例要簡單些,當然對我們也更好。如果你的數據不打算展示給其他人,請使用FTP將其傳輸到ftp://ftp.mysql.com/pub/mysql/upload/。如果信息是高度保密的,而且你甚至不打算向我們展示,請使用其他名稱給出示例,但請注意,這應是最后的選擇。

·???????? 如果可能,應包含相關程序的所有選項。例如,應指明啟動mysqld服務器時使用的選項,以及用來運行MySQL客戶端程序的選項。對于程序(如mysqldmysql)選項以及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 TABLEREPAIR 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問題或缺陷”

關于某些常見問題的解決方案,請參見附錄A:問題和常見錯誤

將答案單獨發送給你而不是發送到郵件列表時,良好的禮節是,對回答進行歸納總結并將結果發送到郵件列表,以便其他人也能從你所收到、并解決了問題的回應中受益。

1.7.1.4.?在郵件列表上回答問題的指南

如果你認為自己的解答會引起廣泛關注,可以將其張貼到郵件列表,而不是直接回復請教的個人。盡量使你的解答具有普遍性,以便除初始發起人之外的其他人也能從中受益。將解答張貼到郵件列表時,請確認你的解答不是已有答案的復制品。

在你的回復中,應盡量歸納問題的基本部分,沒有必要一定引用全部初始信息。

在要在打開HTML模式的情況下從瀏覽器張貼郵件信息。很多用戶不使用瀏覽器來閱讀郵件。

1.7.2.?IRC(在線聊天系統)上的MySQL社區支持

除了各種MySQL郵件列表外,在IRC(在線聊天系統)上,也能發現有經驗的社區成員。以下是目前我們已知的最好的網絡/渠道:

·???????? Freenode(請參見http://www.freenode.net/以查找服務器信息)

o??????? #mysql,主要針對MySQL問題,也歡迎其他數據庫和一般的SQL問題。與MySQL一起使用PHP、Perl或C方面的問題也很常見。

如果你正在尋找URC客戶端軟件,以便連接到IRC網絡,請訪問xChathttp://www.xchat.org/)。X-Chat(GPL許可)即能用于Unix平臺,也適用于Windows平臺(免費的面向Windows的X-Chat可從站點http://www.silverex.org/download/上下載)。

1.7.3.?MySQL論壇上的MySQL社區支持

最新的社區支持資源是位于下述站點的論壇:http://forums.mysql.com

有各種可用論壇,分為以下大類:

·???????? 移植

·???????? MySQL用法

·???????? MySQL連接器

·???????? 編程語言

·???????? 工具

·???????? 第三方應用程序

·???????? 存儲引擎

·???????? MySQL技術

·???????? SQL標準

·???????? 業務

1.8.?MySQL標準的兼容性

在本節中,介紹了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簇

我們也正著手在數據庫服務器中提供XML支持。

1.8.1.?MySQL遵從的標準是什么

我們致力于支持全套ANSI/ISO SQL標準,但不會以犧牲代碼的速度和質量為代價。

ODBC級別0-3.51。

1.8.2.?選擇SQL模式

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服務器模式”

1.8.3.?在ANSI模式下運行MySQL

你可以使用“--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';

1.8.4.?MySQL對標準SQL的擴展

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??????? 你可以使用標準的系統命令來備份、重命名、移動、刪除、并拷貝由MyISAMISAM存儲引擎管理的表。例如,要想重命名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 TABLECHECK TABLEOPTIMIZE TABLE,以及REPAIR TABLE語句。

o??????? CREATE DATABASEDROP DATABASE語句。請參見13.1.3節,“CREATE DATABASE語法”

o??????? DO語句。

o??????? EXPLAIN SELECT獲取如何聯合表的介紹。

o??????? FLUSHRESET語句。

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_nameDROP col_name、或DROP INDEXIGNORERENAME。在ALTER TABLE語句中使用多個ADDALTERDROPCHANGE子句。請參見13.1.2節,“ALTER TABLE語法”

o??????? 使用索引名,字段前綴上的索引,并在CREATE TABLE語句中使用INDEXKEY。請參見13.1.5節,“CREATE TABLE語法”

o??????? CREATE TABLE一起使用TEMPORARYIF NOT EXISTS

o??????? DROP TABLE一起使用IF EXISTS。

o??????? 使用單個DROP TABLE語句,能夠舍棄多個表。

o??????? UPDATEDELETE語句的ORDER BYLIMIT子句。

o??????? INSERT INTO ... SET col_name = ... syntax.

o??????? INSERTREPLACE語句的DELAYED子句。

o??????? INSERTREPLACEDELETEUPDATE語句的LOW_PRIORITY子句。

o??????? SELECT語句中使用INTO OUTFILESTRAIGHT_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??????? 列類型MEDIUMINTSETENUM、以及不同的BLOBTEXT類型。

o??????? 列屬性AUTO_INCREMENTBINARYNULLUNSIGNED以及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??????? 默認情況下,所有的字符串比較均區分大小寫,其分類順序由當前字符集確定(默認為cp1252 Latin1)。如果你不喜歡該點,應使用BINARY屬性或BINARY cast聲明列,這樣,就會使用基本的字符代碼值進行比較,而不是詞匯順序。

o??????? %”操作符等同于MOD()。也就是說“N % M等同于MOD(N,M)。Cyuyan的程序員支持“%”,而且它也是為了兼容PostgreSQL而使用的。

o??????? 在列比較中,可在SELECT語句的FROM左側使用=<><=<>=><<>><=>ANDORLIKE操作符。例如:

o???????????????????? mysql> SELECT col1=1 AND col2=2 FROM tbl_name;

o??????? 返回最近AUTO_INCREMENT值的LAST_INSERT_ID()函數。請參見12.9.3節,“信息函數”

o??????? 允許在數值列上使用LIKE。

o??????? REGEXPNOT REGEXP擴展了常規的表達式操作符。

o??????? 具有1個或2個以上參量的CONCAT()CHAR()。(在MySQL服務器中,這些函數可以有任意數目的參量)。

o??????? BIT_COUNT()CASEELT()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子句同時使用的函數和修改程序

1.8.5.?MySQL與標準SQL的差別

我們試圖使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()函數不支持對REALBIGINT的拋棄。請參見12.8節,“Cast函數和操作符”

·???????? 標準SQL要求,SELECT語句中的HAVING子句能夠引用GROUP BY子句中的列。在MySQL 5.0.2之前,不能完成該功能。

1.8.5.1.?子查詢

MySQL 4.1支持子查詢和導出表。“子查詢”指的是嵌套在另一語句中的SELECT語句。“導出表”(未命名視圖)是另一語句的FROM子句中的子查詢。請參見13.2.8節,“Subquery語法”

從MySQL 4.1版起,可以使用聯合或其他方法重寫大多數子查詢。關于如何完成該任務的更多信息,請參見13.2.8.11節,“對于較早的MySQL版本,采用聯合方法重寫子查詢”

1.8.5.2.?SELECT INTO TABLE

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語句”

1.8.5.3.?事務和原子操作

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_backmoney_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;

1.8.5.4.?存儲程序和觸發程序

對于MySQL,在5.0版本中實現了存儲程序。請參見第20章:存儲程序和函數

從5.0.2版開始,在MySQL中實現了基本的觸發器功能,計劃在MySQL 5.1中進一步發展它。請參見第21章:觸發程序

1.8.5.5.?外鍵

在MySQL服務器3.23.44和更高版本中,InnoDB存儲引擎支持對外鍵約束的檢查功能,這些約束包括CASCADEON DELETEON UPDATE。請參見15.2.6.4節,“FOREIGN KEY約束”

對于InnoDB之外的其他存儲引擎,MySQL服務器能夠解析CREATE TABLE語句中的FOREIGN KEY語法,但不能使用或保存它。未來將進行擴展,能夠將這類信息保存到表規范文件中,以便能被mysqldump和ODBC檢索。稍后,還將為MyISAM表實現外鍵約束。

外鍵增強為數據庫開發人員提供了多項益處:

·???????? 假定關聯設計恰當,外鍵約束使得程序員更難將不一致性引入數據庫。

·???????? 數據庫服務器具有集中式約束檢查功能,因而沒有必要在應用程序一側執行這類檢查。這樣,就消除了不同應用程序使用不同方式檢查約束的可能性。

·???????? 使用級聯更新和刪除,簡化了應用程序代碼。

·???????? 設計恰當的外鍵有助于以文檔方式記錄表間的關系。

請記住,這些好處是以數據庫服務器為執行必要檢查而需的額外開銷為代價的。服務器額外檢查會影響性能,對于某些應用程序,該特性不受歡迎,應盡量避免。(出于該原因,在一些主要的商業應用程序中,在應用程序級別上實施了外鍵邏輯)。

MySQL允許數據庫開發人員選擇要使用的方法。如果你不需要外鍵,并希望避免與強制引用完整性有關的開銷,可選擇另一種表類型取而代之,如MyISAM。(例如,MyISAM存儲引擎為僅執行INSERTSELECT操作的應用程序提供了極快的性能,這是因為插入能和檢索同時進行)。請參見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子句。

1.8.5.6.?視圖

在MySQL服務器5.0版中實現了視圖功能(包括可更新視圖)。在5.0.1和更高版本中,提供了二進制版的視圖功能。請參見第22章:視圖

View(視圖)十分有用,它允許用戶像單個表那樣訪問一組關系(表),而且僅允許對它們的這類訪問。視圖也能限制對行的訪問(特定表的子集)。對于列控制的訪問,可使用MySQL服務器中的高級權限系統。請參見5.7節,“MySQL訪問權限系統”

在設計視圖的過程中,我們的宏偉目標是,在SQL的范圍內盡可能與關聯數據庫系統的“Codd's Rule #6”兼容。“所有理論上可更新的視圖,實際上也應是可更新的”。

1.8.5.7.?‘--’作為注釋起始標記

一些其他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

1.8.6.?MySQL處理約束的方式

使用MySQL,你可以使用允許回滾的事務表,以及不允許回滾的非事務表。因此,在MySQL中的約束處理功能與其他DBMS中的略有不同。在非事務性表中插入或更新大量行時,當出現錯誤以至于不能回滾所作的變更時,必須處理該情況。

其基本原理在于,在解析將要執行的語句的同時,MySQL服務器會盡量為檢測到的問題生成錯誤信息,并會在執行語句的同時盡量恢復出現的錯誤。在大多數情況下我們均是這樣作的,但不包括所有情況。

出現錯誤時,MySQL可選擇中途中止語句,或盡可能恢復并繼續執行語句。默認情況下,服務器將采取后一種路線。這意味著,服務器可能會強制將非法值變為最接近的合法值(例如)。

從MySQL 5.0.2開始,提供了數種SQL模式,使用它們,能夠對如何接受可能為不良數據值的方式進行更好的控制,也能在出現錯誤時,對是否繼續執行語句或放棄語句進行控制。使用這些選項,能夠將MySQL服務器配置為更為傳統的風格,類似于拒絕不恰當輸入的其他DBMS。可以在運行時設置SQL模式,這樣,各客戶端就能選擇與其需求最為貼切的行為。請參見5.3.2節,“SQL服務器模式”

在以下部分,介紹了使用不同約束類型的情況。

1.8.6.1.?PRIMARY KEY和UNIQUE索引約束

通常情況下,當你試圖INSERTUPDATE會導致主鍵、唯一鍵或外鍵沖突的行時,將出現錯誤。如果你正在使用事務性存儲引擎時,如InnoDB,MySQL會自動回滾語句。如果你正在使用非事務性存儲引擎,MySQL將在出錯的行上停止執行語句,剩余的行也不再處理。

如果你希望忽略這類鍵沖突,可使用MySQL支持的、用于INSERTUPDATEIGNORE關鍵字。在這種情況下,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表的外鍵支持。

1.8.6.2.?對無效數據的約束

在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_TABLESSTRICT_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 IGNOREUPDATE IGNORE而不是不帶IGNORE的INSERTUPDATE,將錯誤當作告警對待。

1.8.6.3.?ENUM和SET約束

ENUMSET列提供了定義僅能包含給定值集合的列的有效方式。但是,從MySQL 5.0.2起,ENUMSET不是實際約束。其原因與不重視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服務器模式”。啟用嚴格模式后,ENUMSET列的定義可作為對輸入至列的值的約束。如果值不滿足下述條件,將出現錯誤:

·???????? ENUM值必須是在列定義中給出的值之一,或內部的數字等同物。該值不能是錯誤值(即,0或空字符串)。對于定義為ENUM('a','b','c')的列,諸如'''d''ax'等,均是非法的,并將被拒。

·???????? SET值必須是空字符串,或由1個或多個在列定義中給出的且用逗號隔開的值組成。 對于定義為SET('a','b','c')的列,諸如'd''a,b,c,d'等,均是非法的,并將被拒。

如果使用了INSERT IGNOREUPDATE IGNORE,在嚴格模式下,可抑制無效值導致的錯誤。在這種情況下,將生成警告而不是錯誤。對于ENUM,值將作為錯誤成員(0)插入。對于SET,會將給定值插入,但無效的子字符串將被刪除。例如,'a,x,b,y'的結果是'a,b',就像前面介紹的那樣。


這是MySQL參考手冊的翻譯版本,關于MySQL參考手冊,請訪問dev.mysql.com。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。