     [file include.texi not included]

     START-INFO-DIR-ENTRY
     * mysql: (mysql).               MySQL documentation.
     END-INFO-DIR-ENTRY

This is a manual for MySQL. This version is about the mysql_version version of MySQL. For a 3.20 version see the relevant distribution.

MySQL についての一般情報
***************

これは MySQL のリファレンスマニュアルです; これは MySQL バージョン mysql_version について記述しています。

MySQL は発展中なので、マニュアルは頻繁に更新されます。そのため、オンラインで参照しない限り、このバージョンが期限切れである可能性があります。このマニュアルの最新バージョンは http://www.mysql.com/doc.html に多様な形式で置いてあります。マニュアル内の情報を見つけるつらい時間を持つなら、検索可能 PHP バージョン http://www.mysql.com/php/manual.php3 を試すことが可能です。

MySQL はとても高速で、マルチスレッド、マルチユーザ、頑丈な SQL (Structured Query Language)データベースサーバです。

Unix と OS/2 プラットフォームでは MySQL は基本的に無償であり、Microsoft プラットフォームでは、30日の試用期間を過ぎて使用する場合に MySQL ライセンスを買わなければなりません. See Licensing and Support.

MySQL ホームページ (http://www.mysql.com/)は MySQL についての最新情報を提供しています。

次のリストはマニュアルのいくつかの有用なセクションを説明しています:

  * MySQL の能力の説明については、Features を参照してください。

  * インストール方法については Installing を参照してください。 MySQL を新しいマシンや OS に移行するためのヒントについては Porting を参照してください。

  * 3.21 リリースからのアップグレードについての情報は、 Upgrading-from-3.21 を参照してください。

  * MySQL 導入のチュートリアルについては、Tutorial を参照してください。

  * SQL の例とベンチマーク情報についてはベンチマーキングのディレクトリを参照してください。(sql-bench ディレクトリです)

  * 新しい機能とバグ修正の履歴については News を参照してください。

  * 現在知られているバグと無い機能の一覧については Bugs を参照してください。

  * 将来の計画については TODO を参照してください。

  * このプロジェクトへの全ての貢献者のリストについては Credits を参照してください。

重要:

エラー(バグ)レポート、質問、コメントはメーリングリスト mysql@lists.mysql.com に送ってください。See Bug reports。バグレポートを生成するためには mysqlbug スクリプトを使用すべきです。ソースディストリビューションでは、mysqlbug スクリプトは scripts ディレクトリに見つけることができます。バイナリディストリビューションでは、mysqlbug は bin ディレクトリに見つけることができます。

このマニュアルへの追加または修正に関連する提案がある場合は、それらを MySQL マニュアルチーム (docs@mysql.com)に送ってください。

MySQL とは何か？
===========

MySQL は本当にマルチユーザ、マルチスレッドの SQL データベースサーバです。SQL は世界でもっともポピュラーなデータベース言語です。MySQL は、サーバデーモン mysqld と多くの種類のクライアントプログラムとライブラリからなるクライアント/サーバ実装です。

SQLは、情報を保存し、更新し、そしてアクセスすることを簡単にするために標準化された言語です。例えば、あなたは、商品案内を検索するためにSQLを使って、ウェブサイトに関するカスタマー情報を蓄積することができます。 MySQL は、ログや写真を保存させるにも、十分にはやく、フレキシブルです。

MySQL の主な目的は高速で頑丈で簡単に使用できることです。 MySQL は独自に開発されました。我々は、とても大きなデータベースを、他のデータベースベンダが我々に提供するものよりも速く、重要度の順に処理できる SQL サーバを必要としていたからです。我々は、10,000 テーブルを含む 40 以上のデータベースの環境で 1996 年から MySQL を使用しています。そのテーブルの 500 テーブル以上は 700万以上のレコードを持ちます。これは約100ギガバイトの、基幹業務のデータです。

MySQL が作成される上での基本は、何年もの間、製品環境の高い要求で使用されていたルーチンのセットです。MySQL はまだ開発中ですが、豊富でとても有用な関数セットを既に提供しています。

MySQL の公式な発音は ``My Ess Que Ell'' です(MY-SEQUEL ではありません)。

このマニュアルについて
===========

このマニュアルは以下の方々により訳されました (ハンドル名だけ書きます。敬称略。翻訳サーバーに登録した順 :) )：

  * 民斗

  * hama

  * dale

  * kippara

  * kenji

  * aoki

  * tok21108

  * こむら

  * tamori

このマニュアルは現在 Texinfo, プレーンテキスト, Info, HTML, PostScript, PDF バージョンがあります。サイズが大きいため Postscript と PDF バージョンは MySQL のディストリビューションには含まれていませんが、別にダウンロードするようになっています。http://www.mysql.com/.

プライマリドキュメントは Texinfo ファイルです。HTML バージョンは texi2html の変更されたバージョンで自動的に提供されます。プレーンテキストと Info バージョンは makeinfo で提供されます。PostScript バージョンは texi2dvi と divps を使用して提供されます。PDF バージョンは Ghostscript ユーティリティ ps2pdf で提供されます。

このマニュアルは David Axmark, Michael (Monty) Widenius, Paul DuBois, によって作成され、維持されています。他の貢献者については Credits を参照してください。

このマニュアル中で使用されている表記
------------------

このマニュアルは特定の印刷上の表記を使用しています:

constant
     固定幅フォントは次のものに使用されます。コマンド名, オプション; SQL ステートメント; データベース名, テーブル名, フィールド名; C と Perl コード; 環境変数。例: ``mysqladmin がどのように動作するかを見るためには、 --help オプションをつけて起動してください。''

filename
     引用符で括られた固定幅フォントはファイル名とパス名に使用されます。例: `` ディストリビューションは /usr/local ディレクトリ配下にインストールされます。''

c
     引用符で括られた固定幅フォントは文字シーケンスを示すためにも使用されます。例: ``ワイルドカードを指定するためには、% 文字を使用してください。''

italic
     イタリックフォントは強調のために使用されます, このように。

boldface
     ボールドフォントはアクセス権名(例えば、``process 権を容易に与えないでください'')と、特に強い強調を伝えるために使用されます。

コマンドが特定のプログラムによって実行されることを意味することを表す時、コマンドと共に表示されるプロンプトによって、そのプログラムを表します。例えば、 shell> は、あなたのログインシェルから実行するコマンドを表し、 mysql> は mysql クライアントプログラムから実行するコマンドを表します:

     shell> type a shell command here
     mysql> type a mysql command here

シェルコマンドは Bourne シェル構文で示されます。csh 形式のシェルを使用している場合は、わずかに変更してコマンドを発行する必要があるでしょう。例えば、環境変数を設定してコマンドを実行するシーケンスは、Bourne シェル構文では次のようになります:

     shell> VARNAME=value some_command

csh では、次のようなシーケンスを実行してください:

     shell> setenv VARNAME value
     shell> some_command

データベース名, テーブル名, フィールド名はコマンドの中で置換しなければいけないことがよくあります。このような置換が必要なことを示すために、このマニュアルは 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 ステートメントは大文字でも小文字でも記述できます。このマニュアルが SQL ステートメントを示すときは、特別なキーワードを説明している時には(それを強調するために)そのキーワードに大文字が使用され、残りのステートメントに小文字が使用されます。 例えば、SELECT ステートメントの説明中には次が見られるでしょう:

     mysql> SELECT count(*) FROM tbl_name;

一方、COUNT() 関数の説明中では、ステートメントは次のように書かれます:

     mysql> select COUNT(*) from tbl_name;

特別な強調が意図されない場合、全てのキーワードは大文字で書かれます。

構文の説明中では、角括弧([ と ])はオプションの単語や節であることを示すために使用されます:

     DROP TABLE [IF EXISTS] tbl_name

構文要素がいくつかのものからなる場合、垂直バー(|)で区切られます。選択セットから一つのメンバを選ぶことができるときは、角括弧中にリストされます。 ([ and ]):

     TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)

選択セットから一つのメンバを選ぶ必要があるときは、波括弧({ と })中にリストされます:

     {DESCRIBE | DESC} tbl_name {col_name | wild}

MySQL の歴史
=========

我々自身の速くて低レベルな (ISAM) ルーチンを使用する、我々のテーブルへ接続するために、 我々は一度 mSQL を使用するつもりでした。しかし、いくつかのテストの後、我々は mSQL は我々が必要とするほど高速ではなく、柔軟度を持っていないとの結論に至りました。この結果、mSQL とほとんど同じ API インタフェースを持つ、我々のデータベースへの新しい SQL インタフェースに帰結しました。この API はサードパーティコードの移植を簡単にするために選択されました。

MySQL の名前の由来は完全には明らかではありません。我々のベースディレクトリと多くのライブラリとツールは接頭辞 ``my'' を 10 年以上も使っています。しかし、Monty の娘(何年か若い)も My という名前です。そのため、この2つのどちらが MySQL に名前を与えたかは、我々にとっても未だ謎です。

Books about MySQL
=================

While this manual is still the right place for up to date techical information, its primary goal is to contain everything there is to know about MySQL. And it is sometimes nice to have a bound book to read in bed or while you travel. Here are a list of books about MySQL (in English).

Title                 MySQL (http://www2.newriders.com/cfm/prod_book.cfm?RecordID=584)
Publisher                     New Riders
Author                Paul DuBois
Pub Date              1st Edition December 1999
ISBN                  0735709211
Pages                 800
Price                 $49.99 US
Downloadable examples               samp_db.tar.gz (http://mysql.com/Contrib/Examples/samp_db.tar.gz)
Errata               are available here (http://www.mysql.com/pauls-mysql-book-errata.html)

Foreword by Michael ``Monty'' Widenius, MySQL Moderator

In MySQL, Paul DuBois provides you with a comprehensive guide to one of the most popular relational database systems. Paul has contributed to the online documentation for MySQL, and is an active member of the MySQL community. The principal MySQL developer, Monty Widenius, and a network of his fellow developers reviewed the manuscript, providing Paul with the kind of insight no one else could supply.

Instead of merely giving you a general overview of MySQL, Paul teaches you how to make the most of its capabilities. Through two sample database applications that run throughout the book, he gives you solutions to problems you're sure to face. He helps you integrate MySQL efficiently with third-party tools, such as PHP and Perl, enabling you to generate dynamic Web pages through database queries. He teaches you to write programs that access MySQL databases, and also provides a comprehensive set of references to column types, operators, functions, SQL syntax, MySQL programming, C API, Perl DBI, and PHP API. MySQL simply gives you the kind of information you won't find anywhere else.

If you use MySQL, this book provides you with:

  * An introduction to MySQL and SQL

  * Coverage of MySQL's data types and how to use them

  * Thorough treatment of how to write client programs in C

  * A guide to using the Perl DBI and PHP APIs for developing command-line and Web-based applications

  * Tips on administrative issues such as user accounts, backup, crash recovery, and security

  * Help in choosing an ISP for MySQL access

  * A comprehensive reference for MySQL's data types, operators, functions, and SQL statements and utilities

  * Complete reference guides for MySQL's C API, the Perl DBI API, and PHP's MySQL-related functions

Title                 MySQL & mSQL (http://www.oreilly.com/catalog/msql/noframes.html)
Publisher                     O'Reilly
Authors               Randy Jay Yarger, George Reese & Tim King
Pub Date              1st Edition July 1999
ISBN                  1-56592-434-7, Order Number: 4347
Pages                 506
Price                 $34.95

This book teaches you how to use MySQL and mSQL, two popular and robust database products that support key subsets of SQL on both Linux and UNIX systems. Anyone who knows basic C, Java, Perl, or Python can write a program to interact with a database, either as a stand-alone application or through a Web page. This book takes you through the whole process, from installation and configuration to programming interfaces and basic administration.  Includes ample tutorial material.

Title                  Sams Teach Yourself MySQL in 21 Days (http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=0672319144)
Publisher              Sams
Authors                Mark Maslakowski and Tony Butcher
Pub Date               June 2000
ISBN                   0672319144
Pages                  N/A
Price                  $39.99

Sams Teach Yourself MySQL in 21 Days is for intermediate Linux users who want to move into databases.  A large share of the audience to be web developers needing a database to store large amounts of information that can be retrieved via the Web. Sams Teach Yourself MySQL in 21 Days is a practical, step-by-step tutorial.  The reader will learn to design and employ this open source database technology into his/her web site using practical, hands-on examples to follow.

Title                  E-Commerce Solutions with MySQL (http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=0761524452)
Publisher              Prima
Authors                N/A
Pub Date               September 2000
ISBN                   0761524452
Pages                  500
Price                  $39.99

No description available.

Title                  Professional MySQL Programming (http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=1861004281)
Publisher              Wrox
Authors                N/A
Pub Date               July 2000
ISBN                   1861004281
Pages                  1000
Price                  $49.99

No description available.

Title                  PHP3 and MySQL Web Development (http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=0672317842)
Publisher              N/A
Authors                William Jason Gilmore
Pub Date               October 2000
ISBN                   672317842
Pages                  N/A
Price                  $39.99

No description available.

MySQLの主な機能
==========

MySQL の重要な特徴のいくつかを以下の項目にあげます：

  * カーネルスレッドを使用する完全なマルチスレッド。これは有効であれば簡単に複数の CPU を使用できることを意味します。

  * C, C++, Ruby, Eiffel, Java, Perl, PHP, Python そして Tcl API。See Clients。

  * 多くの種類のプラットフォームで動作します。See Which OS。

  * 多くのフィールド型: 1, 2, 3, 4, 8 バイト長の符号付き/符号無し整数, FLOAT, DOUBLE, CHAR, VARCHAR, TEXT, BLOB, DATE, TIME, DATETIME, TIMESTAMP, YEAR, SET, ENUM 型。See Column types。

  * 最適化された one-sweep multi-join を使用するとても速い結合。

  * クエリの SELECT と WHERE 部内での全ての演算子と関数のサポート。例:

          mysql> SELECT CONCAT(first_name, " ", last_name) FROM tbl_name
                     WHERE income/dependents > 10000 AND age > 30;

  * SQL 関数は高度に最適化されたクラスライブラリを通して実装されていて、それが得ることのできるのと同じくらい速いのです！ 普通、クエリの初期化の後には、全くメモリ割り当てはありません。

  * SQL GROUP BY と ORDER BY 節の完全なサポート。グループ関数 (COUNT(), COUNT(DISTINCT), AVG(), STD(), SUM(), MAX(), MIN()) のサポート。

  * ANSI SQL と ODBC 構文での LEFT OUTER JOIN のサポート。

  * 同一クエリ内に異なるデータベースからのテーブルを混在できます (バージョン 3.22)。

  * とても柔軟で安全な 特権システム とパスワードシステム。ホストベースの証明が可能です。サーバに接続する時の全てのパスワードトラフィックは暗号化されているためパスワードは安全です。

  * Windows95 の ODBC (Open-DataBase-Connectivity) (ソースつき)。全ての ODBC 2.5 関数と他の多く。あなたの MySQL サーバに接続するために、例えば Access を使用できます。See ODBC。

  * インデックス圧縮つきのとても速い B-tree ディスクテーブル。

  * テーブル毎に 16 インデックスが許されます。各インデックスは 1 から 16 個のフィールドまたはフィールドの一部からなります。最大インデックス長は 256 バイトです (これは MySQL のコンパイル時に変更できます)。インデックスは CHAR または VARCHAR フィールドの先頭部分を使用できます。

  * 固定長と可変長のレコード。

  * 一時テーブルとして使用されるメモリ内ハッシュテーブル。

  * 大きなデータベースの操作。我々は、50,000,000 レコードを含むいくつかのデータベースで MySQL を使用しています。

  * 全てのフィールドはデフォルト値を持ちます。 テーブル項目のサブセットを挿入するために INSERT を使用でき、明示的に値が与えられていないフィールドはそのデフォルト値が設定されます。

  * 可搬性のために GNU Automake, Autoconf, libtool を使用しています。

  * C と C++ で書かれています。広範な種類のコンパイラでテストされてます。

  * とても速いスレッドベースのメモリ割り当てシステム。

  * メモリリークがありません。市販のメモリリーク検出製品(purify)でテストされています。

  * myisamchk を含んでいます。これは、テーブル検査、最適化、修復のためのとても速いユーティリティです。See Maintenance。

  * 異なるキャラクタセットの完全なサポート。ISO-8859-1 (Latin1), big5, ujis など。例えば、スカンジナビア語文字 å, ä そして ö はテーブル名やフィールド名として許されます。

  * 全てのデータは 選択されたキャラクターセットの形式で保存されています。通常文字列フィールドの全ての比較はケース非依存です。

  * ソートは、MySQL サーバー起動時に、選択されたキャラクターセットにに従って行なわれます。(デフォルトは、スウェーデン語の方法)。ソース内に新しいソート順序配列を追加することで、これは変更可能です。とても先進的なソートの例を見るには、Czech ソートコードを見てください。 MySQL は多くの種類のキャラクタセットをサポートし、コンパイル時や実行時に指定できます。

  * SQL92 標準にあるようなテーブルとフィールドのエイリアス名。

  * DELETE, INSERT, REPLACE, UPDATE は変更された(影響を受けた)行の数を返します。サーバ接続時にフラグを設定することにより、代わりに適合したレコード数を返すことも可能です。

  * 関数名はテーブル名やフィールド名と衝突しません。例えば ABS は正しいフィールド名です。制限は、関数呼び出しに、関数名とそれに続く ( の間に空白が許されないことだけです。See Reserved words。

  * 全ての MySQL プログラムはオンラインヘルプを得るために、 --help と -? オプションで呼び出すことができます。

  * サーバは多くの言語でクライアントへのエラーメッセージを提供できます。 See Languages。

  * クライアントは、TCP/IP 接続または Unix ソケット、あるいは NT の場合はネームドパイプを使用して MySQL サーバと接続します。

  * MySQL 固有の SHOW コマンドはデータベース、テーブル、インデックスについての情報を取出すために使用できます。EXPLAIN コマンドはオプティマイザがどのようにクエリを解析するかを決定するために使用できます。

MySQL はどれくらい安定か？
================

この節では、``MySQL はどれくらい安定か？'' と ``私はこのプロジェクトで MySQL に依存できるか？'' という質問について回答します。

我々はここで、いくつかの問題を明らかにし、多くの人に関係すると思われるさらに重要な質問のいくつかを回答することを試みます。この節は、メーリングリスト(そこではとても活発にバグが報告されています)から取り込まれた情報が一緒に置かれています。

TcX では、MySQL は 1996 中頃から我々のプロジェクトで何の問題もなく動いていました。広く公にリリースされた時、我々は、MySQL 内に ``テストされていないコード'' の部分があることに注意しました。これは、我々とは異なる方法でクエリを作成する新しいユーザによってすぐに見つけられました。新しい各リリースは、(多くの新しい機能を持っているのに)前のものよりも問題は少なくなります。そして次のリリースの一つを ``安定'' と呼ぶことができるように我々は望んでいます。

MySQL の各リリースは実用的で、ユーザが ``グレイゾーン'' からのコードの使用を開始する時にだけ問題があります。当然、外部のユーザは、何がグレイゾーンかを知ることができません; この節で現在知られているこれらを示してみます。説明は MySQL の 3.22.x バージョンで扱われます。知られていて報告されているバグは全て最新のバージョンで修正されています。bugs 節に書かれているバグは除きます。それらは ``設計'' 関連のものです。See Bugs.

MySQL は複数の階層と様々な独立モジュールで書かれています。これらのモジュールは、それぞれがどのようにテストされているかとともに次にリストされています:

ISAM テーブル処理 --- 安定
     これは MySQL 3.22 とそれ以前のバージョンにおいて、全てのデータの保存と検索を管理します。全ての MySQL リリースでは、このコード内には(報告された)バグは一つもありません。不正なテーブルを得る唯一の方法は、更新の途中にあるサーバを殺すことだけです。そして各クエリ間で全てのデータはディスクにフラッシュされるため、いかなるデータも修復外の破壊が起こるということはまずないでしょう。 MySQL 内のバグのためにデータが失われたというバグレポートは一つもありません。

The MyISAM table handler --- Beta
     これは MySQL 3.23 での新機能です. これは ISAM テーブルのコードを元に拡張されていますが、多くの便利な機能を持っています。

パーサと単語解析 --- 安定
     このシステム内には長い間バグは一つも報告されていません。

C クライアントコード --- 安定
     知られている問題はありません。3.20 リリースの初期には、送信/受信バッファサイズにいくつかの制限がありました。3.21.x 以降、バッファはデフォルトの 24M まで動的に大きくなります。

標準クライアントプログラム --- 安定
     これらは mysql, mysqladmin, mysqlshow, mysqldump, mysqlimport を含みます.

基本的な SQL --- 安定
     基本的な SQL 機能システムと文字列節と動的メモリ処理。このシステムには報告されたバグは一つもありません。

クエリオプティマイザ --- 安定

範囲オプティマイザ --- 安定

結合オプティマイザ --- 安定

ロック --- ガンマ
     これはとてもシステムに依存しています。いくつかのシステムでは、これは、標準 OS ロック (fcntl) を使用するため大きな問題があります。これらの場合では、MySQL デーモンを --skip-locking フラグつきで動かすべきです。知られている問題は、いくつかの Linux システムと NFS マウントされたファイルシステム使用時の SunOS です。

Linux スレッド --- ガンマ
     fcntl() コールでだけ問題が見つかっています。これは mysqld への --skip-locking オプションの使用で修正できます。何人かは 0.5 リリースで lockup 問題を報告しました。1000以上の同時接続を使用する予定であれば、LinuxThreads を再コンパイルする必要があります。しかし、デフォルトの LinuxThread でも多くの接続を実行することは可能です(しかし 1021 以上にならないようにしてください)。デフォルトの 2MB のスタック空間は、アプリケーションを不安定にします。そして 1021 個のアイドル接続の生成後に coredump を引き起こします。詳しくは Linux Notes をご覧ください。

Solaris 2.5+ pthread --- 安定
     我々は、我々の全ての製品でこれを使用しています。

MIT スレッド (他のシステム) --- ガンマ
     3.20.15 から報告されたバグはありません。3.20.15 から知られたバグはありません。いくつかのシステムでは、いくつかの操作が遅くなるという ``misfeature'' があります(1/20 秒の sleep が各クエリ間で行なわれます)。もちろん、MIT スレッドはすべてを少し遅くします。しかしインデックスベースの SELECT では、ステートメントは通常一度のフレームで行われるため、 mutex locking/thread juggling はありません。

他のスレッド実装 --- アルファ - ベータ
     他のシステムへの移行はまだとても新しく、多分 MySQL に、しかし一番多いのはスレッド実装自身に、多くのバグを持っています。

LOAD DATA..., INSERT ... SELECT --- 安定
     何人かはこれにバグを見つけたと考えましたが、それは結局誤解でした。問題の報告の前にマニュアルを良くチェックしてください！

ALTER TABLE --- 安定
     3.22.12 で少し変更しました。

DBD --- 安定
     現在、Jochen Wiedmann wiedmann@neckar-alb.de によってメンテされています。感謝！

mysqlaccess --- ガンマ
     Yves.Carlier@rug.ac.be によって書かれメンテされてます。感謝！

GRANT --- ガンマ
     MySQL 3.22.12 で大きな変更が行なわれました。

MyODBC (uses ODBC SDK 2.5) --- ガンマ
     いくつかのプログラムでちゃんと動作しているように見えます。

TcX は代金を支払った顧客のために email サポートを提供しています。しかし MySQL メーリングリストは通常、全ての一般的な質問に回答を提供しています。バグは通常すぐにパッチで修正され、深刻なバグには、ほとんどいつも新しいリリースがあります。

2000 年対応
========

MySQL 自身は 2000 年問題(Y2K)に対して何の問題も持っていません:

  * MySQL は Unix 時間関数を使用し、2069 年まで日付には何の問題もありません; 全ての2桁の年は 1970 から 2069 の範囲にあると見なされます。これは、year フィールド内に 01 を格納する場合、MySQL はそれを 2001 として扱うということを意味します。

  * 全ての MySQL 日付関数は一つのファイル sql/time.cc に格納され、2000年安全にとても注意深くコード化されています。

  * MySQL 3.22 以降のバージョンでは、新しい YEAR フィールド型は 0 と 1901 から 2155 までの年を1バイトで格納でき、2 桁または4桁で表示できます。

2000年安全でない方法で MySQL を使用するアプリケーションでは問題になります。例えば、多くの古いアプリケーションは4桁値ではなく2桁値(これは曖昧です)を使用して年を格納し操作します。この問題は、00 または 99 のような値を ``欠けている'' 値の表われとして使用するアプリケーションによって作られます。

あいにく、これらの問題を修正するのは困難です。様々なアプリケーションが様々なプログラムによって書かれていて、その各々が慣習と日付操作関数の様々な組み合わせを使用するからです。

これは、MySQL が 2030 年までの日付に何の問題もないことを示す簡単なテストです！

     mysql> DROP TABLE IF EXISTS y2k;
     mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp);
     mysql> INSERT INTO y2k VALUES ("1998-12-31","1998-12-31 23:59:59",19981231235959);
     mysql> INSERT INTO y2k VALUES ("1999-01-01","1999-01-01 00:00:00",19990101000000);
     mysql> INSERT INTO y2k VALUES ("1999-09-09","1999-09-09 23:59:59",19990909235959);
     mysql> INSERT INTO y2k VALUES ("2000-01-01","2000-01-01 00:00:00",20000101000000);
     mysql> INSERT INTO y2k VALUES ("2000-02-28","2000-02-28 00:00:00",20000228000000);
     mysql> INSERT INTO y2k VALUES ("2000-02-29","2000-02-29 00:00:00",20000229000000);
     mysql> INSERT INTO y2k VALUES ("2000-03-01","2000-03-01 00:00:00",20000301000000);
     mysql> INSERT INTO y2k VALUES ("2000-12-31","2000-12-31 23:59:59",20001231235959);
     mysql> INSERT INTO y2k VALUES ("2001-01-01","2001-01-01 00:00:00",20010101000000);
     mysql> INSERT INTO y2k VALUES ("2004-12-31","2004-12-31 23:59:59",20041231235959);
     mysql> INSERT INTO y2k VALUES ("2005-01-01","2005-01-01 00:00:00",20050101000000);
     mysql> INSERT INTO y2k VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000);
     mysql> INSERT INTO y2k VALUES ("2050-01-01","2050-01-01 00:00:00",20500101000000);
     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 |
     | 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 |
     +------------+---------------------+----------------+

     13 rows in set (0.00 sec)

これは、DATE と DATETIME 型は未来のいかなる日付において問題のないことををしめします (これら日付は 9999 年まで扱えます)

TIMESTAMP 型は、時刻を保存しますが、2030-01-01 までです。 TIMESTAMP は 32-bit マシンでは 1970 から 2030 の範囲です。 64-bit マシンでは、 2106 年まで扱えれます。

MySQL は 2000年対応ですが、曖昧でない入力を提供するのはあなたの責任です。曖昧な日付の入力データ（2桁の年の値）の扱いについての MySQL の規則については Y2K issues を参照してください。

一般的な SQL 情報とチュートリアル
===================

この本は MySQL メーリングリストの数人によって推奨されています:

     Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
     The Practical SQL Handbook: Using Structured Query Language
     Second Edition
     Addison-Wesley
     ISBN 0-201-62623-3
     http://www.awl.com

この本も MySQL ユーザーにいくつかの推薦を受けています:

     Martin Gruber
     Understanding SQL
     ISBN 0-89588-644-8
     Publisher Sybex 510 523 8233
     Alameda, CA USA

SQL チュートリアルがネット上にあります http://www.geocities.com/SiliconValley/Vista/2207/sql1.html

SQL in 21 Tagen (online book in German language): http://www.mut.de/leseecke/buecher/sql/inhalt.htm

便利な MySQL 関連リンク
===============

次のリンク以外にも、多くの MySQL プログラム、ツール、API を Contrib directory (http://www.mysql.com/Contrib/) から見つけてダウンロードすることができます。

Tutorials
---------

  * A beginner's tutoral of how to start using MySQL (http://www.devshed.com/resource/advanced/mysql/index.html)

  * http://www.analysisandsolutions.com/code/mybasic.htm Beginners MySQL Tutorial on how to install and set up MySQL on a Windows machine.

  * A lot of MySQL tutorials (http://www.devshed.com/Server_Side/MySQL/)

  * Setting Up a MySQL-Based Website (http://www.linuxplanet.com/linuxplanet/tutorials/1046/1/)

  * MySQL-Perl tutorial (http://www.hotwired.com/webmonkey/backend/tutorials/tutorial1.html)

  * Installing new Perl modules that require locally installed modules (http://www.iserver.com/support/contrib/perl5/modules.html)

  * PHP/MySQL Tutorial (http://www.hotwired.com/webmonkey/databases/tutorials/tutorial4.html)

  * Hands on tutorial for MySQL (http://www.useractive.com/)

Porting MySQL / Using MySQL on different systems
------------------------------------------------

  * The MacOS Xclave (http://xclave.macnn.com/MySQL/). Running MySQL on MacOSX

  * MySql for MacOSX Server (http://www.prnet.de/RegEx/mysql.html)

  * Client libraries for the Macintosh (http://www.lilback.com/macsql/)

Perl related links
------------------

  * Perl DBI with MySQL FAQ (http://haven.e-cactus.com/dbi_mysql)

MySQL discussion forums
-----------------------

  * Examples using MySQL; (check Top 20) (http://www.weberdev.com/)

  * FutureForum Web Discussion Software (http://futurerealm.com/forum/futureforum.htm)

Commercial applications that support MySQL
------------------------------------------

  * SupportWizard; Interactive helpdesk on the web (This product includes a licensed copy of MySQL) (http://www.supportwizard.com/)

  * StWeb (http://www.stweb.org/) StWeb - Stratos Web and Application server - an easy-to-use, cross platform, Internet/Intranet development and deployment system for development of web-enabled applications. The standard version of StWeb has a native interface to MySQL database.

  * Right Now Web; Web automation for customer service (http://www.rightnowtech.com/)

  * Win32 GUI client (http://www.ecker-software.de) A Win32 GUI client by David Ecker.

  * Bazaar; Interactive Discussion Forums with web interface (http://www.icaap.org/Bazaar/)

  * PhoneSweepT (http://www.phonesweep.com/) is the world's first commercial Telephone Scanner. Many break-ins in recent years have come not through the Internet, but through unauthorized dial-up modems. PhoneSweep lets you find these modems by repeatedly placing phone calls to every phone number that your organization controls. PhoneSweep has a built-in expert system that can recognize more than 250 different kinds of remote-access programs, including Carbon Copy(TM), pcANYWHERET(TM), and Windows NT RAS. All information is stored in the SQL database. It then generates a comprehensive report detailing which services were discovered on which dial-up numbers in your organization.

SQL クライアント/Report writers
-------------------------

  * MySQL Editor/Utility for MS Windows Platforms. (http://www.urbanresearch.com/software/utils/urbsql/index.html)

  * KDE MySQL client (http://www.xnot.com/kmysql)

  * KMySQL (http://www.penguinpowered.com/~kmysql) KMySQL is a database client for KDE that primarily supports MySQL.

  * Kiosk; a MySQL client for database management (http://www.icaap.org/software/kiosk/). Written in Perl. Will be a part of Bazaar.

  * A free report writer in Java (http://www.geocities.com/SiliconValley/Ridge/4280/GenericReportWriter/grwhome.html)

  * FutureSQL Web Database Administration Tool (http://futurerealm.com/opensource/futuresql.htm). FutureSQL by Peter F. Brown, is a Free, Open Source Rapid Application Development web database administration tool, written in Perl, using MySQL. It uses DBI:DBD and CGI.pm.

     FutureSQL allows one to easily setup config files to view, edit, delete and otherwise process records from a MySQL database. It uses a data dictionary, configuration files and templates, and allows "pre-processing" and "post-processing" on both fields, records and operations.

  * MySQLExport (http://www.javaframework.de) Export of MySQL create statements and data in a lot of different formats (SQL, HTML, CVS, text, ZIP, GZIP...)

MySQL をサポートする Web 開発ツール
-----------------------

  * PHP: A server-side HTML-embedded scripting language (http://www.php.net/)

  * The Midgard Application Server; a powerful Web development environment based on MySQL and PHP (http://www.midgard-project.org)

  * SmartWorker is a platform for web application development (http://www.smartworker.org)

  * XSP: e(X)tendible (S)erver (P)ages and is a HTML embedded tag language written in Java (previously known as XTAGS) (http://xsp.lentus.se/) dbServ (http://www.dbServ.de/) is an extension to a web server to integrate databases output into your HTML code. You may use any HTML function in your output. Only the client will stop you. It works as standalone server or as JAVA servlet.

  * Platform independent ASP from Chili!Soft (http://www.chilisoft.com/)

  * MySQL + PHP demos (http://www.wernhart.priv.at/php/)

  * ForwardSQL: HTML interface to manipulate MySQL databases (http://www.dbwww.com/)

  * WWW-SQL: Display database information (http://www.daa.com.au/~james/www-sql/)

  * Minivend: A Web shopping cart (http://www.minivend.com/minivend/)

  * HeiTML: A server-side extension of HTML and a 4GL language at the same time (http://www.heitml.com/)

  * Metahtml: A Dynamic Programming Language for WWW Applications (http://www.metahtml.com/)

  * VelocityGen for Perl and Tcl (http://www.binevolve.com/)

  * Hawkeye Internet Server Suite (http://hawkeye.net/)

  * Network Database Connection For Linux (http://www.fastflow.com/)

  * WDBI: Web browser as a universal front end to databases which supports MySQL well. (http://www.wdbi.net/)

  * WebGroove Script: HTML compiler and server-side scripting language (http://www.webgroove.com/)

  * A server-side web site scripting language (http://www.ihtml.com/)

  * How to use MySQL with ColdFusion on Solaris (ftp://ftp.igc.apc.org/pub/myodbc/README)

  * Calistra's ODBC MySQL Administrator (http://calistra.com/MySQL/)

  * Webmerger (http://www.webmerger.com) This CGI tool interprets files and generates dynamic output based on a set of simple tags. Ready-to-run drivers for MySQL and PostgreSQL through ODBC.

  * PHPclub (http://phpclub.unet.ru/index_e.php3). Tips and tricks for PHP

  * MySQL and Perl Scripts (http://www.penguinservices.com/scripts)

  * The Widgetchuck; Web Site Tools and Gadgets (http://www.widgetchuck.com)

  * AdCycle (http://www.adcycle.com/) advertising management software

  * pwPage (http://www.bidsystems.com/pwPage) provides an extremely fast and simple approach to the creation of database forms.  That is, if a database table exists and an HTML page has been constructed using a few simple guidelines, pwPage can be immediately used for table data selections, insertions, updates, deletions and selectable table content reviewing.

  * OMNIS (http://www.omnis-software.com/products/studio/studio.html) OMNIS Studio is a rapid application development (RAD) tool.

Database design tools with MySQL support
----------------------------------------

  * "DeZign for databases" is a database development tool using an entity relationship diagram (ERD). (http://www.mysql.com/dezign/index.html)

MySQL ツールでの Web サーバ
-------------------

  * An Apache authentication module (http://bourbon.netvision.net.il/mysql/mod_auth_mysql/)

  * The Roxen Challenger Web server (http://www.roxen.com/)

Extensions for other programs
-----------------------------

  * MySQL support for BIND (The Internet Domain Name Server) (http://www.seawood.org/msql_bind/)

  * MySQL support for Sendmail and Procmail (http://www.inet-interactive.com/sendmail)

Using MySQL with other programs
-------------------------------

  * Using MySQL with Access (http://www.iserver.com/support/addonhelp/database/mysql/msaccess.html)

  * Installing new Perl modules that require locally installed modules (http://www.iserver.com/support/contrib/perl5/modules.html)

ODBC related links
------------------

  * Popular iODBC Driver Manager (libiodbc) now available in Open Source format (http://www.iodbc.org/)

  * The FreeODBC Pages (http://users.ids.net/~bjepson/freeODBC/)

  * unixodbc (http:/http://genix.net/unixODBC/) The unixODBC Project goals are to develop and promote unixODBC to be the definitive standard for ODBC on the Linux platform. This is to include GUI support for KDE.

API 関連リンク
---------

  * MySQL COM extension (http://www.amedea.cz/mysqlx/index.html) With this COM objects You can use MySQL also on Windows platform with ASP pages or Delphi, Visual Basic, Visual C++, ... languages.

  * www.jppp.com (http://www.jppp.com) Partially implemented TDataset-compatible components for MySQL.

  * qpopmysql (http://www.riverstyx.net/qpopmysql/) A patch to allow POP3 authentication from a MySQL database. There's also a link to Paul Khavkine's patch for Procmail to allow any MTA to deliver to users in a MySQL database.

  * Visual Basic class generator for Active X (http://www.pbc.ottawa.on.ca)

  * Client libraries for the Macintosh (http://www.lilback.com/macsql/)

  * SCMDB (http://www.dedecker.net/jessie/scmdb/). SCMDB is an add-on for SCM that ports the mysql C library to scheme (SCM). With this library scheme developers can make connections to a mySQL database and use embedded SQL in their programs.

他の MySQL 関連リンク
--------------

  * Registry of Web providers who support MySQL (http://www.wix.com/mysql-hosting)

  * Links about using MySQL in Japan/Asia (http://www.softagency.co.jp/mysql/index.en.phtml)

  * Commercial Web defect tracking system (http://www.open.com.au/products.html)

  * PTS: Project Tracking System (http://www.stonekeep.com/pts/)

  * Job and software tracking system (http://tomato.nvgc.vt.edu/~hroberts/mot)

  * ExportSQL: A script to export data from Access95+ (http://www.cynergi.net/non-secure/exportsql/)

  * SAL (Scientific Applications on Linux) MySQL entry (http://SAL.KachinaTech.COM/H/1/MYSQL.html)

  * A consulting company which mentions MySQL in the right company (http://www.infotech-nj.com/itech/index.shtml)

  * PMP Computer Solutions. Database developers using MySQL and mSQL (http://www.pmpcs.com/)

  * Airborne Early Warning Association (http://www.aewa.org)

  * MySQL UDF Registry (http://abattoir.cc.ndsu.nodak.edu/~nem/mysql/udf/)

  * Y2K tester (http://21ccs.com/~gboersm/y2kmatrix/)

SQL とデータベースインタフェース
------------------

  * The JDBC database access API (http://java.sun.com/products/jdbc/)

  * Patch for mSQL Tcl (http://www.gagme.com/mysql)

  * EasySQL: An ODBC-like driver manager (http://www.amsoft.ru/easysql/)

  * A REXX interface to SQL databases (http://www.lightlink.com/hessling/rexxsql.html)

  * Tcl interface (http://www.binevolve.com/~tdarugar/tcl-sql)

例とソース
-----

  * Little6 Inc (http://www.little6.com/about/linux/) An online contract and job finding site that is powered by MySQL, PHP3 and Linux.

  * DELECis (http://www.delec.com/is/products/prep/examples/BookShelf/index.html) A tool which makes it very easy to create an automatically generated table documentation. They have used MySQL as an example.

  * World Records (http://www.worldrecords.com) A search engine for information about music that uses MySQL and PHP.

  * A Contact Database using MySQL and PHP (http://www.webtechniques.com/archives/1998/01/note/)

  * Web based interface and Community Calender with PHP (http://modems.rosenet.net/mysql/)

  * Perl package to generate html from a SQL table structure and for generating SQL statements from an html form. (http://www.odbsoft.com/cook/sources.htm)

  * Basic telephone database using DBI/DBD (http://www.gusnet.cx/proj/telsql/).

  * TmySQL; A library to use MySQL with Delphi (http://www.productivity.org/projects/mysql/)

  * JDBC examples by Daniel K. Schneider (http://tecfa.unige.ch/guides/java/staf2x/ex/jdbc/coffee-break)

  * SQL BNF (http://www.spade.com/linux/howto/PostgreSQL-HOWTO-41.html)

  * Object Oriented Concepts Inc; CORBA applications with examples in source (http://www.ooc.com/)

  * DBWiz; Includes an example of how to manage own cursors in VB (http://www.pbc.ottawa.on.ca/)

  * Pluribus (http://keilor.cs.umass.edu/pluribus/) Pluribus, is a free search engine that learns to improve the quality of its results over time. Pluribus works by recording which pages a user prefers among those returned for a query. A user votes for a page by selecting it; Pluribus then uses that knowledge to improve the quality of the results when someone else submits the same (or similar) query. Uses PHP and MySQL.

  * Stopbit (http://www.stopbit.com/) A technology news site using MySQL and PHP

  * Example scripts at Jokes2000 (http://www.jokes2000.com/scripts/)

  * http://www.linuxsupportline.com/~kalendar/ KDE based calendar manager The calendar manager has both single user (file based) and multi user (MySQL database) support.

  * Example of storing/retrieving images with MySQL and CGI (http://tim.desert.net/~tim/imger/)

  * Online shopping cart system (http://www.penguinservices.com/scripts)

一般的なデータベースリンク
-------------

  * Database Jump Site (http://www.pcslink.com/~ej/dbweb.html)

  * Homepage of the webdb-l (Web Databases) mailing list. (http://black.hole-in-the.net/guy/webdb/)

  * Perl DBI/DBD modules homepage (http://www.symbolstone.org/technology/perl/DBI/index.html)

  * Cygwin tools. UNIX on top of Windows (http://www.student.uni-koeln.de/cygwin/)

  * dbasecentral.com; Development and distribution of powerful and easy-to-use database applications and systems. (http://dbasecentral.com/)

  * Tek-Tips Forums (http://www.Tek-Tips.com) Tek-Tips Forums are 800+ independent peer-to-peer non-commercial support forums for Computer Professionals.  Features include automatic e-mail notification of responses, a links library, and member confidentiality guaranteed.

MySQL を使用した多くの web ページもあります。See Users。このリストへ追加できるものを webmaster@mysql.com に送ってください。 We now require that you show a MySQL logo somewhere (It is okay to have it on a ``used tools'' page or something similar) to be added.

MySQL メーリングリストと質問をする方法またはエラー(バグ)を報告する方法
***************************************

MySQL メーリングリスト
==============

メイン MySQL メーリングリストを購読するには、メッセージを電子メールアドレス mysql-subscribe@lists.mysql.com に送ってください。

メイン MySQL メーリングリストの購読の中止は、メッセージを電子メールアドレス mysql-unsubscribe@lists.mysql.com に送ってください。

メッセージを送る先のアドレスだけが重要です。メッセージのサブジェクトと本文は無視されます。

もし、あなたのリプライアドレスが妥当な物でない場合、アドレスを明確に指定することが出来ます。 subscribe あるいは unsubscribe のあとにハイフンを付け、そのあとにあなたのアドレスを記述します。ただし @ 文字は = に置き変えて書きます。例えば、 john@host.domain で購読したい場合、 mysql-subscribe-john=host.domain@lists.mysql.com 宛にメッセージを送ります。

mysql-subscribe@lists.mysql.com や mysql-unsubscribe@lists.mysql.com へのメールは ezmlm メーリングリストプロセッサによって自動的に処理されます。 ezmlm についての情報は The ezmlm Website (http://www.ezmlm.org).

本メーリングリストへの投稿を行うには、mysql@lists.mysql.com にメッセージを送ります。しかし、subscribe あるいは unsubscribe のメールを mysql@lists.mysql.com に送らないでください。これらのアドレスへ送られたメールは、何千ものユーザーに配送されてしまいます。

あなたのローカルサイトが多くの mysql@lists.mysql.com 購読者を持つこともあります。この場合、ローカルメーリングリストを作り、lists.mysql.com からの一つのメッセージがそのサイトに送られ、ローカルなリストで複写されるようにしてください。この場合、ローカルの MySQL リストへの追加と削除は、あなたのシステム管理者に問い合わせて下さい。

次の MySQL メーリングリストがあります:

announce
     これは MySQL と関連プログラムの新しいバージョンのアナウンスのためです。これは、全ての MySQL ユーザが入るべきと我々が考える少ない量のリストです。

mysql
     一般の MySQL 議論のための主なリストです。さらに専門的なリストに行くべきものもあることに注意してください。間違ったリストに投稿しても、答を得られないでしょう！

mysql-digest
     ダイジェスト形式の mysql リストです。これは、一日に一回、一つの大きなメールが送られることで個々のメッセージ全てが得られることを意味します。

bugs
     このリストには、完全で再現可能なバグレポートだけを、mysqlbug を使用して投稿すべきです(Windows 上で実行している場合は、OS と MySQL バージョンの記述を含めるべきです)。できれば、投稿前に MySQL の最新の安定バージョンか開発バージョンを使用して問題をテストすべきです！ 含められたテストケース上で、'mysql test < script' を使用することで、誰もがバグを再現できるべきです。このリストに投稿された全てのバグは、次の MySQL リリースで修正されるかドキュメント化されます！ 小さなコードの変更だけですめば、我々はこの問題を修正するパッチの投稿も行ないます。

bugs-digest
     ダイジェスト形式の bugs リストです。

developer
     MySQL コードを動かす人のためのリスト。このリストでは MySQL 開発の議論とパッチの投稿も可能です。

developer-digest
     developer リストのダイジェストバージョン。

java
     MySQL と Java についての議論。多くは JDBC ドライバについてです。

java-digest
     java リストのダイジェストバージョン。

win32
     Windows NT のような Microsoft OS 上の MySQL に関連する全て。

win32-digest
     win32 リストのダイジェストバージョン。

myodbc
     ODBC で MySQL への接続に関連する全て。

myodbc-digest
     myodbc リストのダイジェストバージョン。

msql-mysql-modules
     MySQL でサポートする Perl についてのリスト。

msql-mysql-modules-digest
     msql-mysql-modules リストのダイジェストバージョン。

上述したのと同じ方法で全てのリストの購読または購読中止ができます。あなたの購読または購読中止のメッセージは、mysql ではなく適切なメーリングリストに送ってください。例えば、 myodbc リストを購読または購読中止するには、 myodbc-subscribe@lists.mysql.com または myodbc-unsubscribe@lists.mysql.com にメールを送ります。

質問またはバグ報告
=========

メーリングリストへ質問を尋ねる前に、以下の手順を踏んでください：

  * MySQL のオンラインマニュアルを調べることからはじめます：

          http://www.mysql.com/Manual_chapter/manual_toc.html

     我々は、新しく見つかった問題の解決でマニュアルを頻繁に更新することで、それを最新に保持しようとしています！

  * MySQL メーリングリストアーカイブを検索します：

          http://www.mysql.com/doc.html

  * http://www.mysql.com/ の全ての Web ページ(マニュアルも含む)を検索するために http://www.mysql.com/search.html も使用できます。

ここで回答が見つけられない場合は、近くの MySQL 熟練者とともに調べて下さい。まだあなたの質問の回答が見つけられなければ、先に進み、次のセクションの mysql@lists.mysql.com へメールを送る方法についてを読んでください。

バグや問題を報告する方法
============

良いバグレポートを書くのは忍耐が要りますが、それを最初に正しく行なうことは我々とあなたから時間を節約します。そのバグについての完全なテストケースを含む良いバグレポートは、次のリリースでそれが修正される可能性がとても高くなります。この節では、かなりの、または全く我々の助けにならないことにあなたの時間を浪費しないように、あなたがレポートを正しく書くことを手助けします。

我々は、バグレポートまた可能ならば全ての問題についてのレポートの作成に mysqlbug スクリプトを使用することを奨励します。mysqlbug はソース配布内の scripts ディレクトリ、または、バイナリ配布では MySQL をインストールしたディレクトリ配下の bin ディレクトリから見つけられます。mysqlbug を使用できない場合は、この節に挙げられている全ての必要な情報を含めるべきです。

mysqlbug スクリプトは、下記の多くの情報を自動的に見つけ出すことで、レポートの作成を手助けします。しかし、重要な何かが足りない場合、あなたのメッセージにそれを含めてください！ この節を慎重に読んで、ここで述べられている全ての情報がレポート中に含まれていることを確認してください。

バグを明確に示すテストケースを作ることができれば、 bugs@list.mysql.com リストにそれを投稿してください。注意: このリストには、完全で再現可能なバグ情報を mysqlbug スクリプトを使用して投稿すべきです(Windows 上で実行している場合は、OS と MySQL バージョンの記述を含めるべきです)。できれば、投稿前に MySQL の最新の安定バージョンか開発バージョンを使用して問題をテストすべきです！ 含められたテストケース上で、'mysql test < script' を使用することで、または、バグレポートに含められたシェル/Perlスクリプトを実行することで、誰もがバグを再現できるべきです。このリストに投稿された全てのバグは、次の MySQL リリースで修正されるかドキュメント化されます！ 小さなコードの変更だけですめば、我々はこの問題を修正するパッチの投稿も行ないます。

多すぎる情報を含むメッセージに答えることはできますが、少なすぎる情報を含むものにはできないということを覚えていてください。しばしば人は事実を省いてしまいます。問題の原因をわかっていると思い、いくつかの詳細を重大でないと見なしてしまうからです。良い原則は: 何かを言おうか迷ったときには、言ってください！ 最初にあなたが十分な情報を含めなかったために、再び質問して回答を待つことを強要されるより、数行をあなたのレポートに書く方が千倍速くて迷惑ではありません。

良くある間違いは、使用している MySQL 配布のバージョン番号を示さない、または MySQL をインストールしたプラットフォームを(プラットフォームのバージョン番号を含めて)示さない事です。これはとても関連した情報で、100 のバグレポートのうち 99 の場合、この情報がないと役に立ちません！ 我々は ``何故私では動作しないの？'' のような質問をとても良く受けます。そして我々は、要求された機能はその MySQL バージョンに実装されていない、または、レポート中に述べられているバグは新しい MySQL バージョンで既に修正されているであることを見つけます。時々、エラーはプラットフォーム依存で、オペレーティングシステムとプラットフォームのバージョン番号を知らないことには、何も修正することはできません。

問題に関連している場合は、コンパイラについての情報も与えることを忘れないでください。しばしば人はコンパイラのバグを見つけて、問題は MySQL に関連していると考えます。多くのコンパイラはいつも開発中で、バージョンを上げることによってより良いバージョンになります。問題がコンパイラに依存しているかどうかを確定するには、どのコンパイラが使用されているかを知ることが必要です。全てのコンパイルの問題はバグレポートとみなされ、それに従って報告されるべきであることに注意してください。

最も役に立つのは、問題の良い説明がバグレポートに含められることです。つまり、問題に導かれる全ての行なったことの例と、正確に記述された問題それ自身です。良いバグレポートは、バグや問題を再現する方法を示す完全な例を含むものです。

問題がエラーメッセージを与える場合、それをレポートに含めることはとても重要です！ 我々がプログラムを使用するアーカイブから何かを検索しようとする場合、エラーメッセージはプログラムが与えたものと正確に一致する方が良いです(大文字小文字も守られるべきです！)。どのようなエラーメッセージだったかを覚えるなんてことはしてはいけません；レポートに完全なメッセージをコピーし張りつけてください。

MyODBC での問題がある場合、MyODBC トレースファイルの生成を試みるべきです。 See MyODBC bug report。

あなたのレポートを読む多くの人が 80桁ディスプレイを使用しているということを覚えておいて下さい。従って、mysql コマンドラインツールを使用してレポートまたはサンプルを生成する時、そのようなディスプレイの有効幅を超える出力(例えば、EXPLAIN SELECT ステートメント; 後述のサンプルを見てください)には、--vertical オプション(または \G ステートメント終端)を使用すべきです。

次の情報をレポートに含めてください:

  * 使用している MySQL 配布のバージョン番号 (例えば MySQL 3.22.22)。どのバージョンを動かしているかは mysqladmin version の実行で見つけられます。mysqladmin は MySQL のインストールディレクトリ配下の bin ディレクトリに見つけられます。

  * あなたが作業しているマシンのメーカーとモデル。

  * オペレーティングシステム名とバージョン。多くのオペレーティングシステムでは、Unix コマンド uname -a の実行によってこの情報が得られます。

  * 時にはメモリ(実メモリと仮想メモリ)の量も関係します。疑わしければ、それを含めてください。

  * MySQL のソース配布を使用している場合は、使用したコンパイラの名前とバージョン番号につての情報も必要です。バイナリ配布の場合は、配布名が必要です。

  * 問題がコンパイル中に発生する場合、正確なエラーメッセージと、エラーが発生したファイルの問題のコードの回りの数行も含めて下さい。

  * 何かのデータベーステーブルが問題に関連する場合は、 mysqldump --no-data db_name tbl_name1 tbl_name2 ... からの出力を含めてください。これはデータベース内の任意のテーブルについての情報を得るとても簡単で強力な方法で、我々があなたの状況に一致するものを生成する手助けになります。

  * SELECT ステートメントでの速度に関するバグや問題では、 EXPLAIN SELECT ... の出力と、少なくとも SELECT ステートメントが与える行の数を常に含めるべきです。あなたの状況について、より多くの情報を、誰かがあなたを助けられるように、より適切に与えてください！ 例えば、次はとても良いバグレポートの例です（もちろん 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>

  * 問題やバグが MySQL 実行中に発生する場合、バグを再現する入力スクリプトが必要です。このスクリプトは必要なソースファイル全てを含めるべきです。より精密なスクリプトはあなたのに似た状況を良く再現できます。

     もしスクリプトを提供することができなければ、少なくとも、 mysqladmin variables extended-status processlist の出力結果をメールにを含むべきです。 これはあなたのシステムの情報を提供します！

  * MySQL がクエリから異常な結果を与えると思う場合は、結果だけでなく、結果がどうなるべきかというあなたの意見と、あなたの意見の基本を説明する理由も含めてください。

  * 問題のサンプルを提供する時に、新しい名前にするよりも、実際の状況で存在するのと同じ変数名やテーブル名等を使用した方が良いです。問題は変数やテーブル等の名前に関連することがあります！ おそらくこれはまれなケースですが、 sorry よりも safe の方が良いです。結局、実際に持っているあなたのサンプル中の同じ状況を使用することはあなたにとっても簡単で、我々にとっても全ての意味で良いことです。他の人に見せたくないデータをいくつか持っている場合、 ftp を使用して ftp://www.mysql.com/pub/mysql/secret/ にデータを転送することができます。データが本当に最高機密で我々にさえ見せたくない場合は、先に進んで、他の変数名等を使用してサンプルを作ってみてください。しかしこれは最後の選択と思ってください。

  * 可能ならば、関連プログラムに与えられた全てのオプションを含めてください。例えば、mysqld デーモン開始時に使用したオプションと MySQL クライアントプログラム実行に使用したオプションを示してください。。mysqld, mysql または configure スクリプトへのオプションはしばしば回答へのキーになり、とても関連しています！ とにかくそれらを含めるというのは悪い考えではありません！ Perl や PHP などのモジュールを使用している場合、それらのバージョン番号も含めてください。

  * 数行のテストケースを提供できない場合、またはテストテーブルがメーリングリストにメールするには大きすぎる(10行以上)場合、mysqldump を使用してあなたのテーブルをダンプし、あなたの問題を説明した README ファイルを作るべきです。

     tar と gzip または zip を使用して、ファイルの圧縮アーカイブを生成し、そのアーカイブを ftp を使用して ftp://www.mysql.com/pub/mysql/secret/ に転送してください。それから問題の短い説明を mysql@lists.mysql.com に送ってください。

  * 質問が権限システムに関連する場合、mysqlaccess の出力、 mysqladmin reload の出力、接続しようとした時に得られた全てのエラーメッセージを含めてください！ 権限をテストする時、まず mysqlaccess を実行すべきです。その後、mysqladmin reload version を実行し、最後に問題が発生するプログラムでの接続を試みるべきです。mysqlaccess はMySQL インストールディレクトリ配下の bin ディレクトリに見つけられます。

  * あなたがバグについてのパッチを持っているのは良い事ですが、そのパッチがすべて、我々が求めているもので、あなたのパッチが修正するバグのテスト情報を提供しなくても、我々がそれを使用するだろう、と思わないでください。我々はあなたのパッチに問題を見つけるかもしれませんし、または、それを全く理解できないかもしれません。その場合はそれを使用できません。

     そのパッチに意味があることが正確に確かめられなければ、我々はそれを使用しません。テストケースは我々にこの手助けをします。パッチが起りうる全ての状況を扱うことを示してください。パッチが動作しない境界線のケース(それが稀でも)を見つけた場合、パッチは使用されないでしょう。

  * 何がバグか、何故発生するのか、何に依存しているのか、についての推測は通常間違いです。我々でさえ、まずデバッガを使用してバグの実際の原因を見つけなければ、そのことは推測できません。

  * メールメッセージ中に、あなたがリファレンスマニュアルとメールアーカイブをチェックしたことを示してください。そうすれば、あなたの問題をあなた自身で解決しようとしたことを他の人がわかります。

  * パースエラーが発生する場合、構文を厳密にチェックしてください！ 何が間違っているのかを見つけられなければ、多分、使用しているクエリを MySQL の現在のバージョンがサポートしていないということです。現在のバージョンを使用していて、http://www.mysql.com/doc.html のマニュアルがあなたの使用しているクエリ構文をカバーしていない場合は、これは MySQL があなたのクエリをサポートしていないという意味です。この場合、あなたの選択は、その構文をあなた自身で実装することか、 mysql-support@mysql.com に email でこれを実装するように申し込むことです！

     マニュアルがあなたの使用している構文をカバーしているのにMySQL の古いバージョンを使用している場合、文法が実装された時期について MySQL の変更履歴をチェックすべきです。See News。この場合、より新しいバージョンの MySQL へのアップグレードを選択できます。

  * もしあなたのデータが悪くなったように思えたり、または、ある特定のテーブルにアクセスする時、エラーとなるなら、まず最初に、テーブルを myisamchk で検査し、修復を試みるべきです see Maintenance.

  * もししょっちゅうテーブルがダメになるようなら、いつ、なぜ起こるのかを探し出すべきです！ この場合、mysql-data-directory/'hostname'.err ファイルに何が起こっているのか含まれている場合があります。 このファイルから関連する情報を抜きだしバグレポートに含めてください！通常、 mysqld は 更新の最中に kill されない限りはテーブルを絶対に破壊しません！ もしなぜ mysqld が死ぬのか見つけた場合は、我々があなたに問題解決のための修正を提供することが、はるかに簡単になります! See What is crashing

  * 可能な場合、最新の MySQL バージョンをダウンロードして、これで問題が解決されるかどうかをチェックしてください。全ての MySQL バージョンは通してテストされ、問題なしに動作します！ 全てが可能な限り以前と互換があるように作られていて、すぐに MySQL バージョンを切り替えることができると我々は信じています！ See Which version。

あなたがサポート顧客なら、より高い優先順位で取り扱うため mysql-support@mysql.com にバグレポートをクロスポストしてください。同様に、他の誰かが問題を経験済み(そしておそらく解決済み)かどうかを知るために適切なメーリングリストにも。

MyODBC のバグ報告上の情報については、ODBC Problems を参照してください。

いくつかの一般的な問題の解決法のために → See Problems.

回答があなたに個人的に送られて、メーリングリストに送られていない時、回答を要約し、あなたの問題の解決の手助けになった返事の恩恵を他の人にも与えるために、その要約をメーリングリストに送信することは、良いエチケットです！

メーリングリストで質問に答えるためのガイドライン
========================

あなたの回答が広く関心を持たれると考えられる場合、尋ねた人に個人的に直接返事をする代わりに、メーリングリストに投稿したいと思うでしょう。オリジナルの投稿者以外の人もそれから恩恵を受けられるように十分一般的に回答を作成することを試みてください。メーリングリストに投稿する場合は、あなたの回答が以前の回答と重複していないか確認して下さい。

あなた返事の中で、質問の本質部分の要約を試みてください。質問全体を引用することを義務と感じないで下さい。

HTML モードを ON にしたブラウザからメールメッセージを投稿しないでください！ 多くのユーザはブラウザでメールを読んでいません！

MySQL ライセンスとサポート
****************

(訳注：正確さをきすため原文を併記しています。訳文だけでなく原文に目を通してください。もし意味の取違いを見つけたなら、takeshi@SoftAgency.co.jp に連絡してください。)

This chapter describes MySQL licensing and support arrangements, including:

本章では MySQL のライセンスとサポート契約について述べます。

  * Our licensing policies for non-Microsoft and Microsoft operating systems

  * The copyrights under which MySQL is distributed (see Copyright)

  * Sample situations illustrating when a license is required (see Licensing examples)

  * Licensing and support costs (see Cost), and support benefits (see Support)

  * 非Microsoft と Mirosoft のオペレーティングシステムに対するライセンスのポリシー

  * MySQL 配布における著作権 (see Copyright)

  * ライセンスが必要となる場合の例 (see Licensing examples)

  * ライセンスとサポートの費用 (see Cost), そしてサポートの利益 (see Support)

MySQL licensing policy
======================

The formal terms of the license for non-Microsoft operating systems such as Unix or OS/2 are specified in Public license.  Basically, our licensing policy is as follows:

UnixやOS/2などの非マイクロソフトオペレーティングシステムにおけるライセンスの正式な条項は Public license. に明記してあります。基本的に、我々のライセンスのポリシーは以下のようになっています：

  * For normal internal use, MySQL generally costs nothing.  You do not have to pay us if you do not want to.

  * A license is required if:

       - You sell the MySQL server directly or as a part of another product or service

       - You charge for installing and maintaining a MySQL server at some client site

       - You include MySQL in a distribution that is non-redistributable and you charge for some part of that distribution

  * For circumstances under which a MySQL license is required, you need a license per machine that runs the mysqld server.  However, a multiple-CPU machine counts as a single machine, and there is no restriction on the number of MySQL servers that run on one machine, or on the number of clients concurrently connected to a server running on that machine!

  * You do not need a license to include client code in commercial programs.  The client access part of MySQL is in the public domain. The mysql command line client includes code from the readline library that is under the GNU Public License.

  * For customers who have purchased 1 license or MySQL support, we provide additional functionality.  Currently, this means we provide the myisampack utility for creating fast compressed read-only databases.  (The server includes support for reading such databases but not the packing tool used to create them.)  When support agreements generate sufficient revenue, we will release this tool under the same license as the MySQL server.

  * If your use of MySQL does not require a license, but you like MySQL and want to encourage further development, you are certainly welcome to purchase a license anyway.

  * If you use MySQL in a commercial context such that you profit by its use, we ask that you further the development of MySQL by purchasing some level of support.  We feel that if MySQL helps your business, it is reasonable to ask that you help MySQL.  (Otherwise, if you ask us support questions, you are not only using for free something into which we've put a lot a work, you're asking us to provide free support, too.)

  * 内部での使用は、MySQL にコストはかかりません。もし望まないのであれば、我々に支払う必要はありません。

  * ライセンスは以下では必要です：

       - MySQL を直接販売するか、または他の製品やサービスの一部として MySQL を販売する場合

       - MySQL のインストールやメンテナンスサービスで料金をとる場合。

       - 再配布不可の配布物に MySQL を含め、そのなかのいくつかに料金をかす場合

  * MySQL ライセンスが必要な情況として、mysqld サーバを走らせるマシン 1 台につき 1 つのライセンスを必要とします. しかし、マルチ CPU マシンは１台のマシンとみなします。 1台のマシン上で走らせる MySQL サーバの数に制限はありません。そのマシン上に走るサーバーに接続するクライアントの数にも制限はありません。

  * 市販のプログラムにクライアントコードを含むために、ライセンスを必要としません。 MySQL のクライアントアクセスの部分はパブリックドメインです。 mysql コマンドラインクライアントは、GNU Public License 下にある readline を含みます。

  * For customers who have purchased 1 license or MySQL support, we provide additional functionality.  Currently, this means we provide the myisampack utility for creating fast compressed read-only databases.  (The server includes support for reading such databases but not the packing tool used to create them.)  When support agreements generate sufficient revenue, we will release this tool under the same license as the MySQL server.

  * MySQL の使用にライセンスを必要としない場合でも、MySQL が好きで, 一層の開発を奨励したいならば,確かに,あなたがライセンスを購入する事は歓迎されています.

  * あなたが商用で MySQL を使用しており、それで利益になっているのなら、我々は,あなたがいくつかのサポートを購入することによって MySQL の開発を促進するように頼みます. 我々は,MySQL があなたのビジネスを助けるならば、あなたが MySQL を助けるように頼むのが道理に合うと感じます. （あなたが我々に質問のサポートを求めるのであれば、我々が多くの労力をつぎ込んだものを無償で使用することはやめてください。無償のサポートの提供を我々に頼むこともです。）

If you have any questions as to whether or not a license is required for your particular use of MySQL, please contact us. See Contact information.

MySQL の使用に際してライセンスが必要であるかどうかに関しての質問があるならば我々に問い合わせてください。See Contact information.

If you require a MySQL license, the easiest way to pay for it is to use the license form on TcX's secure server at https://www.mysql.com/license.htmy.  Other forms of payment are discussed in Payment information.

あなたが MySQL ライセンスを必要としており、簡単な支払い方法を望むのであれば、TcXの安全なサーバにおけるライセンスフォームを使用することです. https://www.mysql.com/license.htmy. ほかの支払い方法については Payment information. （日本での購入は http://www.softagency.co.jp/. ）

MySQL licensing policy

MySQL licensing policy on Win32
===============================

For use under Microsoft operating systems (Win95/Win98/WinNT/Win2000), you need a MySQL license after a trial period of 30 days, with the exceptions that are listed later.  See Win license.

A shareware version of MySQL-Win32, that you can try before buying, is available at http://www.mysql.com/mysql_w32.htmy.  This is based on a very late, stable MySQL version, but compiled with full debugging support, which makes this a lot slower than the registered version.  After you have registered for a MySQL license, you will get a password that will enable you to access the newest MySQL-Win32 version.

Microsoft オペレーティングシステム(Win95/Win98/WinNT/Win2000)下における使用では、あなたは30日のトライアル期間の後に MySQL ライセンスを必要とします。 See Win license.

あなたが購入の前に試みることができる MySQL-Win32 のシェアウェアバージョンは http://www.mysql.com/mysql_w32.htmy. にあります. これは安定版の MySQL をベースにフル・デバッグモードでコンパイルしており、正式登録版に比べて速度は遅くなっています。ライセンス代を支払った後に,あなたは最も新しい MySQL-Win32 バージョンにアクセスするためのパスワードを得るでしょう.

（日本語版 MySQL-Win32 の評価版と申し込みは http://www.softagency.co.jp/. ）

The reason for always requiring a license under Microsoft Windows is that because Windows is a highly commercial OS with very high development costs (it usually takes 3 times longer to build and test things under windows), we see no other alternative than only give the latest MySQL Windows version to paying customers.  If we didn't do this we would not be able to keep up development on Windows.

We do give free MySQL licenses on request in the following cases:

  * Educational purposes, like teaching students.

  * Non-commercial research settings.

  * Churches.

  * Registered charity organizations.

  * Individual students who have database related educational project.

  * People who help us with MySQL development in some constructive manner.

If something of the above applies to you, you can apply for a license by sending an email to mysql-licensing@mysql.com. This should include a full description of for what you need a free MySQL license.

As soon as we can afford it we plan to release MySQL Win32 under the same license as MySQL under other OS.  This will however also require that we can find some Windows developers that would like to work on MySQL development under Windows and build windows version for all MySQL releases.

Copyrights used by MySQL
========================

There are several different copyrights on the MySQL distribution:

MySQL 配布における、いくつか異なるコピーライトを示します：

 1. The MySQL-specific source needed to build the mysqlclient library and programs in the client directory is in the public domain. Each file that is in the public domain has a header which clearly states so. This includes everything in the client directory and some parts of the mysys, mystring and dbug libraries.

 2. Some small parts of the source (GNU getopt) are covered by the ``GNU LIBRARY LIBRARY GENERAL PUBLIC LICENSE''.  See the mysys/COPYING.LIB file.

 3. Some small parts of the source (GNU readline) are covered by the ``GNU GENERAL PUBLIC LICENSE''. See the readline/COPYING file.

 4. Some parts of the source (the regexp library) are covered by a Berkeley style copyright.

 5. The other source needed for the MySQL server on non-Microsoft platforms is covered by the ``MySQL FREE PUBLIC LICENSE'', which is based on the ``Aladdin FREE PUBLIC LICENSE.'' See Public license. When running MySQL on any Microsoft operating system, other licensing applies.

 1. client ディレクトリ以下の mysqlclient ライブラリとプログラム群を作成するに必要とされる特定の MySQL のソースは、パブリックドメインです。それぞれのパブリックドメイン下のファイルの冒頭には、その事を明記してあります。これは、client ディレクトリ以下の全ファイルと、 mysys, mystring, dbug ライブラリのいくつかを含みます。

 2. ソースのいくつかの部分は (GNU getopt) ``GNU LIBRARY GENERAL PUBLIC LICENSE'' に従って変更したものです。See the mysys/COPYING.LIB file.

 3. ソースのいくつかの部分は (GNU readline) ``GNU GENERAL PUBLIC LICENSE'' に従って変更したものです。 See the readline/COPYING file.

 4. ソースのいくつかの部分は (regexp library) バークレイスタイルのコピーライトに従って変更したものです。

 5. 非Microsoft プラットフォームの MySQL サーバーに必要なソースは、 ``MySQL FREE PUBLIC LICENSE'' 下にあります。このライセンスは ``Aladdin FREE PUBLIC LICENSE'' を元にしています see Public license。 Microsoftのオペレーティングシステム上で MySQL を使用する場合は、違うライセンスが適用されます。See Win license

The following points set forth the philosophy behind our copyright policy:

以下にわれわれのコピーライトの基本理念を示します：

  * The SQL client library should be totally free so that it can be included in commercial products without limitations.

  * People who want free access to the software into which we have put a lot of work can have it, so long as they do not try to make money directly by distributing it for profit.

  * People who want the right to keep their own software proprietary, but also want the value from our work, can pay for the privilege.

  * That means normal in-house use is FREE. But if you use MySQL for something important to you, you may want to help further its development by purchasing a license or a support contract.  See Support.

  * 本 SQL client ライブラリーは無償であること。これは商用の製品に対しても無制限であることを含む。

  * 商売のための配布を行って対価を得ようとしない限りは、我々が尽力して作った本ソフトウェアに制限なくアクセスできる。

  * 自分自身のソフトウェアの独占権もほしいが,我々のソフトを使用して対価も得たいと考えている人々は,特権を買うことができます.

  * それは,通常の内部の使用が無料であることを意味します。しかし,あなたにとって何か重要なものにそれを使用するならば, あなたは,サポート契約を購入することによって, MySQL の一層の開発をサポートしたがるかもしれません.

Possible future copyright changes
---------------------------------

We may choose to distribute older versions of MySQL with the GPL in the future. However, these versions will be identified as GNU MySQL. Also, all copyright notices in the relevant files will be changed to the GPL.

我々は,将来 GPL で MySQL の旧式のバージョンを配布する事を選ぶかもしれません. この場合,これらのバージョンは GNU MySQL とするつもりです. また,関連ファイルの中のすべての版権情報を GPL に変えるつもりです.

Distributing MySQL commercially 商用配布
====================================

This section is a clarification of the license terms that are set forth in the ``MySQL FREE PUBLIC LICENSE'' (FPL).  See Public license.

以下に ``MySQL FREE PUBLIC LICENSE'' (FPL) を明確に記します. See Public license.

MySQL may be used freely, including by commercial entities for evaluation or unsupported internal use. However, distribution for commercial purposes of MySQL, or anything containing or derived from MySQL in whole or in part, requires a written commercial license from TcX AB, the sole entity authorized to grant such licenses.

MySQL の使用には制限はありません。これは商用利用のための評価や、内部で非サポートで使用することを含みます。しかし次の条件では TcX AB (ライセンスを与える権限を持つ唯一の機関) によって記載された商用ライセンスが必要です。 MySQL 自身を商用目的で配布すること。 MySQL の一部、あるいは全部を含んだ物を商用目的で配布すること。 MySQL を利用して作った物の一部、あるいは全部を含んだ物を商用目的で配布すること。

You may not include MySQL ``free'' in a package containing anything for which a charge is being made, except as noted below.

金銭が発生するいかなる物の中にも、MySQL を ``無償'' で含んではいけません。ただし、以下は除きます。

The intent of the exception provided in the second clause of the license is to allow commercial organizations operating an FTP server or a bulletin board to distribute MySQL freely from it, provided that:

本ライセンスの２番目に例外措置をもうけている意図は、営利団体が運営している FTP サーバー、掲示板等で、自由に MySQL を配布することを許可するためです。

 1. The organization complies with the other provisions of the FPL, which include among other things a requirement to distribute the full source code of MySQL and of any derived work, and to distribute the FPL itself along with MySQL;

 2. The only charge for downloading MySQL is a charge based on the distribution service and not one based on the content of the information being retrieved (i.e., the charge would be the same for retrieving a random collection of bits of the same size);

 3. The server or BBS is accessible to the general public, i.e., the phone number or IP address is not kept secret, and anyone may obtain access to the information (possibly by paying a subscription or access fee that is not dependent on or related to purchasing anything else).

 1. その団体は FPL の他の条項を受け入れること。その要求の中でもとりわけ MySQL といかなる派生物の全ソースの配布と、 MySQL と一緒に FPL 自身を配布することは受け入れること。

 2. MySQL をダウンロードする行為にだけ課金する場合で、この値段は配布サービスの費用であり、受信する対象物によって変わらない事。 (例えば、受信する物が違っていても受信量が同じであれば同じ値段であること。)

 3. サーバー、BBS は一般に公開されていてアクセス可能なこと。例えば、電話番号や IPアドレスが隠されておらず、だれもがその情報にアクセスできること。 (なにかを買うということに関連したり依存したりしない購読料やアクセス料金による物も可)

If you want to distribute software in a commercial context that incorporates MySQL and you do not want to meet these conditions, you should contact TcX AB to find out about commercial licensing, which involves a payment. The only ways you legally can distribute MySQL or anything containing MySQL are by distributing MySQL under the requirements of the FPL, or by getting a commercial license from TcX AB.

MySQL を組み込んだ商業ソフトウェアを配布したいが, これらの条件を満たしたくないならば,あなたは,商業認可に関して TcX AB に連絡するべきです. 商業ライセンスは支払いに影響し,サポートその他の利点を含みます. これらはあなたが MySQL 自身や MySQL を含む物を合法的に配布することができる唯一の方法です: FPLの条件の下に MySQL を配布することか, または TcX AB から商業ライセンスを得ることによって.

Example licensing situations ライセンス例
===================================

This section describes some situations illustrating whether or not you must license the MySQL server.  Generally these examples involve providing MySQL as part of a product or service that you are selling to a customer, or requiring that MySQL be used in conjunction with your product.  In such cases, it is your responsibility to obtain a license for the customer if one is necessary.  (This requirement is waived if your customer already has a MySQL license.  But the seller must send customer information and the license number to TcX, and the license must be a full license, not an OEM license.)

このセクションでは、あなたがどういった状況で MySQL サーバライセンスを得なければならないか否かを、いくつか説明します。一般にこれらの例は、 MySQL が、あなたが顧客に売っている製品やサービスの一部に含まれている場合や、あなたの製品が MySQL の使用を要求している場合などです。このような場合、顧客のためにライセンスを得るのはあなたの責任です。（ただし、すでにその顧客が MySQL のライセンスを持っている場合はのぞきます。が、売り手は顧客の情報とライセンスナンバーをTcXに送る必要があり、かつ、そのライセンスはOEMライセンスではなく、フルライセンスでなければなりません。）

Note that a single MySQL license covers any number of CPUs/users/customers/mysqld servers on a machine!

MySQL ライセンス一つで、一台のマシン上の、全 CPU数/ユーザー数/顧客数/mysqld 数をカバーします。

Selling products that use MySQL
-------------------------------

To determine whether or not you need a MySQL license when selling your application, you should ask whether the proper functioning of your application is contingent on the use of MySQL and whether you include MySQL with your product.  There are several cases to consider:

アプリケーションを販売するとき、あなたが MySQL ライセンスを必要とするかどうか決定するためには, あなたのアプリケーションが適切に機能するためには MySQL を必要とするかどうか、製品に MySQL を含むかどうかを尋ねるべきです. 考えうるいくつかのケースがあります:

  * Does your application require MySQL to function properly?

     If your product requires MySQL, you need a license for any machine that runs the mysqld server.  For example, if you've designed your application around MySQL, then you've really made a commercial product that requires the engine, so you need a license.

     If your application does not require MySQL, you need not obtain a license.  For example, if MySQL just added some new optional features to your product (such as adding logging to a database if MySQL is used rather than logging to a text file), it should fall within normal use, and a license would not be required.

     In other words, you need a license if you sell a product designed specifically for use with MySQL or that requires the MySQL server to function at all.  This is true whether or not you provide MySQL for your client as part of your product distribution.

     It also depends on what you're doing for the client.  Do you plan to provide your client with detailed instructions on installing MySQL with your software?  Then your product may be contingent on the use of MySQL; if so, you need to buy a license.  If you are simply tying into a database that you expect already to have been installed by the time your software is purchased, then you probably don't need a license.

  * Do you include MySQL in a distribution and charge for that distribution?

     If you include MySQL with a distribution that you sell to customers, you will need a license for any machine that runs the mysqld server, because in this case you are selling a system that includes MySQL.

     This is true whether the use of MySQL with your product is required or optional.

  * Do you neither require for your product nor include MySQL with it?

     Suppose you want to sell a product that is designed generally to use ``some database'' and that can be configured to use any of several supported alternative database systems (MySQL, PostgreSQL, or something else).  That is, your product does not not require MySQL, but can support any database with a base level of functionality, and you don't rely on anything that only MySQL supports.  Does one of you owe us money if your customer actually does choose to use MySQL?

     In this case, if you don't provide, obtain or set up MySQL for the customer should the customer decide to use it, neither of you need a license.  If you do perform that service, see MySQL services.

  * あなたのアプリケーションが適切に機能するためには、MySQL を必要としますか?

     あなたの製品が MySQL を必要とするならば,mysqld サーバを走らせるどんなマシンにもライセンスを必要とします. 例えばあなたが MySQL の周りで自分のアプリケーションを設計したならば、本当にエンジンを必要とする商業製品を作った事になるので、ライセンスが必要です.

     あなたのアプリケーションが MySQL を必要としないならば,あなたはライセンスを得る必要はありません。 例えば MySQL がただあなたの製品にいくつかの新しい任意の特徴を加えたならば（テキストファイルへのロギングより、データベースへのロギングに MySQL が使用されるような場合）、それは通常の使用下なので、ライセンスは必要ないでしょう。

     言い換えれば, MySQL とともに使用される製品を売る場合や、完全に機能するために MySQL を必要とするのであれば、ライセンスが必要です。あなたが MySQL を製品の一部として顧客に配布しようがしまいが、この場合にはライセンスが必要です。

     また、あなたが顧客のためにしている事にも依ります。あなたは,あなたのソフトウェアとともに MySQL をインストールし、顧客に提供するのを計画していますか?  そのばあい,あなたの製品は MySQL の使用を条件としていますか ； そうだとすれば, あなたは,ライセンスを買う必要があります. If you are simply tying into a database that you expect already to have been installed by the time your software is purchased, then you probably don't need a license.

  * MySQL を配布物に含め、その配布物に料金をかしますか？

     もし顧客に売る配布物に MySQL を含めるのであれば、 mysqld サーバーの走るいかなるマシンにライセンスが必要です。なぜなら、 MySQL を含むシステムを売っているからです。

     これは製品が MySQL の使用を必須としていようがオプションとしていようが、適用されます。

  * あなたの製品は MySQL をその中に含むことを要求しますか？

     ``なんらかのデータベース'' の使用をデザインしている製品で、この製品がいくつかのデーターベースシステム (MySQL, PostgreSQL, or something else) の中から代わりのもを使用するように調整可能できる製品、こういった物をあなたが売ろうとしていると仮定します。この場合、あなたの製品は MySQL を必要としませんが、いかなるデータベースの基本機能をサポートしており、 MySQL だけをサポートしているものではありません。が、もし顧客が MySQL の使用を選んだ場合に、あなたが我々に支払う義務があるのか？

     この場合、もしその顧客のために、あなたが MySQL を提供したりあるいは、入手したり、セットアップしたりしていないならば、あなたにライセンスは不要です。もしあなたが顧客にこういったサービスを提供するなら、MySQL services.

Selling MySQL-related services MySQL 関連サービスを売る
----------------------------------------------

If you perform MySQL installation on a client's machine and any money changes hands for the service (directly or indirectly), then you must buy a MySQL license.

もし MySQL をクライアントにインストールし、そのサービスでなんらかの代価をえるならば（直接、間接問わず）、あなたは MySQL ライセンスを購入しなくてはなりません。

If you sell an application for which MySQL is not strictly required but can be used, a license may be indicated, depending on how MySQL is set up.  Suppose your product neither requires MySQL nor includes it in your product distribution, but can be configured to use MySQL for those customers who so desire.  (This would be the case, for example, if your product can use any of a number of database engines.)

MySQL は完全に必要というわけではないが,MySQL を使用することができるアプリケーションを販売するならば,  MySQL をセットアップする方法によって, ライセンスは必要になる場合があります。あなたの製品配布物の中に MySQL が含まれておらず、また、 MySQL を必要としていないが、あなたの製品は顧客の希望に合わせて MySQL を使用するように調整できるものだと仮定します。（例えば,あなたの製品が多くのデータベースエンジンのどれかを使用することができるならば,この場合に該当するでしょう.）

If the customer obtains and installs MySQL, no license is needed. If you perform that service for your customer, then a license is needed because then you are selling a service that includes MySQL.

もし顧客自身が MySQL を入手しインストールするならば、あなたにライセンスは不要です。もしあなたがそういったサービスを顧客に行うなら、ライセンスは必要です。なぜなら、 MySQL を含んだサービスをあなたが売ることになるからです。

ISP MySQL services
------------------

Internet Service Providers (ISPs) often host MySQL servers for their customers.

If you are an ISP that allows customers to install and administer MySQL for themselves on your machine with no assistance from you, neither you nor your customer need a MySQL license. Note that this doesn't apply if you are are using Win32;  In this case you will always need a license for each computer that runs the MySQL server.

If you charge for MySQL installation and administrative support as part of your customer service, then you need a license because you are selling a service that includes MySQL.

インターネットサービスプロバイダー(ISP) は MySQL サーバーを自分のお客に提供することもしばしばです。

もしあなたが ISP で、顧客があなたのマシンに MySQL をインストールして管理する事を許可しているのであれば(あなたの手助けは無しで)、あなたと顧客のどちらにも MySQL ライセンスは不要です。もし Win32 を使用しているなら、これは適用されないことに注意してください。 Win32 の場合は、MySQL サーバーを実行するコンピュータ毎にライセンスが必要です。

もしあなたが顧客サービスとして MySQL をインストールし管理することに料金をかすなら、あなたは MySQL を含んだサービスを売っていることになるので、あなたはライセンスが必要です。

Running a web server using MySQL
--------------------------------

If you use MySQL in conjunction with a web server on Unix, you don't have to pay for a license.

This is true even if you run a commercial web server that uses MySQL, since you are not selling MySQL itself.  However, in this case we would like you to purchase MySQL support, because MySQL is helping your enterprise.

もしあなたが UNIX 上で Webサーバー とともに MySQL を使用するなら、ライセンスを買う必要はありません。

これはたとえ MySQL を使用した商用の Webサーバー を走らせていても、 MySQL 自身を売っていないので、ライセンスを買う必要はありません。しかしこの場合、我々はあなたが MySQL サポート契約をすることを望みます。なぜなら、MySQL はあなたの事業を助けているからです。

MySQL licensing and support costs
=================================

Our current license prices are shown below. All prices are in US Dollars. If you pay by credit card, the currency is EURO (European Union Euro) so the prices will differ slightly.

現在のライセンスの価格を以下に示します。全ての価格は US ドルです。もしあなたがクレジットカードで買いたいならば、通貨は EURO (European Union Euro) です。（価格がわずかに異なる）

Number of licenses   Price per copy   Total
1                    US $200   US $200
10 pack              US $150   US $1500
50 pack              US $120   US $6000

For high volume (OEM) purchases, the following prices apply:

大量購入(OEM 販売)の場合は：

Number of licenses    Price per copy   Minimum at one time   Minimum payment
100-999     US $40          100                       US $4000
1000-2499   US $25          200                       US $5000
2500-4999   US $20          400                       US $8000

For OEM purchases, you must act as the middle-man for eventual problems or extension requests from your users. We also require that OEM customers have at least an extended email support contract.  Note that OEM licenses only apply for products where the user doesn't have direct access to the MySQL server (embedded system). In other words: The MySQL server should only be used with the application that was supplied you.

　OEM 販売をする場合、ユーザーからの問題や要望に対して、あなたは仲買人として振る舞わなくてはなりません。われわれは OEM の客に対し、少なくとも拡張電子メールサポート契約を要求します。 OEM ライセンスは、MySQL サーバーに直接アクセスする必要のない製品にのみ適用されます (組み込みシステム)。 いうならば、 MySQL は、ただ、あなたが提供しているアプリケーションと共にのみ使用されなくてはなりません。 (OEM 供給を受けた MySQL サーバーライセンスのみを単体で売ることはできません。)

If you have a low-margin high-volume product, you can always talk to us about other terms (for example, a percent of the sale price). If you do, please be informative about your product, pricing, market and any other information that may be relevant.

　もしあなたが薄利多売の製品を持っているなら、他の条件についていつでも我々と話し合うことができます(例えば売値のパーセンテージとか)。もしあなたが製品を売りたいなら、あなたの製品説明、値段、市場、その他関連項目を我々に知らせてください。

After buying 1 MySQL licenses, you will get a personal copy of the myisampack utility.  You are not allowed to redistribute this utility but you can distribute tables packed with it.

1 MySQL ライセンスの購入後、myisampack ユーティリティーが個人むけにコピーできます。これの再配布は許可されませんが、 myisampack でパックしたテーブルは配布できます。

A full-price license is not a support agreement and includes very minimal support. This means that we try to answer any relevant question. If the answer is in the documentation, we will direct you to the appropriate section. If you have not purchased a license or support, we probably will not answer at all.

完全な価格ライセンスはサポート協定でなく,非常に最小限のサポートを含みます. これは,我々がどんな関連質問にも答えようとする事を意味します. 返事がドキュメントにあるならば, 我々は適切なセクションをあなた示すつもりです. あなたがライセンスかサポートを購入しなかったならば, 我々はたぶん全く答えるつもりはありません.

If you discover what we consider a real bug, we are likely to fix it in any case. But if you pay for support we will notify you about the fix status instead of just fixing it in a later release.

もしあなたが、我々が本当にバグだと考える物を見つけた場合、いかなる場合でもそれを修正します。しかし, あなたがサポートを支払うならば, 後のリリースでそれを修正する事の代わりに、我々は修正状態に関してあなたに通知するつもりです.

More comprehensive support is sold separately.  Descriptions of what each level of support includes are given in Support.  Costs for the various types of commercial support are shown below.  Support level prices are in EURO (European Union Euro). One EURO is about 1.17 USD.

より包括的なサポートは別々に販売されます. それぞれのレベルのサポートが含む事に関する記述は Support. にあります。様々なタイプの商用サポートの価格は以下に示します. サポートレベル価格は EURO (European Union Euro) です。 1 EURO はおよそ 1.17 USD です.

Type of support   Cost per year
Basic email support        EURO 170
Extended email support     EURO 1000
Login support              EURO 2000
Extended login support     EURO 5000

You may upgrade from any lower level of support to a higher level of support for the difference between the prices of the two support levels.

下位レベルのサポートから、それより高いレベルのサポートに、 2つのサポートの価格差分の支払いで、アップグレードが可能です。

Payment information
-------------------

Currently we can take SWIFT payments, cheques or credit cards.

現在,SWIFT支払い,小切手またはクレジットカードでの支払いができます.

Payment should be made to: 振込先は：

     Postgirot Bank AB
     105 06 STOCKHOLM, SWEDEN

     TCX DataKonsult AB
     BOX 6434
     11382 STOCKHOLM, SWEDEN

     SWIFT address: PGSI SESS
     Account number: 96 77 06 - 3

Specify: license and/or support and your name and email address.

あなたの購入ライセンス かつ/又は サポートと,名前と Eメールアドレスを記述のこと。

In Europe and Japan you can use EuroGiro (that should be less expensive) to the same account.

ヨーロッパと日本では,あなたは支払いに EuroGiro(それが高価ではない) を使用することができます.

If you want to pay by cheque, make it payable to ``MySQL Finland AB'' and mail it to the address below:

あなたが小切手によって支払いたいと思っているならば,それを ``Monty Program KB'' に支払い満期にして, 以下のアドレスに郵送してください.

     TCX DataKonsult AB
     BOX 6434, Torsgatan 21
     11382 STOCKHOLM, SWEDEN

If you want to pay by credit card over the Internet, you can use TcX's secure license form (https://www.tcx.se/license.htmy).

インターネット上でクレジットカードで支払いたいと思っているならば, あなたは TcXの安全なライセンスフォーム (https://www.tcx.se/license.htmy) を使用することができます.

You can also print a copy of the license form, fill it in and send it by fax to:

また上のページのコピーを印刷して書き込み,ファックスを使って以下にそれを送ることもできます.

+46-8-729 69 05

If you want us to bill you, you can use the license form and write ``bill us'' in the comment field.  You can also mail a message to sales@mysql.com (not mysql@lists.mysql.com!) with your company information and ask us to bill you.

請求書を送って欲しい場合,あなたはライセンスフォームを使用し, 注釈欄に ``請求書 希望'' を書いてください. あるいは,あなたの会社の情報を記載したメッセージを sales@mysql.com におくり, (mysql@lists.mysql.com ではありません!) 請求書を送るように我々に依頼する事もできます。

Contact information
-------------------

For commercial licensing, or if you have any questions about any of the information in this section, please contact the MySQL licensing team. The much preferred method is by E-Mail to mysql-licensing@mysql.com. Fax is also possible but handling of these may take much longer (Fax +46-8-729 69 05).

商業認可か本セクションに関する質問があるならば,以下に連絡してください

     David Axmark
     Detron HB
     Kungsgatan 65 B
     753 21 UPPSALA
     SWEDEN
     Voice Phone +46-18-10 22 80     (Timezone GMT+1. Swedish and English spoken)

Types of commercial support
===========================

Basic email support 基本電子メールサポート
-------------------------------

Basic email support is a very inexpensive support option and should be thought of more as a way to support our development of MySQL than as a real support option.  We at TCX do give a lot of free support in all the different MySQL lists and the money we get from basic eamil support is largely used to make this possible.

基本電子メールサポートは非常に費用のかからないサポートオプションであり, 我々の MySQL の開発をサポートする本当のサポートオプションで、よりよい方法として考えられるべきです.

At this support level, the MySQL mailing lists are the preferred means of communication.  Questions normally should be mailed to the primary mailing list (mysql@lists.mysql.com) or one of the other regular lists (for example, mysql-win32@lists.mysql.com for Windows-related MySQL questions), as someone else already may have experienced and solved the problem you have.  See Asking questions.

このサポートレベルでは, MySQL メーリングリストはコミュニケーションを取るには好まれる方法です. 通常, 質問は主要なメーリングリスト (mysql@lists.mysql.com) か他のメーリングリストのどれかに送信されるべきで、（例えば, Windows に関連する MySQL の質問のための mysql-win32@lists.mysql.com ）これは他の誰かが同じ問題を経験して, 既に解決しているかもしれないからです。 See Asking questions.

However, by purchasing basic email support, you also have access to the support address mysql-support@mysql.com, which is not available as part of the minimal support that you get by purchasing a MySQL license.  This means that for especially critical questions, you can cross-post your message to mysql-support@mysql.com.  (If the message contains sensitive data, you should post only to mysql-support@mysql.com.)

REMEMBER! to ALWAYS include your registration number and expiration date when you send a message to mysql-support@mysql.com.

しかし、基本電子メールサポートを購入することによって, あなたはサポートアドレス mysql-support@mysql.com にアクセスできます. (このメールアドレスは最小の MySQL ライセンスの購入では利用不可能です。) これは特に重要な質問のために使用されており、また、mysql-support@mysql.com. とクロスポストすることも可能です。（メッセージに機密のデータが含まれる場合、あなたは mysql-support@mysql.com. だけに送信するべきです.）

メッセージを mysql-support@mysql.com に送るときは、迅速な応答を確実にするために、必ずあなたの登録番号と満了日付を書き添えてください。

Note that if you have encountered a critical repeatable bug and follow the rules outlined in the manual section of how to report bugs and send it to bugs@lists.mysql.com we promise to try to fix this as soon as possible, independent of your support level! See Bug reports.

Basic email support includes the following types of service:

基本電子メールサポートは以下のサービスを含みます：

  * If your question is already answered in the manual, we will inform you of the correct section in which you can find the answer.  If the answer is not in the manual, we will point you in the right direction to solve your problem.

  * We guarantee a timely answer for your email messages.  We can't guarantee that we can solve any problem, but at least you will receive an answer if we can contact you by email.

  * We will help with unexpected problems when you install MySQL from a binary distribution on supported platforms.  This level of support does not cover installing MySQL from a source distribution.  ``Supported'' platforms are those for which MySQL is known to work. See Which OS.

  * We will help you with bugs and missing features. Any bugs that are found are fixed for the next MySQL release. If the bug is critical for you, we will mail you a patch for it as soon the bug is fixed.  Critical bugs always have the highest priority for us, to ensure that they are fixed as soon as possible.

  * Your suggestions for the further development of MySQL will be taken into consideration. By taking email support you have already helped the further development of MySQL. If you want to have more input, upgrade to a higher level of support.

  * If you want us to help optimize your system, you must upgrade to a higher level of support.

  * もしあなたの質問が既にマニュアルで答えられているのであれば、答えを見つけれるであろう正しいセクションをあなたに教えます。もし答えがマニュアルに無ければ、問題解決のための正しい方向を指し示します。

  * 素早い返信を保証致します。必ずしもどんな問題も解決できると保証は致しませんが、あなたが E メールでコンタクト可能ならば少なくとも返信は受け取るでしょう。

  * サポートされているプラットフォームにおいてバイナリー配布形態から MySQL をインストールする時、予期しない問題が現れた場合お助け致します。このレベルのサポートではソース配布形態から MySQL をインストールする場合はふくまれておりません。``サポート対象'' プラットフォームとは、 MySQL が動作すると知られているものです see Which OS.

  * バグや足りない機能がある場合 。見付かったバグに付いては次期 MySQL リリースにおいて直されます。もしそのバグがあなたにとって致命的であれば、修正次第そのバグの対するパッチをメールでお送りします。致命的バグは常に高い優先度になり、可能な限り速く、修正が行われます。

  * さらなる MySQL 開発のためにあなたの意見は考慮されます。あなたが E メールサポートをお持ちならば、もう既に MySQL の更なる開発への手助けをされている事になります。もっと意見を取り入れたいならば、上位のサポートにアップグレードしてください。

  * もしあなたが私供によるのシステムの最適化の手助けをお望みであれば、更に上位のサポートへアップグレードする必要があります。

  * We include a binary version of the myisampack packing tool for creating fast compressed read-only databases. The current server includes support for reading such databases but not the packing tool used to create them.

Extended email support 拡張電子メールサポート
----------------------------------

Extended email support includes everything in basic email support with these additions:

  * Your email will be dealt with before mail from basic email support users and non-registered users.

  * Your suggestions for the further development of MySQL will receive strong consideration. Simple extensions that suit the basic goals of MySQL are implemented in a matter of days. By taking extended email support you have already helped the further development of MySQL.

  * Typical questions that are covered by extended email support are:

       - We will answer and (within reason) solve questions that relate to possible bugs in MySQL.  As soon as the bug is found and corrected, we will mail a patch for it.

       - We will help with unexpected problems when you install MySQL from a source or binary distribution on supported platforms.

       - We will answer questions about missing features and offer hints how to work around them.

       - We will provide hints on optimizing mysqld for your situation.

  * You are allowed to influence the priority of items on the MySQL TODO. This will ensure that the features you really need will be implemented sooner than they might be otherwise.

Login support ログインサポート
----------------------

Login support includes everything in extended email support with these additions:

  * Your email will be dealt with even before mail from extended email support users.

  * Your suggestions for the further development of MySQL will be taken into very high consideration.  Realistic extensions that can be implemented in a couple of hours and that suit the basic goals of MySQL will be implemented as soon as possible.

  * If you have a very specific problem, we can try to log in on your system to solve the problem ``in place.''

  * Like any database vendor, we can't guarantee that we can rescue any data from crashed tables, but if the worst happens we will help you rescue as much as possible. MySQL has proven itself very reliable, but anything is possible due to circumstances beyond our control (for example, if your system crashes or someone kills the server by executing a kill -9 command).

  * We will provide hints on optimizing your system and your queries.

  * You are allowed to call a MySQL developer (in moderation) and discuss your MySQL-related problems.

Extended login support 拡張ログインサポート
---------------------------------

Extended login support includes everything in login support with these additions:

  * Your email has the highest possible priority.

  * We will actively examine your system and help you optimize it and your queries. We may also optimize and/or extend MySQL to better suit your needs.

  * You may also request special extensions just for you. For example:

          mysql> select MY_CALCULATION(col_name1,col_name2) from tbl_name;

  * We will provide a binary distribution of all important MySQL releases for your system, as long as we can get an account on a similar system. In the worst case, we may require access to your system to be able to create a binary distribution.

  * If you can provide accommodations and pay for traveler fares, you can even get a MySQL developer to visit you and offer you help with your troubles. Extended login support entitles you to one personal encounter per year, but we are as always very flexible towards our customers!

MySQL のインストール
*************

この章では、どのようにして MySQL を得、インストールするのかをのべます:

  * MySQL を得ることができるサイトのリスト → Getting MySQL.

  * どのプラットフォームをサポートしているかは → Which OS.

  * MySQL のいくつかのバージョンは、バイナリ、ソース両方の配布物があります。どのバージョンを使用するのか、どのタイプを使用するかを決めるためには → Many versions.

  * バイナリとソースのインストールについては → Installing binary, と Installing source. それぞれのセットには、あなたが出くわすかもしれないシステムに特有の問題のセクションが含まれます。

  * インストール後に行うことの説明は → Post-installation. MySQL のインストールにおいて、バイナリまたはソース配布にかかわらず、これらのプロシージャは適用します。

MySQL を得る方法
===========

現在のバージョンとダウンロードの指示についての情報は MySQL ホームページ (http://www.mysql.com/) をチェックしてください。

しかし、TcX のインターネット接続はそんなに速くありません; 下記に一覧されたミラーサイトの一つから実際にダウンロードすることをお勧めします。

悪いまたは遅れているミラーは webmaster@mysql.com に報告してください。

ヨーロッパ:

  * Austria [Univ. of Technology/Vienna] WWW (http://gd.tuwien.ac.at/db/mysql/) FTP (ftp://gd.tuwien.ac.at/db/mysql/)

  * Bulgaria [Naturella] WWW (http://archive.nat.bg/pub/mirror/mysql/) FTP (ftp://ftp.ntrl.net/pub/mirror/mysql/)

  * Croatia [HULK] WWW (http://ftp.linux.hr/pub/mysql/) FTP (ftp://ftp.linux.hr/pub/mysql/)

  * Czech Republic [Masaryk University in Brno] WWW (http://mysql.linux.cz/index.html) FTP (ftp://ftp.fi.muni.cz/pub/mysql/)

  * Czech Republic [www.sopik.cz] WWW (http://www.mysql.cz/)

  * Czech Republic [www.gin.cz] WWW (http://mysql.gin.cz/) FTP (ftp://ftp.gin.cz/pub/MIRRORS/www.mysql.com/)

  * Denmark [Borsen] WWW (http://mysql.borsen.dk/)

  * Denmark [SunSITE] WWW (http://SunSITE.auc.dk/mysql/) FTP (ftp://SunSITE.auc.dk/pub/databases/mysql/)

  * Estonia [OKinteractive] WWW (http://mysql.mirror.ok.ee)

  * France [minet] WWW (http://www.minet.net/devel/mysql/)

  * Finland [EUnet] WWW (http://mysql.eunet.fi/)

  * Finland [clinet] FTP (ftp://ftp.clinet.fi/mirrors/ftp.mysql.org/pub/mysql/)

  * Germany [Bonn University, Bonn] WWW (http://www.wipol.uni-bonn.de/MySQL//) FTP (ftp://ftp.wipol.uni-bonn.de/pub/mirror/MySQL/)

  * Germany [Wolfenbuettel] WWW (http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/) FTP (ftp://ftp.fh-wolfenbuettel.de/pub/database/mysql/)

  * Germany [Staufen] WWW (http://mysql.staufen.de/)

  * Germany [Cable & Wireless] FTP (ftp://ftp.ecrc.net/pub/database/mysql/)

  * Greece [NTUA, Athens] WWW (http://www.ntua.gr/mysql/) FTP (ftp://ftp.ntua.gr/pub/databases/mysql/)

  * Island [GM] WWW (http://mysql.gm.is/) WWW (ftp://ftp.gm.is/pub/mysql)

  * Italy [Teta Srl] WWW (http://www.teta.it/mysql/)

  * Ireland [Ireland On-Line/Dublin] WWW (http://mysql.iol.ie) FTP (ftp://ftp.iol.ie/pub/mysql)

  * Poland [Sunsite] WWW (http://sunsite.icm.edu.pl/mysql/) FTP (ftp://sunsite.icm.edu.pl/pub/unix/mysql/)

  * Portugal [lerianet] WWW (http://mysql.leirianet.pt) FTP (ftp://ftp.leirianet.pt/pub/mysql/)

  * Russia [DirectNet] WWW (http://mysql.directnet.ru) FTP (ftp://ftp.dn.ru/pub/MySQL)

  * Russia [IZHCOM] WWW (http://mysql.udm.net/) FTP (ftp://ftp.izhcom.ru/pub/mysql/)

  * Russia [Scientific Center/Chernogolovka] FTP (ftp://ftp.chg.ru/pub/databases/mysql/)

  * Romania [Timisoara] WWW (http://www.dnttm.ro/mysql) FTP (ftp://ftp.dnttm.ro/pub/mysql)

  * Romania [Bucharest] WWW (http://www.lbi.ro/MySQL) FTP (ftp://ftp.lbi.ro/mirrors/ftp.tcx.se)

  * Sweden [Sunet] WWW (http://ftp.sunet.se/pub/unix/databases/relational/mysql/) FTP (ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/)

  * Switzerland [Sunsite] WWW (http://sunsite.cnlab-switch.ch/ftp/mirror/mysql/) FTP (ftp://sunsite.cnlab-switch.ch/mirror/mysql/)

  * UK [Omnipotent/UK] WWW (http://mysql.omnipotent.net/) FTP (ftp://mysql.omnipotent.net/)

  * UK [PLiG/UK] WWW (http://ftp.plig.org/pub/mysql/) FTP (ftp://ftp.plig.org/pub/mysql/)

  * UK [SunSITE] WWW (http://sunsite.org.uk/packages/mysql/) FTP (ftp://sunsite.org.uk/packages/mysql/)

  * Ukraine [PACO] WWW (http://mysql.paco.net.ua) FTP (ftp://mysql.paco.net.ua/)

北アメリカ:

  * Canada [Tryc] WWW (http://web.tryc.on.ca/mysql/)

  * Canada [Cyberus] WWW (http://mysql.cyberus.ca/) FTP (ftp://mysql.cyberus.ca/)

  * USA [Hurricane Electric/San Jose] WWW (http://mysql.he.net)

  * USA [Meltzer/New York State] FTP (ftp://ftp.meltzer.org/pub/mysql/)

  * USA [Circle Net/North Carolina] WWW (http://www.mysql.net)

  * USA [Gina net/Florida] WWW (http://www.gina.net/mysql/)

  * USA [Wisconsin University/Wisconsin] WWW (http://mirror.sit.wisc.edu/mysql/) FTP (ftp://mirror.sit.wisc.edu/mirrors/mysql/)

  * USA [DIGEX] FTP (ftp://ftp.digex.net/pub/packages/database/mysql/)

  * USA [LinuxWired/Scottsdale, AZ] WWW (http://mysql.linuxwired.net/) FTP (ftp://ftp.linuxwired.net/pub/mirrors/mysql/)

南アメリカ:

  * Brazil [Matrix] WWW (http://mysql.matrix.com.br)

  * Chile [Vision] WWW (http://mysql.vision.cl/)

アジア:

  * China [Freecode] WWW (http://mysql.freecode.com.cn)

  * China [Hong Kong] WWW (http://mysql.islnet.net)

  * China [Netfirm] WWW (http://mysql.netfirm.net)

  * Korea [KREONet] WWW (http://linux.kreonet.re.kr/mysql/)

  * Japan [SoftAgency] WWW (http://www.softagency.co.jp/MySQL) 日本語版MySQLのダウンロード(WWW) (http://www.softagency.co.jp/)

  * Japan [Nagoya Syouka University] WWW (http://mirror.nucba.ac.jp/mirror/mysql) FTP (ftp://mirror.nucba.ac.jp/mirror/mysql)

  * Singapore [HJC] WWW (http://mysql.hjc.edu.sg) FTP (ftp://ftp.hjc.edu.sg/mysql)

  * Taiwan [HT] WWW (http://mysql.ht.net.tw)

  * Taiwan [TTN] WWW (http://mysql.ttn.net)

オーストラリア:

  * Australia [AARNet/Queensland] WWW (http://mirror.aarnet.edu.au/mysql) FTP (ftp://mirror.aarnet.edu.au/pub/mysql)

  * Australia [Blue Planet/Melbourne] WWW (http://mysql.bluep.com/)

  * Australia [ITworks Consulting/Victoria] WWW (http://mysql.itworks.com.au)

アフリカ:

  * South-Africa [Mweb/] WWW (http://www.mysql.mweb.co.za)

  * South-Africa [The Internet Solution/Johannesburg] FTP (ftp://ftp.is.co.za/linux/mysql/)

MySQL がサポートする OS
================

我々は GNU Autoconf を使用していますので、MySQL は POSIX スレッドと C++ コンパイラが動作する全ての新しいシステムに移植可能です。(クライアントコードのコンパイルだけは C++ を必要としますが、スレッドは必要ではありません。) 我々は自身のソフトウェアを、最初に Sun Solaris (現在は 2.5 & 2.6 & 2.7) 上で、より小さい範囲は RedHat Linux 5.0 上で、使用し開発します。

MySQL は次の OS/スレッドパッケージの組み合わせで、コンパイルの成功が報告されています。多くの OS では、ネイティブスレッドは最新バージョンだけで動作することに注意してください。

  * AIX 4.x with native threads

  * BSDI 2.x with the included MIT-pthreads package

  * BSDI 3.0, 3.1 and 4.x with native threads

  * DEC UNIX 4.x with native threads

  * FreeBSD 2.x with the included MIT-pthreads package

  * FreeBSD 3.x with native threads

  * HP-UX 10.20 with the included MIT-pthreads package

  * HP-UX 11.x with the native threads.

  * Linux 2.0+ with LinuxThreads 0.7.1 or glibc 2.0.7

  * MacOS X Server

  * NetBSD 1.3/1.4 Intel and NetBSD 1.3 Alpha (Requires GNU make)

  * OpenBSD > 2.5 with native therads. OpenBSD < 2.5 with the included MIT-pthreads package

  * OS/2 Warp 3, FixPack 29 and OS/2 Warp 4, FixPack 4

  * SGI Irix 6.x with native threads

  * Solaris 2.5 and above with native threads on SPARC and x86

  * SunOS 4.x with the included MIT-pthreads package

  * SCO OpenServer with a recent port of the FSU Pthreads package

  * SCO UnixWare 7.0.1

  * Tru64 Unix

  * Win95, Win98, NT and Win2000 (the newest version is currently available only for users with a MySQL license or MySQL email support).  For those who wish to test before they buy, we have released MySQL 3.22.33 (http://www.mysql.com/mysql_w32.htmy) (an older version) as shareware.

使用する MySQL バージョン
================

make を行う前に決める事は、あなたが最新の開発リリースを使用するのか、または最新の安定リリースを使用するのかです。

  * 通常、あなたが最初に MySQL を使い始める場合、またはバイナリ配布がない他のシステムに MySQL を移植しようとする場合、我々は開発リリース (現在は mysql_version) の選択を勧めます。開発リリースには普通は本当に悪いバグはありません。それは、あなたのマシン上で、 crash-me とベンチマークテストで簡単にテストできます。 See Benchmarks。注意: すべての MySQL リリースはそれぞれのリリースの前に MySQL ベンチマークと広範囲なテストスイートでチェックされます。

  * そうでなくて、古いシステムで実行していてアップグレードしたいけれども、開発版は試したくない場合は、あなたが使用している物と同じブランチ中の最新のもの(あなたが使用している物より新しいバージョンの物)にアップグレードすべきです。 このバージョンでは、致命的なバグだけを修正し、比較的安全で小さな変更を行っています。

make 前の２番目の決定事項は、ソース配布とバイナリ配布のどちらを使用するかです:

  * あなたが現在バイナリ配布が存在するプラットフォーム上で MySQL を実行したいのなら、それを使用してください。通常、ソース配布よりもインストールは簡単です。

  * MySQL を作る C と C++ コードを読みたい(そして/または変更したい) 場合はソース配布を入手するべきです。ソースコードはいつでも究極のマニュアルです。ソース配布はバイナリ配布よりも多くのテストと例も含んでいます。

MySQL の命名法では、リリース番号は3つの数値とサフィックスからなります。例えば、mysql-3.21.17-beta のようなリリース名は次のように解釈されます:

  * 最初の数値(3)はファイル形式を表します。全てのバージョン 3 リリースは同じファイルフォーマットを持ちます。バージョン 4 が現れた時、全てのテーブルは新しい形式に変換する必要があります (このための良いツールはもちろん含まれます)。

  * 2番目の数値(21)はリリースレベルです。通常は二つから選択します。一つはリリース/安定ブランチで(現在は 22)、もう一つは開発ブランチです(現在は 23)。通常は両方とも安定ですが、開発バージョンはきまぐれで、ドキュメントがなく、いくつかのシステムではコンパイルに失敗します。

  * 3番目の数値(17)はリリースレベル内のバージョン番号です。これは新しい配布の度に増加します。普通はあなたの選択したリリースレベルの最新バージョンを求めます。

  * サフィックス(beta)はリリースの安定レベルを表します:

       - alpha は、100% テストされていないいくつかの新しい大きなコードセクションが存在することを示し、知られているバグは News 節に記述されています (通常はありません)。See News。多くの alpha リリースには新しいコマンドと拡張もあります。大きなコード変更を含む開発中のものは、alpha リリース上に現れます。しかし全てリリース前にテストされます。それぞれの MySQL リリースには既知のバグはありません。

       - beta は全ての新しいコードがテストされたことを意味します。大きな新しいものは追加されません。知られているバグはありません。 alpha バージョンで、少なくとも一カ月間、致命的なバグが報告されなくて、古いコマンドをより信頼できなくするような新しい機能を追加する計画がない時に、 alpha から beta にバージョンが変更されます。

       - gamma は beta がしばらくして、正しく動くように見えるものです。小さな修正だけが追加されます。これは多くの他の会社がリリースと呼ぶものです。

       - サフィックスがない場合は、多くの異なる場所で、プラットフォーム固有のバグを除いてバグレポートなしでそのバージョンがしばらくの間動作していたことを意味します。 致命的なバグ修正だけがリリースに適用されます。これは我々が stable リリースと呼ぶものです。

MySQL の全てのバージョンは、比較的安全に使用できることを確かめるため、我々は標準テストとベンチマークを通して確認しています。標準テストは以前に見つかった全てのバグをチェックするように拡張されるため、テストスイートはより良く保持されます。

全てのリリースは少なくても次のテストがされていることに注意してください:

内部テストスイート
     これは顧客のための製品システムの一部です。多くのテーブルと何百というメガバイトのデータを持っています。

MySQL ベンチマークスイート
     これは一般的な範囲のクエリを実行します。これは、最適化の最新バッチが実際にコードをより速く作れるかどうかを確認するテストでもあります。 See Benchmarks。

crash-me テスト
     これは、データベースがサポートしている機能と、その許容量と制限を決定しようとします。See Benchmarks。

他のテストは我々の内部製品環境で最新の MySQL バージョンを我々が少なくとも1つのマシンで使用することです。我々は動作のため 100ギガバイト以上のデータを持ちます。

アップデートがリリースされる方法と時
==================

MySQL は TcX でかなり速く進化していて、我々はこれを他の MySQL ユーザに共有してもらいたいです。我々は、他の人が必要としていると思われるとても便利な機能を持った時に、リリースの作成を試みます。

我々は、実装が簡単な機能を要求するユーザの手助けも試みます。我々は、我々のライセンスユーザが求めるものにも注目し、特に我々の拡張 email サポート顧客が求めるものに注目して、彼らの手助けを試みます。

新しいリリースをダウンロードする必要はありません。News 節は、新しいリリースが、あなたが本当に求める何かを持っているかどうかをあなたに教えます。 See News。

我々は MySQL の更新時は次のポリシーにしたがって行います：

  * それぞれのマイナーアップデートで、バージョン文字列中の最後の数値が増加します。主要な新機能や前のバージョンとのマイナーな非互換があった時には、バージョン文字列中の2番目の数値が増加します。ファイル形式が変更した時、最初の数値が増加します。

  * 安定にテストされたリリースは年に約 1-2 回現れます。しかし小さなバグが見つかった場合は、バグフィックスだけのリリースがリリースされます。

  * 作業中のリリースは約 1-8 週間毎に現れます。

  * いくつかのプラットフォームのためのバイナリ配布は我々によってメジャーリリースから作られます。他の人が他のシステムのためにバイナリ配布を作りますが、おそらく頻繁ではありません。

  * 通常、小さなバグを見つけて修正するとすぐに、有効なパッチを作ります。

  * 危険ではないけれども困らされるバグには、我々に知らせて頂ければ有効なパッチを作成します。その他の場合、大きなパッチの中にそれらの多くを結合します。

  * 偶然、致命的なバグがリリース中にある場合、我々は新しいリリースを可能な限りすぐに作ります。他の会社もそうしてもらいたいです。:)

現在の安定リリースは 3.22 です; 我々はすでに 3.23 の開発に移行しています。しかし、安定バージョンでもバグはまだ修正されます。我々は、バグ修正と``行なわなければいけない''ことを無視するような、完全な凍結を考えていません。``幾分かの凍結''とは、``ほとんど確実に既に動作しているものに影響を与えない''小さなことを追加するかもしれないということを意味します。

インストールレイアウト
===========

この節では、バイナリとソース配布のインストールで生成されるディレクトリのデフォルトのレイアウトを説明します。

バイナリ配布はアンパックすることによりインストールされ、インストール場所はあなたが選択した場所(通常 /usr/local/mysql)の中の次のディレクトリを選択し生成します:

ディレクトリ   ディレクトリの内容
bin           クライアントプログラム, mysqld サーバ
data          ログファイル, データベース
include       インクルード(ヘッダ)ファイル
lib           ライブラリ
scripts       mysql_install_db
share/mysql   エラーメッセージファイル
sql-bench     ベンチマーク

ソース配布は configure しコンパイルした後にインストールされます。デフォルトではインストールステップは /usr/local 配下のファイルを次のサブディレクトリにインストールします:

ディレクトリ   ディレクトリの内容
bin           クライアントプログラムとスクリプト
include/mysql    インクルードファイル
info          Info 形式のドキュメント
lib/mysql     ライブラリ
libexec       mysqld サーバ
share/mysql   エラーメッセージファイル
sql-bench     ベンチマークと crash-me テスト
var           データベースとログファイル

ソースインストールのレイアウトはバイナリインストールと次の点が異なります:

  * mysqld サーバは /bin ではなく libexec ディレクトリにインストールされます。

  * データディレクトリは data ではなく var です。

  * mysql_install_db は /usr/local/mysql/scripts ではなく /usr/local/bin ディレクトリにインストールされます。

  * ヘッダーファイルのディレクトリは include/mysql で、ライブラリのディレクトリは lib/mysql です。 include や lib ではありません。

MySQL バイナリ配布のインストール
===================

次にさらに詳細な説明を行ないます:

MySQL バイナリ配布をインストールするには、次のツールが必要です:

  * GNU gunzip。配布の伸長のため。

  * 適正な tar。配布の展開のため。GNU tar は動くことが知られています。

Linux では、代わりのインストール方法として RPM (RedHat Package Manager) を使用することができます。 See Linux-RPM.

問題が起きたときは、mysql@lists.mysql.com に質問を投稿する時に mysqlbug を常に使用してください。問題がバグでないとしても、mysqlbug はあなたの問題を解決する助けになるであろうシステム情報を収集します。mysqlbug を使用しないと、あなたの問題の解決を得る可能性が小さくなります！ mysqlbug は、配布のアンパック後に bin ディレクトリ内に見つけられます。See Bug reports.

MySQL バイナリ配布をインストールし、使用するために行なわなければならない基本的なコマンド:

     shell> gunzip < mysql-VERSION-OS.tar.gz | tar xvf -
     shell> ln -s mysql-VERSION-OS mysql
     shell> cd mysql
     shell> scripts/mysql_install_db
     shell> bin/safe_mysqld &

ここでさらに詳細な説明を続けます:

バイナリ配布のインストールには、次のステップに従い、それから インストール後のセットアップとテストのために Post-installation に進んでください。

 1. 配下に配布をアンパックしたいディレクトリを選んで、そこに移ってください。以下の例では、/usr/local 配下に配布をアンパックし、MySQL をインストールするディレクトリ /usr/local/mysql を生成します。(したがって、以下の指示は /usr/local にファイルを生成するパーミッションを持っているとみなします。ディレクトリがプロテクトされている場合は、 root でインストールを行なう必要があります。)

 2. 配布ファイル Getting MySQL. にリストされたサイトの一つから得てください。

     MySQL バイナリ配布は圧縮された tar アーカイブとして提供され、mysql-VERSION-OS.tar.gz のような名前を持ちます。ここで VERSION は数値(例えば、3.21.15)で、OS は配布が意図しているオペレーティングシステムの種類を表します(例えば pc-linux-gnu-i586)。

 3. 配布をアンパックし、インストールディレクトリを生成してください:

          shell> gunzip < mysql-VERSION-OS.tar.gz | tar xvf -
          shell> ln -s mysql-VERSION-OS mysql

     最初のコマンドは mysql-VERSION-OS という名前のディレクトリを生成します。二番目のコマンドはそのディレクトリにシンボリックリンクを作成します。これはインストールディレクトリを /usr/local/mysql として、より簡単に参照させるためです。

 4. インストールディレクトリに移ってください:

          shell> cd mysql

     いくつかのファイルとサブディレクトリが mysql ディレクトリ中に見つけられます。インストール目的の最も重要なものは bin と scripts サブディレクトリです。

     bin
          このディレクトリはクライアントプログラムとサーバを含んでいます。シェルが MySQL プログラムを正しく見つけられるように、このディレクトリのフルパス名をあなたの PATH 環境変数に追加すべきです。See Environment variables.

     scripts
          このディレクトリは mysql_install_db スクリプトを含んでいます。これはサーバアクセスパーミッションを初期化するために使用されます。

 5. mysqlaccess を使用し、かつ MySQL 配布を非標準の場所に持ちたい場合は、mysqlaccess が mysql クライアントを見つけようとする場所を変更する必要があります。bin/mysqlaccess スクリプトの 18 行目付近を編集してください。次のような行を探してください:

          $MYSQL     = '/usr/local/bin/mysql';    # path to mysql executable

     パスを mysql が実際にシステム上におかれている場所を示すように変更してください。これを行なわないと、mysqlaccess 実行時に broken pipe エラーになるでしょう。

 6. MySQL 許可テーブルを作成します (これは初めて MySQL をインストールするときだけ行います):

          shell> scripts/mysql_install_db

     3.22.10以前のバージョンの MySQL は、mysql_install_db. 実行時に MySQL を起動していましたが、もはやこれは起動しなくなりました

 7. Perl DBI/DBD インタフェースのサポートをインストールしたい場合、Perl support を見てください。

 8. MySQL をマシン起動時に自動的に開始したい場合、 support-files/mysql.server をシステムのスタートアップファイルがある場所にコピーしてください。さらなる情報は support-files/mysql.server スクリプト自身の中と、Automatic start に見つけられます。

全てがアンパックされてインストールされた後、配布の初期化とテストを行なうべきです。

MySQL サーバーは以下のコマンドで開始できます：

     shell> bin/safe_mysqld &

See Post-installation.

Linux RPM notes
---------------

（訳注：もし RedHat 以外の Linux を使用しており、.rpm を、自分が使用しているパッケージ管理システムの管理下におきたい場合、alien : http://kitenet.net/programs/alien/ というツールを使用します。これは RPM(Debian, Slackware) を自分が使用しているパッケージの形式に変換してくれます。）

RPM を使用して MySQL をインストールすることを推奨します。 MySQL RPMS は RedHat 5.2 で作成していますが、他の rpm と glibc をサポートしている Linux でも動作するでしょう。

RPM file での問題, 例えば Sorry, the host 'xxxx' could not be looked up は、see Binary notes-Linux.

以下が使用するであろう RPM files です:

  * MySQL-VERSION.i386.rpm

     MySQL サーバー。ただ単に他のマシン上で走っている MySQL サーバーに接続するだけなら、これは不要でしょう。

  * MySQL-client-VERSION.i386.rpm

     MySQL クライアント標準プログラム。このパッケージはほとんどの場合インストールすることになるでしょう。

  * MySQL-bench-VERSION.i386.rpm

     ベンチマーク。perl msql-mysql-modules RPM が必要。

  * MySQL-devel-VERSION.i386.rpm

     他の MySQL クライアント(perlモジュールのような)をコンパイルするのに必要なライブラリーとインクルードファイルを含みます。

  * MySQL-VERSION.src.rpm

     上記全てのソース。これは他のアーキテクチャ用に RPM を作成する場合にのみ必要でしょう。 (例えば Alpha or SPARC).

RPM パッケージに含まれるファイルをみるには:

     shell> rpm -qpl MySQL-VERSION.i386.rpm

インストールの最小の方法：

     shell> rpm -i MySQL-VERSION.i386.rpm MySQL-client-VERSION.i386.rpm

クライアントパッケージだけをインストール：

     shell> rpm -i MySQL-client-VERSION.i386.rpm

RPM はデータを /var/lib/mysql に保存します。 RPM は起動時にサーバーを立ちあげるように、/etc/rc.d/ に登録します。 (This means that if you have performed a previous installation, you may want to make a copy of your previously-installed MySQL startup file if you made any changes to it, so you don't lose your changes.)

After installing the RPM file(s), the mysqld daemon should be running and you should now be able to start using MySQL. See Post-installation.

If something goes wrong, can find more information in the binary installation chapter. See Installing binary.

クライアントプログラムのビルド
---------------

自分で書いたか、第三者が作成した MySQL クライアントプログラムをコンパイルする場合、 -lmysqlclient オプションを使用してリンクされなければなりません。また -L オプションを指定して、ライブラリがどこにあるか指定する必要がある場合もあります。例えばライブラリが /usr/local/mysql/lib にインストールされるならば、リンクの時に -L/usr/local/mysql/lib -lmysqlclient と指定します。

MySQL ヘッダーファイルを使用するクライアントのために、あなたがそれらをコンパイルする時には、-I オプションを指定しなければならない事もあります。 (例えば, -I/usr/local/mysql/include)

System 特有の問題
------------

以下のセクションでは特定のシステム上に起こると認められたいくつかの問題のを示します。

Linux notes
...........

TcX のバイナリリリースは -static でリンクされており、これはあなたのシステムがどのバージョンのライブラリーを使用しているか気にする必要がありません。よって、LinuxThreads もこの場合必要ありません。 -static でリンクされたプログラムのサイズはダイナミックリンクされたプログラムより大きくなりますが、少し(3-5%)速くなります。しかし一つの問題として、このスタティックリンクされたプログラムでは、ユーザー定義関数(UDF)が使用できないことです。もし UDF を使用する(書く)場合(C, C++とかで)、自分自身で MySQL をダイナミックリンクを使用してコンパイルしなくてはなりません。

もし glibc2 ではなく libc5 のシステムを使用しているなら、このバイナリリリースではホスト名解決とgetpwnam()にいくつか問題が出ます。 (これは glibc がホスト名解決とgetwpent()にいくつかの外部ライブラリに依存しているためで、たとえ -static リンクしても解決しません). この場合、mysql_install_db 実行時に以下のエラーが出るでしょう：

     Sorry, the host 'xxxx' could not be looked up

あるいは、--user オプションで mysqld を起動しようとしたとき、以下のエラーが出る場合：

     getpwnam: No such file or directory

この問題は、以下のうちのどれかの方法で解決できます：

  * MySQL ソース配布を入手し( RPM か tar )、代わりにインストールします。

  * mysql_install_db --force を実行します; これは mysql_install_db にかかれている resolveip テストを実行しません。また許可テーブル内でホスト名が使えなくなっています；ホスト名でなく IP アドレスで登録します (localhost は除). もし --force を持っていないような古い MySQL を使用しているなら、エディターで、resolveip テストを mysql_install から削除します。

  * mysqld を --user の代わりに su で起動。

Linux-Intel binary と MySQL RPM リリースは、もっとも速くなるように調整されています。我々はもっとも早く安定したコンパイラーを常に使用しています。

HP-UX notes
...........

Some of the binary distributions of MySQL for HP-UX is distributed as an HP depot file and as a tar file.  To use the depot file you must be running at least HP-UX 10.x to have access to HP's software depot tools.

The HP version of MySQL was compiled on an HP 9000/8xx server under HP-UX 10.20, and uses MIT-pthreads. It is known to work well under this configuration. MySQL 3.22.26 and newer can also be built with HP's native thread package.

Other configurations that may work:

  * HP 9000/7xx running HP-UX 10.20+

  * HP 9000/8xx running HP-UX 10.30

The following configurations almost definitely won't work:

  * HP 9000/7xx or 8xx running HP-UX 10.x where x < 2

  * HP 9000/7xx or 8xx running HP-UX 9.x

To install the distribution, use one of the commands below, where /path/to/depot is the full path to the depot file:

  * To install everything, including the server, client and development tools:

          shell> /usr/sbin/swinstall -s /path/to/depot mysql.full

  * To install only the server:

          shell> /usr/sbin/swinstall -s /path/to/depot mysql.server

  * To install only the client package:

          shell> /usr/sbin/swinstall -s /path/to/depot mysql.client

  * To install only the development tools:

          shell> /usr/sbin/swinstall -s /path/to/depot mysql.developer

The depot places binaries and libraries in /opt/mysql and data in /var/opt/mysql. The depot also creates the appropriate entries in /sbin/init.d and /sbin/rc2.d to start the server automatically at boot time. Obviously, this entails being root to install.

To install the HP-UX tar distribution, you must have a copy of GNU tar.

MySQL ソース配布のインストール
==================

ソースから MySQL を作成しインストールするためには次のツールが必要です:

  * GNU gunzip。配布の伸張のため。

  * 適正な tar。配布の展開のため。GNU tar は動くことが知られています。

  * ANSI C++ コンパイラ。gcc >= 2.8.1, egcs >= 1.0.2, SGI C++, SunPro C++ は働くことが知られているコンパイラのいくつかです。 libg++ は gcc 使用時には必要ではありません。gcc 2.7.x は、sql/sql_base.cc のような、完全に正当な C++ ファイルのいくつかをコンパイルできないというバグがあります。gcc 2.7.x だけしかなければ、MySQL をコンパイルできるように gcc をアップグレードする必要があります。

  * 良い make プログラム。GNU make は常に推奨され、時々は必要とされます。問題があれば GNU make 3.75 以上を試すことをお勧めします。

問題が起きたときは、mysql@lists.mysql.com に質問を投稿する時に mysqlbug を常に使用してください。問題がバグでないとしても、mysqlbug はあなたの問題を解決する助けになるであろうシステム情報を収集します。mysqlbug を使用しないと、あなたの問題の解決を得る可能性が小さくなります！ mysqlbug は、配布のアンパック後に scripts ディレクトリ内に見つけられます。See Bug reports。

素早いインストールの概要
------------

MySQL をソースからインストールするために行なわなければならない基本的なコマンド(from an unpacked tar file):

     shell> ./configure
     shell> make
     shell> make install
     shell> scripts/mysql_install_db
     shell> /usr/local/mysql/bin/safe_mysqld &

RPM ソースから開始する場合は：

     shell> rpm --rebuild MySQL-VERSION.src.rpm

これはインストールできるRPMバイナリを作成します

もし DBI と Msql-Mysql-modules Perl モジュールをインストールするなら、 bin/mysql_setpermission スクリプトが使用する新しいユーザーを追加することができます。

次にさらに詳細な説明を行ないます:

ソース配布のインストールには、次のステップに従い、それから インストール後の初期化とテストのために see Post-installation に進んでください。

 1. 配布をアンパックしたいディレクトリを選んで、そこに移ってください。

 2. 配布ファイルを Getting MySQL. にリストされたサイトの一つから得てください。

     MySQL ソース配布は圧縮された tar アーカイブとして提供され、mysql-VERSION.tar.gz のような名前を持ちます。ここで VERSION は mysql_version のような番号です。

 3. カレントディレクトリに配布をアンパックしてください:

          shell> gunzip < mysql-VERSION.tar.gz | tar xvf -

     このコマンドは mysql-VERSION という名前のディレクトリを作成します。

 4. アンパックされた配布のトップレベルディレクトリに移ってください:

          shell> cd mysql-VERSION

 5. リリースを configure し、全てをコンパイルしてください:

          shell> ./configure --prefix=/usr/local/mysql
          shell> make

     configure の実行時、いくつかのオプションを指定できます。オプションの一覧は ./configure --help を実行してください。configure options, さらに有用なオプションのいくつかについて議論しています。

     configure が失敗して、援助を得るために mysql@lists.mysql.com にメールを送ろうとする場合、config.log から問題の解決の手助けにできると考えられる行を含めてください。configure が異常終了する場合、 configure からの出力の最後の数行も含めてください。バグレポートは mysqlbug スクリプトを使用して投稿してください。See Bug reports。

     コンパイルが失敗する場合、いくらかのよくある問題での手助けのため、 Compilation problems を参照してください。

 6. 全てをインストールしてください:

          shell> make install

     このコマンドは root として実行する必要があります。

 7. MySQL 権限テーブルを生成してください(以前に MySQL をインストールしていない時にだけ必要です):

          shell> scripts/mysql_install_db

     注意: 3.22.10 より古い MySQL バージョンでは、 mysql_install_db 実行時に MySQL サーバが開始されましたが、これはもはや真ではありません！

 8. Perl DBI/DBD インタフェースのサポートをインストールしたい場合、Perl support を見てください。

 9. MySQL をマシン起動時に自動的に開始したい場合、 support-files/mysql.server をシステムのスタートアップファイルがある場所にコピーしてください。さらなる情報は support-files/mysql.server スクリプト自身の中と、Automatic start に見つけられます。

全てがインストールされた後、配布の初期化とテストを行なうべきです。

MySQL サーバーを以下のコマンドで開始できます。 BINDIR は safe_mysqld がインストールされているディレクトリ (/usr/local/bin by default) です:

     shell> BINDIR/safe_mysqld &

コマンドがすぐに mysqld daemon ended エラーで失敗する場合、 mysql-data-directory/'hostname'.err ファイルになんらかの情報を見つけることができます。 よくあることとして、すでに他の mysqld が走っている場合などがあります。 See Multiple servers.

See Post-installation。

パッチの適用
------

時々、パッチは、メーリング・リストに流されたり、または MySQL FTPサイトの パッチエリア (ftp://www.mysql.com/pub/mysql/Downloads/Patches) に置かれます。

メーリング・リストからのパッチを適用するには、パッチが載っているメッセージをファイルに保存して、あなたの MySQL ソース・ツリーの一番上のディレクトリーに移動し、以下のようにコマンドを実行します：

     shell> patch -p1 < patch-file-name
     shell> rm config.cache
     shell> make clean

FTPサイトに置かれるパッチは、プレーンテキストファイルとして、あるいは gzip で圧縮されたファイルとして頒布されます。プレーンテキストのパッチの場合は、上に示したメーリングリストのパッチと同様に適用します。 圧縮されたパッチを適用するには、 MySQL ソース・ツリーの一番上のディレクトリーに移動し、以下のようにコマンドを実行します：

     shell> gunzip  < patch-file-name.gz | patch -p1
     shell> rm config.cache
     shell> make clean

それから通常のソースインストールの指示を ./configure ステップから始めます。make install ステップ実行後、あなたの MySQL サーバを再起動します。

make install を実行する前に、現在走っているサーバーを止める必要があるかもしれません。 ( mysqladmin shutdown で止めます ) いくつかのシステムでは、現在実行しているものを止めない限り、新しいバージョンをインストールできないようになっています。

典型的な configure オプション
--------------------

configure スクリプトは MySQL 配布をどのようにコンフィグするかを制御するための多くの処理を提供します。典型的には、 configure コマンドラインにオプションを使用してこれを行ないます。いくつかの環境変数を使用しても configure に影響を与えることができます。 See Environment variables. configure がサポートするオプションの一覧は、次のコマンドを実行してください:

     shell> ./configure --help

良く使われる configure オプションのいくつか以下に説明します:

  * MySQL クライアントライブラリとクライアントプログラムだけをコンパイルするには、--without-server オプションを使用してください:

          shell> ./configure --without-server

     C++ コンパイラがなければ、mysql はコンパイルできません(これは C++ を要求するクライアントプログラムの一つです)。この場合、configure から C++ コンパイラをテストするコードを削除でます。それから ./configure を --without-server オプションつきで実行してください。コンパイルステップは mysql の作成を試みますが、 mysql.cc についての警告は無視できます。(make が止まる場合、エラーが発生しても残りの作成を継続するように make -k を試してください。)

  * ログファイルとデータベースディレクトリを /usr/local/var 配下におきたくない場合は、次の一つのような configure コマンドを使用してください:

          shell> ./configure --prefix=/usr/local/mysql
          shell> ./configure --prefix=/usr/local \
                     --localstatedir=/usr/local/mysql/data

     最初のコマンドはインストールプレフィックスを変更し、デフォルトの /usr/local ではなく /usr/local/mysql 配下にインストールします。次のコマンドはデフォルトのインストールプレフィックスを保存しますが、データベースディレクトリのデフォルト位置(通常は /usr/local/var)を上書きし、/usr/local/mysql/data に変更します。

  * UNIX を使用していて、ソケットの位置をデフォルト位置(通常は /tmp または /var/run)でなく他のどこかにしたい場合は、configure コマンドを次のように使用します:

          shell> ./configure --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock

     ファイル名は絶対パス名でないといけません。

  * 静的リンクされたプログラムをコンパイルしたい場合(例えば、バイナリ配布を作成するため、もっと速くするため、いくつかの RedHat 配布での問題を回避するため)は、次のように configure を実行します:

          shell> ./configure --with-client-ldflags=-all-static \
                     --with-mysqld-ldflags=-all-static

  * gcc を使用していて、libg++ や libstdc++ がインストールされていない場合、configure に gcc を C++ コンパイラとして使用することを伝えてください:

          shell> CC=gcc CXX=gcc ./configure

     gcc を C++ コンパイラとして使用する時、libg++ または libstdc++ のリンクは試みません。

     コンパイラやリンカが共有ライブラリ libmysqlclient.so.# を生成できないというエラーになる場合、--disable-shared オプションを configure に与えることで、この問題を回避できます。この場合、 configure は共有ライブラリ libmysqlclient.so.# を作成しません。

  * 非 NULL 項目(すなわち、NULL が許されていない項目)に DEFAULT 項目値を使用しないように MySQL をコンフィグできます。これは、非 NULL 値を要求する全ての項目に値を明示的に指定しなければ、INSERT ステートメントはエラーを生成します。デフォルト値の使用を抑えるには、次のように configure を実行します:

          shell> CXXFLAGS=-DDONT_USE_DEFAULT_FIELDS ./configure

  * デフォルトでは、MySQL は ISO-8859-1 (Latin1) 文字セットを使用します。デフォルトセットを変更するには、--with-charset オプションを使用します:

          shell> ./configure --with-charset=CHARSET

     CHARSET は次の一つです: big5, cp1251, cp1257, czech, danish,dec8, dos, euc_kr, gb2312, gbk, german1, hebrew, hp8, hungarian, koi8_ru, koi8_ukr, latin1, latin2, sjis, swe7, tis620, ujis, usa7, win1251 or win1251ukr. See Character sets.

     注意: 文字セットを変更したい場合は、コンフィグレーション間で make distclean を行なう必要があります！ (3.23.14 以前の場合)

     サーバとクライアント間で文字を変換したい場合は、 SET OPTION CHARACTER SET コマンドを調べるべきです。 See SET OPTION.

     警告: テーブルを生成した後に文字セットを変更する場合、 myisamchk -r -q を全てのテーブルに実行する必要があります。そうでないと、インデックスは正しくソートされません。(これは、MySQL のインストール時、いくつかのテーブルの生成時、異なる文字セットを使用して MySQL の再コンフィグ時、そして再インストール時に発生します。)

  * デバッグコードつきで MySQL をコンフィグするには、 --with-debug オプションを使用します:

          shell> ./configure --with-debug

     これにより、いくつかのエラーを見つけられる安全なメモリ割り当てが含まれ、何が発生しているかについての出力を提供します。 See Debugging server.

  * あなたのクライアントプログラムがスレッドを使用している場合、 MySQL クライアントライブラリを --with-thread-safe-client でスレッド安全用にコンパイルする必要があります; これは、デフォルトではいくつかのスレッド安全でない関数で、ライブラリがスレッド安全関数コールを使用するようになります。これを行なうことで小さなパフォーマンスペナルティがありますが、通常このオプションの使用は完全に安全です。

  * 固有のシステムに関係するオプションについては、この章より後のシステム固有の節で見つけることができます。See Source install system issues。

コンパイルの問題か？
==========

Solaris 上で gcc を使用した場合、一切警告無く全ての MySQL プログラムがきれいに作れます。他のシステムではインクルードファイルの違いから警告が出るかもしれません。 MIT-pthreads を使用した際の警告は MIT-pthreads を参照してください。他の問題は、以下をチェックしてください。

多くの問題の解決のために、再 configure が必要です。あなたが再構成する必要があるならば、以下に気をつけてください：

  * もし configure を一度実行した後に実行するならば、 configure は前に作った情報を利用します。この情報は config.cache に保存されます。 configure は起動時にこのファイルを探し、もし存在するならば、その中の情報が正しい物として読み込みます。これはあなたが再コンフィグするならば無効になります。

  * configure を実行するごとに、 make を実行してコンパイルしなければなりません。しかし、最初に、前のビルドでできたオブジェクトを、消しておいてください。なぜなら、違うコンフィグオプションにより生成されたからです。

古いコンフィグやオブジェクトファイルの使用を防ぐため、 configure 前に以下のコマンドを実行してください：

     shell> rm config.cache
     shell> make clean

こうするかわりに、make distclean としても構いません。

以下に、 MySQL をコンパイルする際に起こりやすい問題をあげておきます：

  * sql_yacc.cc コンパイル時に、以下のようなエラーが出た場合、メモリー、スワップが足りません：

          Internal compiler error: program cc1plus got fatal signal 11
            or
          Out of virtual memory
            or
          Virtual memory exhausted

     この問題は、gcc がインライン展開で sql_yacc.cc をコンパイルするのに、とても多くのメモリーを必要とするからです。この場合、 configure を --with-low-memory オプション指定で実行します：

          shell> ./configure --with-low-memory

     このオプションは、 gcc を使用しているなら -fno-inline オプションをコマンドラインに加え、gcc 以外ならば -O0 を加えます。多くのメモリーとスワップを持っていない限りは、--with-low-memory オプションを使用すべきです。この問題はけっこうなハードウェア構成でも起こることが知られています。通常、 --with-low-memory オプションでこの問題は解決できます。

  * 標準では、configure は c++ という名前でコンパイラーを使用し、 GNU c++ は -lg++ を使ってリンクします。もし gcc を使用しているならば、コンフィグ時に以下のような問題が出るかもしれません：

          configure: error: installation or configuration problem:
          C++ compiler cannot create executables.

     この問題は、g++, libg++ あるいは libstdc++ に関連したものです。

     原因の一つとして考えられることは、 g++ を持っていないか、あるいは、 g++ はあっても libg++ か libstdc++ がないという事です。 config.log ファイルは c++ コンパイラが動作しなかった理由を記録しています！この問題を解決するに当たり、あなたが持っている C++ コンパイラーの代わりに gcc を使用しても構いません。CXX 環境変数に "gcc -O3" としてみてください。例えば：

          shell> CXX="gcc -O3" ./configure

     これは gcc が g++ と同様に C++ ソースをコンパイルするので動きますが、 libg++ か libstdc++ が標準ではリンクされません。

     他の解決方法は、もちろん、g++, libg++, libstdc++ をインストールすることです。

  * もし以下のエラーのどれかが起きた場合、 GNU make のバージョンを上げてください：

          making all in mit-pthreads
          make: Fatal error in reader: Makefile, line 18:
          Badly formed macro assignment
            or
          make: file `Makefile' line 18: Must be a separator (:
            or
          pthread.h: No such file or directory

     Solaris と FreeBSD の make プログラムには問題があることが知られています。

     GNU make version 3.75 は動作確認されています。

  * もし C,C++ のためにフラグを与えたい場合、CFLAGS と CXXFLAGS 環境変数にフラグを追加してください。同様に、 CC と CXX にコンパイラー名を与えることもできます。例えば：

          shell> CC=gcc
          shell> CFLAGS=-O6
          shell> CXX=gcc
          shell> CXXFLAGS=-O6
          shell> export CC CFLAGS CXX CXXFLAGS

     TcX binaries にはフラグの定義がリストされています。色々なシステム上で役に立つと思います。

  * 以下のようなエラーの場合、gcc コンパイラーをアップグレードしてください：

          client/libmysql.c:273: parse error before `__attribute__'

     gcc 2.8.1 は動作することが確認されていますが、 gcc 2.95.2 以上をお勧めします。

  * mysqld コンパイル時に以下のようなエラーが出た場合、 configure がaccept(), getsockname(), getpeername() の最後の引数を正しく検出していません：

          cxx: Error: mysqld.cc, line 645: In this statement, the referenced
               type of the pointer value "&length" is "unsigned long", which
               is not compatible with "int".
          new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);

     これを修正するには、config.h ファイル(configure により作られる) を修正します。いかのように：

          /* Define as the base type of the last arg to accept */
          #define SOCKET_SIZE_TYPE XXX

     XXX を size_t か int (あなたのオペレーティングシステムが依存している型)に変えます。 (configure すると毎回 config.h は作り直されるので、この修正は configure する度に行わなければならないことに注意)

  * sql_yacc.cc ファイルは sql_yacc.yy から生成されます。通常、 MySQL が既に生成されたコピーとともにあるので、 sql_yacc.cc ファイルを自分自身で作成することはありません。しかし、以下のエラーの場合、再作成する必要があります：

          "sql_yacc.yy", line xxx fatal: default action causes potential...

     これはあなたの yacc のバージョンが不十分であることを示しています。 bison (the GNU version of yacc) を代わりにインストールして使用する必要があります。

  * もし mysqld か MySQL クライアントをデバッグしたいなら、 configure を --with-debug オプション付きで実行します。そしてコンパイルし、新しいクライアントライブラリーでクライアントをリンクします。 See Debugging client.

MIT-pthreads に関して
=================

このセクションではMIT-pthreadsを使っているさいに起こる問題についていくつか述べています。

Linux では、MIT-pthreads を使用してはならず、 LinuxThreads をインストールするべきです！ See Linux.

もしあなたのシステムが本来のスレッドのサポートを提供しなければ、あなたは、 MIT-pthreadsパッケージを使って、MySQL を構築する必要があります。これにはほとんどのFreeBSDシステム、SunOS4.x,Solaris 2.4とそれ以前、ほかいくつかが含まれます。 See Which OS.

  * ほとんどのシステム上では --with-mit-threads オプションで configure 実行することによって、 MIT-pthreadsが使われることを強制することができます。

          shell> ./configure --with-mit-threads

     MIT-pthreadsを使う時、非ソースディレクトリで構築することはサポートされていません。なぜなら、私たちはこのコードへ私たちの変更を最小にしたいからです。

  * MIT-pthreadsは、Unixソケット実装に使われている AF_UNIX プロトコルをサポートしません。これは、もしあなたが使っている MIT-pthreads をコンパイルすれば、全ての接続は、 TCP/IP を使う(つまり少し遅くなる)ことを意味します。もし、あなたが MySQL を構築したあとで、ローカルのサーバーに接続できないならば、それはあなたのクライアントがデフォルトで Unix ソケットを使って localhost へ接続しようとしているのかもしれません。明示的にローカルホスト名を指定するために、ホスト名指定のオプション (-h か --host) で mysql を使用して、TCP/IP 接続を試してみてください。

  * MIT-pthreads が使われているかどうかチェックはサーバコードを configure するときにだけ行われます。もし、あなたが --without-server を使ってクライアントコードのみをビルドすることを設定したならば、クライアントは MIT-othreads が使われているかいないか、 Unixソケット接続がデフォルトで使われているのかわかりません。なぜなら Unix ソケットは MIT-pthreads 下では動作しないからです。また、あなたはそのようなインスタンスでは -h または  --host を使う必要があります。

  * MySQL が MIT-pthreads を使ってコンパイルされると、パフォーマンス上の問題のためシステムロックはデフォルトでディスエーブルとされます。  --use-locking オプションを指定してサーバーに伝えることで、システムロックは使えるようになります。

  * ときどき(少なくともSolarisでは) pthread の bind() コマンドは何のエラーメッセージなしにソケットへの bind に失敗することがあります。これは結果としてサーバーへの接続失敗となります。たとえば、

          shell> mysqladmin version
          mysqladmin: connect to server at '' failed;
          error: 'Can't connect to mysql server on localhost (146)'

     これを解決するために mysqld サーバーを終了して、再起動してください。これは私たちがサーバーダウンを強制して、すぐにリスタートさせようとしたときだけ起こりました。

  * MIT-pthreads を使っていると、sleep() システムコールは SIGINT (break) では割り込みできません。 これは　mysqladmin --sleep を走らせているときにだけ起こることがわかっています。割り込みが発生してプロセスが停止する前に、あなたは終了させるための sleep() コールを待たなくてはなりません。

  * リンクしているとき(少なくともSolarisでは)、あなたはこのような warning メッセージを受け取るでしょう。これらは無視してかまいません。

          ld: warning: symbol `_iob' has differing sizes:
              (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
          file /usr/lib/libc.so value=0x140);
              /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
          ld: warning: symbol `__iob' has differing sizes:
              (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
          file /usr/lib/libc.so value=0x140);
              /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken

  * 他のいくつかの warnings もまた無視してかまいません。

          implicit declaration of function `int strtoll(...)'
          implicit declaration of function `int strtoul(...)'

  * 私たちはまだ MIT-pthread とともに動く readline を手に入れていません(これは必要ではないのですが、おそらく誰かには興味があるでしょう)。

Perl のインストールについて
================

Unix への Perl のインストール
--------------------

MySQL は Perl DBI/DBD インターフェースをサポートします。See Perl. DBI/DBD インターフェースの Perl のクライアントは、Perl 5.004 以上が必要です。これより古いバージョンの Perl ですと動きません。

MySQL Perl は、 MySQL クライアント・プログラミング・サポートが既にインストールされていることが条件です。もしあなたが RPM ファイルから MySQL をインストールしたのなら、クライアント・プログラムは、クライアント RPM にあります。 が、クライアント・プログラミング・サポートは、開発者向け RPM にあります。開発者向け RPM をインストールしたことを確かめて下さい。

これらは 3.22.8 から MySQL 配布とは分けられて配布されています。もし Perl モジュールをインストールしたいなら、http://www.mysql.com/Contrib を確認してください。ここにおかれています。

Perl の配布物は tar でアーカイブされ、圧縮されています。 MODULE-VERSION.tar.gz という命名規則で配布されています。 (MODULE はモジュール名、VERSION はバージョン番号)

Data-Dumper, DBI, Msql-Mysql-modules が必要です。これを取ってきたら、以下のようにしてインストールします。 Data-Dumper モジュールを例にしますが、他も同様にできます。

 1. 配布物をカレントディレクトリに展開：

          shell> gunzip < Data-Dumper-VERSION.tar.gz | tar xvf -

     これは Data-Dumper-VERSION というディレクトリを作ります。

 2. 展開したディレクトリに入ります：

          shell> cd Data-Dumper-VERSION

 3. コンパイル、インストール：

          shell> perl Makefile.PL
          shell> make
          shell> make test
          shell> make install

モジュールが動作するかを確かめるので make test コマンドは重要です。インターフェースコードのテストのために Msql-Mysql-modules のインストール中にこれらのコマンドを実行する際には、 MySQL サーバーが稼働していなければなりません。でなければ、テストは失敗します。

新しいリリースの MySQL をインストールした場合に常に Msql-Mysql-modules を再構築、再インストールすることはいい考えです。すべての DBI スクリプトが MySQL のアップグレード後にコアダンプする兆候に気づいた場合は、特にそうしてください。

もし Perl module を正しくシステムディレクトリーやローカルのPerlディレクトリにインストールできない場合、以下の文献が役立ちます：

     http://www.iserver.com/support/contrib/perl5/modules.html

このページの以下を参照してください： Installing New Modules that Require Locally Installed Modules.

Win32 への ActiveState Perl のインストール
---------------------------------

Win32 上に、 ActiveState Perl に MySQL DBD モジュールをインストールするには、以下のようにしなくてはなりません：

  * Open a DOS shell.

  * もし必要なら、HTTP_proxy 変数をセット。 例えば set HTTP_proxy=my.proxy.com:3128

  * PPM プログラムの起動： C:\perl\bin\ppm.pl

  * DBI のインストール(もし入っていなければ)： install DBI

  * この成功後に、 ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd  をインストール

The above should work at least with ActiveState Perl 5.6.

もし上記のように出来なければ、代わりに MyODBC ドライバーを入れ、 MySQL サーバーに ODBC 経由で接続しなくてはなりません。

     use DBI;
     $dbh= DBI->connect("DBI:ODBC:$dsn","$user","$password") ||
       die "Got error $DBI::errstr when connecting to $dsn\n";

Win32 への MySQL Perl 配布物のインストール
------------------------------

MySQL Perl 配布は DBI, DBD:MySQL , DBD:ODBC を含みます。

  * http://www.mysql.com/download.html から  Perl distribution for Win32 を取得。

  * C: で unzip します。 C:\PERL ができます。

  * あなたのパスに C:\PERL\BIN を加えます。

  * あなたのパスに C:\PERL\BIN\MSWin32-x86-thread か C:\PERL\BIN\MSWin32-x86 を加えます。

  * DOS shell で、 perl -v を実行して perl をテストします。

Perl DBI/DBD 使用時の問題
-------------------

もし Perl が ../mysql/mysql.so モジュールが見つからないとメッセージを出した場合、シェアードライブラリ libmysqlclient.so を取りこめなかったと考えられます。

以下のような方法で解決方法があります：

  * Msql-Mysql-modules のコンパイルでは、 perl Makefile.PL のかわりに perl Makefile.PL -static -config とします。

  * libmysqlclient.so を他のシェアードライブラリがあるところ(/usr/lib とか /lib)にコピーします。

  * Linux の場合、/etc/ld.so.conf ファイルに、libmysqlclient.so があるディレクトリを書き加え、ldconfig -v を実行します。

  * LD_RUN_PATH (LD_LIBRARY_PATH) 環境変数に libmysqlclient.so があるディレクトリを書き加えます。

もし DBD-mysql で以下のエラーが出た場合、 gcc (あるいは、gcc でコンパイルされた古いバイナリ) を使用していると思われます：

     /usr/bin/perl: can't resolve symbol '__moddi3'
     /usr/bin/perl: can't resolve symbol '__divdi3'

mysql.so を作成する時のリンクコマンドに -L/usr/lib/gcc-lib/... -lgcc を追加してください。 (Perlクライアントを作る際の make の出力をチェックしてください) -L オプションに指定するのは、あなたのシステム内の libgcc.a があるディレクトリです。

Perl と MySQL が gcc を使用して作られていない場合も原因としてあります。この場合、両方を gcc でコンパイルすることにより、ミスマッチを避けることができます。

ダイナミックリンクをサポートしていないシステム(like SCO)でPerlモジュールを使用したい場合、 DBI と DBD-mysql を含むスタティックのPerlを作る事もできます。これは、まず、 DBI コードがリンクされているPerlを作って現在のPerlの上にインストールします。そして、 DBD コードをさらにリンクさせるPerlを作り、それをインストールします。

SCOでは、環境変数を以下のようにしなくてはなりません：

     shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
     or
     shell> LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
     shell> LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
     shell> MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:/usr/skunk/man:

最初、DBI をスタティックリンクしたPerlを作るために、 perl/DBI ディレクトリで以下のように実行します：

     shell> perl Makefile.PL -static -config
     shell> make
     shell> make install
     shell> make perl

この後、あなたは新しいPerlをインストールしなければなりません。 make perl をすると、インストール操作に実行するに必要な make コマンドを表示します。 SCOでは、make -f Makefile.aperl inst_perl MAP_TARGET=perl とします。

次に、DBD::mysql をスタティックリンクしたPerlを作るために、 perl/Mysql-modules ディレクトリで以下のように実行します：

     shell> perl Makefile.PL -static -config
     shell> make
     shell> make install
     shell> make perl

これも新しいPerlをインストールしなくてはなりません。 make perl の出力は使用するコマンドを示します。

System-specific issue
=====================

以下のセクションは、ソース配布から MySQL をインストールする際に特定のシステム上に起こると認められた問題のいくつかを示します.

Solaris notes
-------------

Solaris では MySQL ソースを展開するときトラブルが出るでしょう！ Solaris の tar は長い名前を扱えず、 MySQL を展開する場合、以下のようなエラーになります：

     x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,informix,ms-sql,mysql,oracle,solid,sybase, 0 bytes, 0 tape blocks
     tar: directory checksum error

この場合、GNU tar (gtar) を展開に使用してください。コンパイルずみのものが以下にあります： http://www.mysql.com/Downloads/.

Sun ネイティブスレッドは Solaris 2.5 以上で動きます。 2.4 以下の場合、MySQL は時動的に MIT-pthreads を使用します see MIT-pthreads.

もし、configure 時に、以下のエラーが出たなら：

     checking for restartable system calls... configure: error can not run test
     programs while cross compiling

これはコンパイラーのインストールでなにかを間違っています! この場合、あなたは、より新しいバージョンへコンパイラーをアップグレードすべきです。以下の行を config.cache ファイルに追加することによって、この問題を解決してもかまいません：

     ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'}

もしあなたが SPARC の Solaris を使用しているなら、 gcc 2.95.2 を推奨します。これは ttp://gcc.gnu.org/. で見つけれます。 egs 1.1.1 と gcc 2.8.1 は SPARC 上では完全に動作しないことに注意！

gcc 2.95.2 を使用した、推奨する configure は:

     shell> CC=gcc CFLAGS="-O6" \
            CXX=gcc CXXFLAGS="-O6 -felide-constructors -fno-exceptions -fno-rtti" \
            ./configure --prefix=/usr/local/mysql --with-low-memory

もし Sun Workshop 4.2 compiler を使用するなら、configure を以下のようにします：

CC=cc CFLAGS="-xstrconst -Xa -xO4 -native -mt" CXX=CC CXXFLAGS="-xO4 -native -noex -mt" ./configure --prefix=/usr/local/mysql

     shell> CC=cc CFLAGS="-Xa -fast -xO4 -native -xstrconst -mt" \
            CXX=CC CXXFLAGS="-noex -XO4 -mt" \
            ./configure

configure スクリプトの次の行を：

     #if !defined(__STDC__) || __STDC__ != 1

以下に変えます:

     #if !defined(__STDC__)

もし -Xc オプションで __STDC__ を有効にした場合、 Sun compiler は Solaris の  pthread.h ヘッダーファイルを使用してコンパイルすることができません。これはサンのバグです(インクルードファイルかコンパイラーのバグ)

もし mysqld を起動時に以下のエラーが出た場合、マルチスレッドを外して(オプション -mt を指定) Sun compiler を使って MySQL をコンパイルし直してください：

     libc internal error: _rmutex_unlock: rmutex not held

-mt を CFLAGS と CXXFLAGS に加えます。

gcc で MySQL をコンパイルするときに以下のエラーが出た場合、これは gcc があなたの Solaris のバージョン用に調整されていません！

     shell> gcc -O3 -g -O2 -DDBUG_OFF  -o thr_alarm ...
     ./thr_alarm.c: In function `signal_hand':
     ./thr_alarm.c:556: too many arguments to function `sigwait'

この場合、新しい gcc でコンパイルします！少なくとも Solaris 2.5 では、ほとんどの gcc のバイナリのバージョンが古く、スレッドを使用するプログラムにはこのインクルードファイルは使えません！

Solaris は スタテックリンクのシステムライブラリーを用意していません (libpthreads and libdl)。そのため、--static オプションで MySQL をコンパイルできません。もしこれを試みた場合、以下のエラーになります：

     ld: fatal: library -ldl: not found

もし多くのプロセスが速く mysqld に接続を試みた場合、 MySQL ログに以下のようにエラーが出ます:

     Error in accept: Protocol error

サーバーを --set-variable back_log=50 オプションで起動すれば、この問題に対処できるでしょう。

もし自分の MySQL クライアントプログラムをリンクして実行時に以下のようにエラーが出た場合：

     ld.so.1: ./my: fatal: libmysqlclient.so.#: open failed: No such file or directory

これは以下のどれかで回避できます：

     以下のフラグでクライアントをリンクします(-Lpath の代わりに): -Wl,r/full-path-to-libmysqlclient.so

     libmysqclient.so を /usr/lib にコピーします

     LD_RUN_PATH 環境変数を libmysqlclient.so が存在するところにセットした後、クライアントを実行します。

--with-libwrap configure オプション使用時、libwrap.a が必要とするライブラリも含める必要があります:

     --with-libwrap="/opt/NUtcpwrapper-7.6/lib/libwrap.a -lnsl -lsocket

configure や MySQL が -lz のリンクを試み、あなたがそれをインストールしていないという問題がある場合は、２つの選択肢があります:

  * 圧縮通信プロトコルを使用できるようにしたい場合、ftp.gnu.org から zlib を入手してインストールする必要があります。

  * --with-named-z-libs=no をつけて configure を行ないます。

Solaris 2.7 notes
-----------------

通常、Solaris 2.6 のバイナリは Solaris 2.7 で使用できます。ほとんどの Solaris 2.6 の問題も Solaris 2.7 に適用できます。

Solaris 2.7 は、インクルードファイルにいくつかバグがあります。 gcc で以下のようなエラーが出た場合：

     /usr/include/widec.h:42: warning: `getwc' redefined
     /usr/include/wchar.h:326: warning: this is the location of the previous
     definition

以下のようにして回避します：

/usr/include/widec.h を .../lib/gcc-lib/os/gcc-version/include にコピー 41 行目を変更:

     変更前：

     #if     !defined(lint) && !defined(__lint)

     変更後：

     #if     !defined(lint) && !defined(__lint) && !defined(getwc)

代わりに、/usr/include/widec.h を直接変更してもかまいません。どちらの方法にしても、ファイルを修正後は、config.cache を消して configure を再実行しなくてはなりません！

make 実行時に以下のようなエラーになった場合、configure が curses.h ファイルを検出できていません (これは /usr/include/widec.h のエラーのためにおきます):

     In file included from mysql.cc:50:
     /usr/include/term.h:1060: syntax error before `,'
     /usr/include/term.h:1081: syntax error before `;'

これを解決するには、以下のうち一つを行います：

  * 前述したとおり、/usr/include/widec.h を修正し、configure を再実行します。

  * #define HAVE_TERM 行を config.h ファイルから消し、 make を再実行します。

  * CFLAGS=-DHAVE_CURSES CXXFLAGS=-DHAVE_CURSES ./configure とコンフィギャーします。

Solarix x86 notes
-----------------

gcc か egcs を Solaris x86 で使用した場合、load 時にコアダンプする場合、以下のように configure します:

     shell> CC=gcc CFLAGS="-O6 -fomit-frame-pointer" \
            CXX=gcc \
            CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" \
            ./configure --prefix=/usr/local/mysql

これは libstdc++ ライブラリーと C++ の問題を回避します。

もしこれが該当しない場合、デバッグモードでコンパイルしてデバッグのトレースファイルを書き出すようにして起動するか、 gdb を使用して起動してください。 See Debugging server.

SunOS 4 notes
-------------

SunOS 4 では MIT-pthreads が必要です。このために、 GNU make が MySQL のコンパイルに必要になります。

いくつかの SunOS 4 では dynamic libraries と libtool に問題があります。これを避けるために、以下のようにして configure します：

     shell> ./configure --disable-shared --with-mysqld-ldflags=-all-static

readline のコンパイル時、二重定義のワーニングが出ますが、これは無視して構いません。

mysqld をコンパイルする時、いくつか implicit declaration of function ワーニングがでますが、無視して構いません。

Linux notes (all Linux versions)
--------------------------------

Linux では MySQL は LinuxThreads を使用します。もし glibc2 を持たない古い Linux を使用している場合、 MySQL のコンパイルの前に、 LinuxThreads をインストールしなければなりません。 http://www.mysql.com/Downloads/Linux

注意: 2.1.1 とそれ以前の glibc バージョンは pthread_mutex_timedwait 操作中に致命的なバグがあります。これは INSERT DELAYED を行なう時に使用されます。INSERT DELAYED を使用する場合、次のパッチを glibc ライブラリに追加しなければなりません: http://www.mysql.com/Downloads/Patches/glibc-pthread_cond_timedwait.patch。 MySQL 3.23.7 と MySQL 3.22.32 はこのバグの一時的な回避を含んでいます。

1000以上の同時接続を使用する予定であれば、LinuxThreads にいくつかの変更をして、再コンパイルし、MySQL を新しい libthread.a を使用するように再リンクする必要があります。sysdeps/unix/sysv/linux/bits/local_lim.h 内の PTHREAD_THREADS_MAX を 4096 に増加し、internals.h 中の STACK_SIZE を 256 KB に減少させてください。注意: STACK_SIZE がデフォルトの 2MB である場合、MySQL は 1000 程度の接続で安定でなくなります。

glibc 2.1.3-65 かそれ以降の場合、STACK_SIZE を増やす必要はありません; mysqld の thread_stack 値を代わりに変更できます。

If you use a lot of concurrent connections, you may suffer from a 2.2 kernel "feature" that penalizes a process for forking or cloning a child in an attempt to prevent a fork bomb attack. This will cause MySQL not to scale well as you increase the number of concurrent clients. On single CPU systems, we have seen this manifested in a very slow thread creation - which means it may take a long time to connect to MySQL ( as long as 1 minute), and it may take just as long to shut it down. On multiple CPU systems, we have observed a gradual drop in query speed as the number of clients increases. In the process of trying to find a solution, we have received a kernel patch from one of our users, who claimed it made a lot of difference for his site. We have done some limited testing in which the patch greatly improved the scalabitility of MySQL. The patch is available here (http://www.mysql.com/Downloads/Patches/linux-fork.patch) - be warned, though, that we assume no reponsibility for any damage that this patch could do - use at your own risk. We have also been told by the Linux kernel developers that this problem is fixed in 2.4, although we have not yet done any testing.

もし mysqld が動かなかったり、 mysql_install_db が動かない場合、以下を読みすすめてください！ LinuxThreads か libc/glibc ライブラリーに問題のある Linux システムだけに起こります。しかし MySQL を動かせるために簡単な方法が多くあります。一番簡単な方法は、バイナリになった MySQL (not the RPM) を使用することです；このバージョンのバイナリは、あなた自身がコンパイルしたものより 10% ほど速いでしょう！ See Compile and link options.

一つ知られている問題として、バイナリ配布を libc5 の古い Linux システム (RedHat 4.x , Slackware 3.6以下, Debian 1.3 bo 以下など) で使用すると、ホスト名解決の致命的なエラーが出ます see Binary notes-Linux.

myisamchk は libc.so.5.3.12 で使用するとハングります. 最新の libc にアップグレードしてください。

LinuxThreads を使用している場合、最低３つのプロセスが走ります。これらは実スレッドで、一つは LinuxThreads マネージャーのために、一つは接続のハンドルに、もうひとつはアラームとシグナルのハンドルです。

注意: linux カーネルと linuxthread ライブラリはデフォルトでは 1024 スレッドだけ持つことができます。これはパッチを適用していないシステム上では MySQL への接続は最大 1021 だけであるということを意味します。ページ http://www.volano.com/linuxnotes.html はこの制限をどのように回避するかの情報が含まれています。

もし mysqld デーモンプロセスが ps などでみると死んでいるようであれば, 通常これは MySQL バグか、壊れたテーブルを持っています。 See Crashing.

LinuxThreads を使用していて mysqladmin shutdown が動かない場合、 LinuxThreads 0.7.1 以上にアップグレードしてください。

RedHat を使用していて, 以下のようなエラーが出た場合：

     /usr/bin/perl is needed...
     /usr/sh is needed...
     /usr/sh is needed...

この場合、 rpm のバージョンを rpm-2.4.11-1.i386.rpm と rpm-devel-2.4.11-1.i386.rpm (以上) にしなくてはいけません。

RedHat 4.2 は以下からアップグレードが入手できます。 ftp://ftp.redhat.com/updates/4.2/i386. あるいは他の場合は http://www.sunsite.unc.edu/pub/Linux/distributions/redhat/code/rpm/

もし MySQL クライアントを実行して以下のエラーになった場合：

     ld.so.1: ./my: fatal: libmysqlclient.so.4: open failed: No such file or directory

以下の方法で解決できます：

  * クライアントを以下のフラグで(-Lpathのかわりに)リンクします： -Wl,r/path-libmysqlclient.so

  * libmysqclient.so を /usr/lib にコピーします

  * LD_RUN_PATH 環境変数を libmysqlclient.so が存在する場所に設定します。 (クライアントを実行する前に設定します)

富士通コンパイラ (fcc / FCC) を使用している場合、MySQL のコンパイルにいくつかの問題があります。Linux ヘッダファイルはとても gcc 指向であるためです。

次の configure 行は fcc/FCC で動作します:

     CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=const -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib  -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO '-D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory

Linux-x86 notes
...............

MySQL は libc 5.4.12 以上が必要です。libc 5.4.46 で動作します。 glibc 2.0.6 以上でも動作します。 glibc の RPM にはいくつか問題があり、アップデートをチェックしてください。 glibc 2.0.7-19 と 2.0.7-29 RPM で動作します。

古い Linux 配布物では、configure 時に以下のようなエラーが出るかもしれません：

     Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file.
     See the Installation chapter in the Reference Manual.

これは _P マクロが一つのアンダースコアしかもてないためで、このエラーメッセージのように対処してください。

以下のようなワーニングは無視して構いません：

     mysqld.cc -o objs-thread/mysqld.o
     mysqld.cc: In function `void init_signals()':
     mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int'
     mysqld.cc: In function `void * signal_hand(void *)':
     mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int'

Debian GNU/Linux では、MySQL をマシンの起動時に立ちあげるためには、以下のようにします：

     shell> cp support-files/mysql.server /etc/init.d/mysql.server
     shell> /usr/sbin/update-rc.d mysql.server defaults 99

mysql.server スクリプトは MySQL をインストールした先の share/mysql directory にあります。あるいは、 MySQL のソースの中の support-files ディレクトリにあります。

mysqld がつねにスタート時にコアをはく場合、古い /lib/libc.a を使用しているかもしれません。 sql/mysqld を消去して、新しく make install してみてください。これはいくつかの Slackware で報告された現象です。 RedHat 5.0 は glibc のバージョンによって問題が発生します。 See Linux-RedHat50.

もし mysqld をリンクする場合に以下のようなエラーが出た場合、 libg++.a が正しくインストールされていません：

     /usr/lib/libc.a(putc.o): In function `_IO_putc':
     putc.o(.text+0x0): multiple definition of `_IO_putc'

libg++.a の使用を避けるには、 configure を以下のようにします：

     shell> CXX=gcc ./configure

RedHat 5.0 notes
................

もし RedHat で MySQL に問題がある場合、まず glibc のバージョンを新しいものにあげてください！

RedHat のオフィシャルパッチ(including glibc-2.0.7-19 and glibc-devel-2.0.7-19) をインストールしているなら、 MySQL は問題なく動くはずです！

glibc 2.0.5 には pthread_key_create 変数を解放する部分にバグがあり、アップデートが必要です。glibc 2.0.5 を使用する場合、スタティックリンクされて作成された MySQL バイナリ配布物を使用すべきです。ソースからコンパイルしたい場合、 http://www.mysql.com/Downloads/Linux にある LinuxThreads の修正版をインストールするか、あるいは glibc をバージョンアップしなくてはなりません。

もし glibc or LinuxThreads のバージョンが問題のあるものだと、 mysqld はコネクションの度にクラッシュします。例えば、mysqladmin version は mysqld を完全にクラッシュします！

また、問題のあるライブラリーを使用していると、 mysqld は起動時にクラッシュします。いくつかの Linux systems では、以下のようにして configure でこれを避けることができます：

     shell> ./configure --with-mysqld-ldflags=-all-static

RedHat 5.0 では、glibc 2.0.7-19 RPM を簡単にインストールできますので、インストール後、--with-mysqld-ldflags=-all-static なしで configure できます。

glibc 2.0.7 のソースに対するパッチは

     http://www.mysql.com/Download/Linux/glibc-2.0.7-total-patch.tar.gz

にあります。このパッチは MySQL がテストされたパッチで、簡単に適用できます。

もし MySQL 構築時にクラッシュする場合、新しい MySQL のバイナリをダウンロードしてみてください。これはスタティックリンクで作成されており、ライブラリーの衝突を避けることができ、全ての Linux で動くはずです！

MySQL はデバッグのためトレースファイルに情報を書き出すことができます。これは問題を解決するためにヒントになる情報を多く出力します。 See Debugging server.

RedHat 5.1 notes
................

RedHat 5.1 の glibc (glibc 2.0.7-13) はメモリーリークします。 glibc を 2.0.7-19 にアップグレードしなくてはなりません。あるいは、バイナリ配布の mysqld を使用するかです。もしこれを行わなかった場合、メモリー関連の問題が発生します(out of memory, etc.,etc.)。多くの場合以下のように：

     Can't create a new thread (errno 11). If you are not out of available
     memory, you can consult the manual for any possible OS dependent bug

glibc 2.0.7-19 にアップグレード後は、MySQL をダイナミックリンク指定(デフォルト)で configure できます。が、glibc 2.0.7-19 をソースからインストールしない限り、 --with-mysqld-ldflags=-all-static オプションは configure で使用できません！

glibc のバージョンは rpm -q glibc で確認できます。

Linux-SPARC notes
.................

いくつかの埋め込み関数, readdir_r() が壊れます。この顕れとして、SHOW DATABASES が常に空を返します。これは configure 後、コンパイルする前に、 config.h から HAVE_READDIR_R を取り除くことで解決します。

その他いくつかの問題は、あなたの Linux にパッチを当てる必要があります。パッチは http://www.mysql.com/patches/Linux-sparc-2.0.30.diff にあります。このパッチは、vger.rutgers.edu にある sparclinux-2.0.30.tar.gz 用です。 (これは正式の 2.0.30 とは違います。パッチを正式2.0.30に当てないように) そして LinuxThreads 0.6 かそれ以上にしなくてはなりません。

これは jacques@solucorp.qc.ca から寄せられました。

Linux-Alpha notes
.................

MySQL 3.23.12 が、Linux-Alpha 上で最初にテストされたバージョンです。もし MySQL を Linux-Alpha 上で使用したいと考えたなら、このバージョンより新しいものを使用します。

Linux-Alpha での一番大きな問題は、このプラットフォームの glibc にまだいくつか問題があることです。 最新の glibc を得ることからはじめてください。

We have tested MySQL on Alpha with our benchmarks + test suite and it appears to work nicely.  The main thing we haven't yet had time to test is how things works with many concurrent users.

When we compiled MySQL we where using SuSE 6.3, kernel 2.2.13-SMP, egcs 1.1.2 and libc-2.1.2-28.

We used the following configure line:

     CFLAGS="-O6 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions  -fno-rtti" ./configure --prefix=/usr/local/mysql --disable-shared

If you have access to Compaq's C compiler, the following configure line will give you about 9 % more performance:

     CC=ccc CFLAGS="-fast -O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mcpu=ev6 -Wa,-mev6" CXXLDFLAGS='/usr/lib/compaq/libots-2.2.7/libots.so /usr/lib/compaq/cpml-5.0.0/libcpml_ev6.a' ./configure --prefix=/usr/local/mysql --disable-shared

Note that the last example assumes your are using an Alpha EV6 processor.

Some known problems when running MySQL on Linux-Alpha:

  * If you create many files ( > 10000) in one directory (as done by the test-create in the MySQL benchmarks, mysqld may report the error Can't create/write to file '...' (Errcode: 12). This is probably a bug in the Linux-Alpha kernel.

  * Debugging threaded applications like MySQL will not work with gdb 4.18.  You should download and use gdb 5.0 instead!

  * If you try linking mysqld staticly, the resulting image will core dump at start.  In other words, DON'T use --with-mysqld-ldflags=-all-static

We don't yet know if the following old information is still relevant, so we leave this here until we have had time to test Linux-Alpha properly.

もしシグナルで問題がある場合 (MySQL dies unexpectedly under high load)、これは OS とスレッドのバグでしょう。この場合、MySQL をシグナルを使用しないように、configure 時に指定できます：

     shell> CFLAGS=-DDONT_USE_THR_ALARM \
            CXXFLAGS=-DDONT_USE_THR_ALARM \
            ./configure ...

これは MySQL のパフォーマンスに影響しませんが、 mysqladmin kill or mysqladmin shutdown を使用して、接続が ``sleeping'' になっているクライアントを kill できません。次のコマンドを発行したとき、そのクライアントは死にます。

MkLinux notes
.............

MySQL は最新の glibc を使用した MkLinux で動作します。 (glibc 2.0.7 でテストしました).

Qube2 Linux notes
.................

Qube2 (Linux Mips) 上で MySQL を動作させるには、最新の glibc ライブラリでなくてはなりません(glibc-2.0.7-29C2 は動作することが分かっています)。 そして、 egcs C++ compiler (egcs-1.0.2-9, gcc 2.95.2 以上) を使用しなくてはなりません。

Alpha-DEC-Unix notes
--------------------

When compiling threaded programs under Digital UNIX, the documentation recommends the -pthread option for cc and cxx and the libraries -lmach -lexc (in addition to -lpthread). You should run configure something like this:

     shell> CC="cc -pthread" CXX="cxx -pthread -O" \
            ./configure --with-named-thread-libs="-lpthread -lmach -lexc -lc"

When compiling mysqld, you may see a couple of warnings like this:

     mysqld.cc: In function void handle_connections()':
     mysqld.cc:626: passing long unsigned int *' as argument 3 of
     accept(int,sockadddr *, int *)'

You can safely ignore these warnings. They occur because configure can't detect warnings, only errors.

If you start the server directly from the command line, you may have problems with it dying when you log out.  (When you log out, your outstanding processes receive a SIGHUP signal.)  If so, try starting the server like this:

     shell> nohup mysqld [options] &

nohup causes the command following it to ignore any SIGHUP signal sent from the terminal.  Alternatively, start the server by running safe_mysqld, which invokes mysqld using nohup for you.

Alpha-DEC-OSF1 notes
--------------------

If you have problems compiling and have DEC CC and gcc installed, try running configure like this:

     shell> CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
            ./configure --prefix=/usr/local/mysql

If you get problems with the c_asm.h file, you can create and use a 'dummy' c_asm.h file with:

     shell> touch include/c_asm.h
     shell> CC=gcc CFLAGS=-I./include \
            CXX=gcc CXXFLAGS=-O3 \
            ./configure --prefix=/usr/local/mysql

On OSF1 V4.0D and compiler "DEC C V5.6-071 on Digital UNIX V4.0 (Rev. 878)" the compiler had some strange behavior (undefined asm symbols). /bin/ld also appears to be broken (problems with _exit undefined errors occuring while linking mysqld).  On this system, we have managed to compile MySQL with the following configure line, after replacing /bin/ld with the version from OSF 4.0C:

     shell> CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql

With the Digital compiler "C++ V6.1-029", the following should work:

     CC=cc -pthread
     CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host
     CXX=cxx -pthread
     CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host
     export CC CFLAGS CXX CXXFLAGS
     ./configure --prefix=/usr/mysql/mysql --with-low-memory --enable-large-files --with-mysqld-ldflags=-all-static --disable-shared --with-named-thread-libs="-lmach -lexc -lc"

In some versions of OSF1, the alloca() function is broken. Fix this by removing the line in config.h that defines 'HAVE_ALLOCA'.

The alloca() function also may have an incorrect prototype in /usr/include/alloca.h.  This warning resulting from this can be ignored.

configure will use the following thread libraries automatically: --with-named-thread-libs="-lpthread -lmach -lexc -lc".

When using gcc, you can also try running configure like this:

     shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ....

If you have problems with signals (MySQL dies unexpectedly under high load) you may have found an OS bug with threads and signals. In this case you can tell MySQL not to use signals by configuring with:

     shell> CFLAGS=-DDONT_USE_THR_ALARM \
            CXXFLAGS=-DDONT_USE_THR_ALARM \
            ./configure ...

This doesn't affect the performance of MySQL, but has the side effect that you can't kill clients that are ``sleeping'' on a connection with mysqladmin kill or mysqladmin shutdown.  Instead, the client will die when it issues its next command.

With gcc 2.95.2, you will probably run into the following compile error:

     sql_acl.cc:1456: Internal compiler error in `scan_region', at except.c:2566
     Please submit a full bug report.

To fix this you should change to the sql directory and do a 'cut and paste' of the last gcc line, but change -O3 to -O0 (or -O0 immediately after gcc if you don't have any -O option on your compile line. After this is done you can just change back to the top level directly and run make again.

SGI-IRIX notes
--------------

If you are using Irix 6.5.3 or newer mysqld will only be able to create threads if you run it as a user with CAP_SCHED_MGT privileges (like root) or give the mysqld server this privilege with the following shell command:

     shell> chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld

You may have to undefine some things in config.h after running configure and before compiling.

In some Irix implementations, the alloca() function is broken. If the mysqld server dies on some SELECT statements, remove the lines from config.h that define HAVE_ALLOC and HAVE_ALLOCA_H. If mysqladmin create doesn't work, remove the line from config.h that defines HAVE_READDIR_R. You may have to remove the HAVE_TERM_H line as well.

SGI recommends that you install all of the patches on this page as a set: http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html

At the very minimum, you should install the latest kernel rollup, the latest rld rollup, and the latest libc rollup.

You definately need all the POSIX patches on this page, for pthreads support:

http://support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html

If you get the something like the following error when compiling mysql.cc:

     "/usr/include/curses.h", line 82: error(1084): invalid combination of type

Then type the following in the top-level directory of your MySQL source tree:

     shell> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
     shell> make

There have also been reports of scheduling problems.  If only one thread is running, things go slow. Avoid this by starting another client. This may lead to a 2-to-10-fold increase in execution speed thereafter for the other thread.  This is a poorly-understood problem with Irix threads; you may have to improvise to find solutions until this can be fixed.

If you are compiling with gcc, you can use the following configure command:

     shell> CC=gcc CXX=gcc CXXFLAGS=-O3 \
            ./configure --prefix=/usr/local/mysql --with-thread-safe-client --with-named-thread-libs=-lpthread

FreeBSD notes
-------------

FreeBSD 3.x is recommended for running MySQL since it the thread package is much more integrated.

最も簡単にインストールする方法は、http://www.freebsd.org の mysql-server と mysql-client の ports を利用することです。 http://www.freebsd.org

これは以下のような利点をもたらします：

  * オプティマイズされた MySQL が動く

  * 自動 configuration と build

  * スタートアップ用のスクリプトが /usr/local/etc/rc.d にインストール

  * Ability to see which files that are installed with pkg_info -L. And to remove them all with pkg_delete if you no longer want MySQL on that machine.

FreeBSD 2.x 上では MIT-pthreads を、そして versions 3 以上では、ネイティブのスレッドを使用してください。最近のいくつかの 2.2.x ではネイティブのスレッド で動作が可能ですが、 mysqld を 落とすときに問題が起こります。

名前解決の設定を確実にしておいてください。 でないと、mysqld に接続する際、名前解決にとても時間がかかり、接続に失敗するでしょう。

確実に /etc/hosts ファイルに localhost が登録されているようにしてください。 (でないと、データベースへの接続で問題が出ます)。 /etc/hosts ファイルは、以下の行から始まるべきです：

     127.0.0.1       localhost localhost.your.domain

もし configure が MIT-pthread を使用すると分かった場合、 MIT-pthreads notes を読むべきです。 See MIT-pthreads.

If you get an error from make install that it can't find /usr/include/pthreads, configure didn't detect that you need MIT-pthreads. This is fixed by executing these commands:

     shell> rm config.cache
     shell> ./configure --with-mit-threads

FreeBSD の make の振る舞いは  GNU の make と少し違います。もし make にかかわる問題が出たなら、 GNU make をインストールすべきです。

FreeBSD では、デフォルトのファイルハンドルの上限値がとても少ない値であることも知られています。See Not enough file handles. safe_mysqld 中の ulimit -n のコメントを外すか、/etc/login.conf ファイルで mysqld ユーザーの制限値を増加させます。 (/etc/login.conf の変更の際は cap_mkdb /etc/login.conf で再構築が必要です)。もしデフォルトを使用したくなければ、このユーザーに password ファイル中で適切な Class を与えることでも、変更可能になります。(use: chpass mysqld-user-name)

もし MySQL が現在時で問題があるなら、 TZ 環境変数を設定しなくてはなりません。 See Environment variables.

安全で安定したシステムを入れるなら、 -STABLE のカーネルだけを使用してください。

NetBSD notes
------------

To compile on NetBSD you need GNU make. Otherwise the compile will crash when make tries to run lint on C++ files.

OpenBSD 2.5 notes
-----------------

On OpenBSD 2.5, you can compile MySQL with native threads with the following options:

     CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no

BSD/OS notes
------------

BSD/OS 2.x notes
................

If you get the following error when compiling MySQL, your ulimit value for virtual memory is too low:

     item_func.h: In method `Item_func_ge::Item_func_ge(const Item_func_ge &)':
     item_func.h:28: virtual memory exhausted
     make[2]: *** [item_func.o] Error 1

Try using ulimit -v 80000 and run make again.  If this doesn't work and you are using bash, try switching to csh or sh; some BSDI users have reported problems with bash and ulimit.

If you are using gcc, you may also use have to use the --with-low-memory flag for configure to be able to compile sql_yacc.cc.

もし MySQL が現在時で問題があるなら、 TZ 環境変数を設定しなくてはなりません。 See Environment variables.

BSD/OS 3.x notes
................

Upgrade to BSD/OS 3.1. If that is not possible, install BSDIpatch M300-038.

Use the following command when configuring MySQL:

     shell> env CXX=shlicc++ CC=shlicc2 \
            ./configure \
                --prefix=/usr/local/mysql \
                --localstatedir=/var/mysql \
                --without-perl \
                --with-unix-socket-path=/var/mysql/mysql.sock

The following is also known to work:

     shell> env CC=gcc CXX=gcc CXXFLAGS=-O3 \
            ./configure \
                --prefix=/usr/local/mysql \
                --with-unix-socket-path=/var/mysql/mysql.sock

You can change the directory locations if you wish, or just use the defaults by not specifying any locations.

If you have problems with performance under heavy load, try using the --skip-thread-priority option to safe_mysqld!  This will run all threads with the same priority; on BSDI 3.1, this gives better performance (at least until BSDI fixes their thread scheduler).

If you get the error virtual memory exhausted while compiling, you should try using ulimit -v 80000 and run make again. If this doesn't work and you are using bash, try switching to csh or sh; some BSDI users have reported problems with bash and ulimit.

BSD/OS 4.x notes
................

BSDI 4.x has some thread related bugs.  If you want to use MySQL on this, you should install all thread related patches. At least M400-023 should be installed.

On some BSDI 4.x systems, you may get problems with shared libraries. The symptom is that you can't execute any client programs, like for example mysqladmin.  In this case you need to reconfigure not to use shared libraries with the --disable-shared option to configure.

SCO notes
---------

The current port is tested only on a ``sco3.2v5.0.4'' and ``sco3.2v5.0.5'' system.  There has also been a lot of progress on a port to ``sco 3.2v4.2''.

For the moment the recommended compiler on OpenServer is gcc 2.95.2. With this you should be able to compile MySQL with just:

     CC=gcc CXX=gcc ./configure ... (options)

 1. For OpenServer 5.0.X you need to use GDS in Skunkware 95 (95q4c).  This is necessary because GNU gcc 2.7.2 in Skunkware 97 does not have GNU as.  You can also use egcs 1.1.2 or newer http://www.egcs.com/.  If you are using egcs 1.1.2 you have to execute the following command:

          shell> cp -p /usr/include/pthread/stdtypes.h /usr/local/lib/gcc-lib/i386-pc-sco3.2v5.0.5/egcs-2.91.66/include/pthread/

 2. You need the port of GCC 2.5.? for this product and the Development system.  They are required on this version of SCO UNIX.  You cannot just use the GCC Dev system.

 3. You should get the FSU Pthreads package and install it first.  This can be found at http://www.cs.wustl.edu/~schmidt/ACE_wrappers/FSU-threads.tar.gz. You can also get a precompiled package from ftp://www.mysql.com/pub/mysql/Downloads/SCO/FSU-threads-3.5c.tar.gz.

 4. FSU Pthreads can be compiled with SCO UNIX 4.2 with tcpip.  Or OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0), with the SCO Development System installed using a good port of GCC 2.5.X ODT or OS 3.0 you will need a good port of GCC 2.5.? There are a lot of problems without a good port.  The port for this product requires the SCO UNIX Development system.  Without it, you are missing the libraries and the linker that is needed.

 5. To build FSU Pthreads on your system, do the following:

      1. Run ./configure in the threads/src directory and select the SCO OpenServer option. This command copies Makefile.SCO5 to Makefile.

      2. Run make.

      3. To install in the default /usr/include directory, login as root, then cd to the thread/src directory, and run make install.

 6. Remember to use GNU make when making MySQL.

 7. On OSR 5.0.5, you should use the following configure line:

          shell> CC="gcc -DSCO" CXX="gcc -DSCO" ./configure

     The -DSCO is needed to help configure detect some thread functions properly.  If you forget -DSCO, you will get the following error message while compiling:

          my_pthread.c: In function `my_pthread_mutex_init':
          my_pthread.c:374: `pthread_mutexattr_default' undeclared (first use this function)

 8. If you don't start safe_mysqld as root, you probably will get only the default 110 open files per process.  mysqld will write a note about this in the log file.

 9. With SCO 3.2V5.0.5, you should use FSU Pthreads version 3.5c or newer. The following configure command should work:

          shell> CC="gcc -belf" ./configure --prefix=/usr/local/mysql --disable-shared

 10. With SCO 3.2V4.2, you should use FSU Pthreads version 3.5c or newer. The following configure command should work:

          shell> CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
                 ./configure \
                     --with-debug --prefix=/usr/local/mysql \
                     --with-named-thread-libs="-lgthreads -lsocket -lgen -lgthreads" \
                     --with-named-curses-libs="-lcurses"

     You may get some problems with some include files. In this case, you can find new SCO-specific include files at ftp://www.mysql.com/pub/mysql/Downloads/SCO/SCO-3.2v4.2-includes.tar.gz. You should unpack this file in the include directory of your MySQL source tree.

SCO development notes:

  * MySQL should automatically detect FSU Pthreads and link mysqld with -lgthreads -lsocket -lgthreads.

  * The SCO development libraries are reentrant in FSU Pthreads. SCO claims that its libraries' functions are reentrant, so they must be reentrant with FSU Pthreads. FSU Pthreads on OpenServer tries to use the SCO scheme to make reentrant library.

  * FSU Pthreads (at least the version at www.mysql.com) comes linked with GNU malloc.  If you encounter problems with memory usage, make sure that gmalloc.o is included in libgthreads.a and libgthreads.so.

  * In FSU Pthreads, the following system calls are pthreads-aware: read(), write(), getmsg(), connect(), accept(), select() and wait().

If you want to install DBI on SCO, you have to edit the Makefiles in DBI-xxx and each subdirectory:

     OLD:                                  NEW:
     CC = cc                               CC = gcc -belf
     CCCDLFLAGS = -KPIC -W1,-Bexport       CCCDLFLAGS = -fpic
     CCDLFLAGS = -wl,-Bexport              CCDLFLAGS =

     LD = ld                               LD = gcc -belf -G -fpic
     LDDLFLAGS = -G -L/usr/local/lib       LDDLFLAGS = -L/usr/local/lib
     LDFLAGS = -belf -L/usr/local/lib      LDFLAGS = -L/usr/local/lib

     LD = ld                               LD = gcc -belf -G -fpic
     OPTIMISE = -Od         		      OPTIMISE = -O1

     OLD:
     CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include

     NEW:
     CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include

This is because the Perl dynaloader will not load the DBI modules if they were compiled with icc or cc.

Perl works best when compiled with cc.

SCO Unixware 7.0 notes
----------------------

You must use a version of MySQL at least as recent as 3.22.13, because that version fixes some portability problems under Unixware.

We have been able to compile MySQL with the following configure command on UnixWare 7.0.1:

     shell> CC=cc CXX=CC ./configure --prefix=/usr/local/mysql

If you want to use gcc, you must use gcc 2.95.2 or newer.

IBM-AIX notes
-------------

Automatic detection of xlC is missing from Autoconf, so a configure command something like this is needed when using the IBM compiler:

     shell> CC="xlc_r -ma -O3 -qstrict -DHAVE_INT_8_16_32" \
            CXX="xlC_r -ma -O3 -qstrict -DHAVE_INT_8_16_32" \
            ./configure

If you change the -O3 to -O2 in the above configure line, you must also remove the -qstrict option (this is a limitation in the IBM C compiler).

If you are using gcc or egcs to compile MySQL, you MUST use the -fno-exceptions flag, as the exception handling in gcc/egcs is not thread-safe!  (This is tested with egcs 1.1.)  We recommend the following configure line with egcs and gcc on AIX:

     shell> CXX=gcc \
            CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
            ./configure --prefix=/home/monty --with-debug --with-low-memory

If you have problems with signals (MySQL dies unexpectedly under high load) you may have found an OS bug with threads and signals. In this case you can tell MySQL not to use signals by configuring with:

     shell> CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
            CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -DDONT_USE_THR_ALARM" \
            ./configure --prefix=/home/monty --with-debug --with-low-memory

This doesn't affect the performance of MySQL, but has the side effect that you can't kill clients that are ``sleeping'' on a connection with mysqladmin kill or mysqladmin shutdown.  Instead, the client will die when it issues its next command.

On some versions of AIX, linking with libbind.a makes getservbyname core dump. This is an AIX bug and should be reported to IBM.

HP-UX 10.20 notes
-----------------

There are a couple of ``small'' problems when compiling MySQL on HP-UX.  We recommend that you use gcc instead of the HP-UX native compiler, because gcc produces better code!

We recommend one to use gcc 2.95 on HP-UX.  Don't use high optimization flags (like -O6) as this may not be safe on HP-UX.

Note that MIT-pthreads can't be compiled with the HP-UX compiler, because it can't compile .S (assembler) files.

The following configure line should work:

     CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pthread --with-named-thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared

If you are compiling gcc 2.95 yourself, you should NOT link it with the DCE libraries (libdce.a or libcma.a) if you want to compile MySQL with MIT-pthreads.  If you mix the DCE and MIT-pthreads packages you will get a mysqld to which you cannot connect.  Remove the DCE libraries while you compile gcc 2.95!

HP-UX 11.x notes
----------------

For HPUX 11.x we recommend MySQL 3.23.15 or later.

If you are using gcc 2.95.1 on a unpatched HPUX 11.x system you will get the error:

     In file included from /usr/include/unistd.h:11,
                      from ../include/global.h:125,
                      from mysql_priv.h:15,
                      from item.cc:19:
     /usr/include/sys/unistd.h:184: declaration of C function `int pthread_atfork(void (*)(...), void (*)
     (...), void (*)(...))' conflicts with
     /usr/include/sys/pthread.h:440: previous declaration `int pthread_atfork(void (*)(), void (*)(), void (*)())' here
     In file included from item.h:306,
                      from mysql_priv.h:158,
                      from item.cc:19:

The problem is that HP-UX doesn't define pthreads_atfork() consistently. It has conflicting prototypes in /usr/include/sys/unistd.h:184 and /usr/include/sys/pthread.h:440 (I post the details below).

One solution is to copy /usr/include/sys/unistd.h into mysql/include and edit unistd.h and change it to match the definition in pthread.h.  Here's the diff:

     183,184c183,184
     <      extern int pthread_atfork(void (*prepare)(), void (*parent)(),
     <                                                                  void (*child)());
     ---
     >      extern int pthread_atfork(void (*prepare)(void), void (*parent)(void),
     >                                                                  void (*child)(void));

After this, the following configure line should work:

     CFLAGS="-fomit-frame-pointer -O6 -fpic" CXX=gcc CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O6" ./configure --prefix=/usr/local/mysql --disable-shared

Here is some information that a HPUX 11.x user sent us about compile MySQL with HPUX:x compiler

  * Environment:
                proper compilers.
                   setenv CC cc
                   setenv CXX aCC
                flags
                   setenv CFLAGS -D_REENTRANT
                   setenv CXXFLAGS -D_REENTRANT
                   setenv CPPFLAGS -D_REENTRANT
               % aCC -V
               aCC: HP ANSI C++ B3910B X.03.14.06
               % cc -V /tmp/empty.c
               cpp.ansi: HP92453-01 A.11.02.00 HP C Preprocessor (ANSI)
               ccom: HP92453-01 A.11.01.00 HP C Compiler
               cc: "/tmp/empty.c", line 1: warning 501: Empty source file.

  * configuration:
               ./configure  --with-pthread        \
               --prefix=/source-control/mysql     \
               --with-named-thread-libs=-lpthread \
               --with-low-memory

  * added '#define _CTYPE_INCLUDED' to include/m_ctype.h. This symbol is the one defined in HP's /usr/include/ctype.h:

               /* Don't include std ctype.h when this is included */
               #define _CTYPE_H
               #define __CTYPE_INCLUDED
               #define _CTYPE_INCLUDED
               #define _CTYPE_USING   /* Don't put names in global namespace. */

  * I had to use the compile-time flag -D_REENTRANT to get the compiler to recognize the prototype for localtime_r. Alternatively I could have supplied the prototype for localtime_r. But I wanted to catch other bugs without needing to run into them. I wasn't sure where I needed it so I added it to all flags.

  * The optimization flags used by MySQL (-O3) are not recognized by HP's compilers. I did not change the flags.

MacOS X notes
-------------

You can get MySQL to work on MacOS X by following the links to the MacOS X ports. See Useful Links.

MySQL 3.23.7 should include all patches necessary to configure it on MacOSX. You must however first install the pthread package from MySql for MacOSX Server (http://www.prnet.de/RegEx/mysql.html) before configuring MySQL.

You might want to also add aliases to your shell's resource file to access mysql and mysqladmin from the command line.

     alias mysql '/usr/local/mysql/bin/mysql'
     alias mysqladmin '/usr/local/mysql/libexec/mysqladmin'

Win32 notes
===========

この節では Win32 上での MySQL の使用とインストールについて述べます。これは MySQL Win32 配布物の README ファイルにも述べられています。

Win32 への MySQL のインストール
----------------------

もし正式版 MySQL を持っていないなら、最初に以下からシェアウエアバージョンをダウンロードすべきです：

MySQL 3.22.x (http://www.mysql.com/mysql_w32.htmy)

日本語版の評価版、および正式版(3.22)の取得は以下になります： MySQL 日本語版 (http://www.softagency.co.jp/)

もし他のプログラムから MySQL に接続しようと考えているなら、多分 MyODBC ドライバーも必要でしょう。 これは MySQL download page (http://www.mysql.com/ownload_myodbc.html). にあります。

日本語版の MyODBC ドライバー は： MyODBC 日本語版 (http://www.softagency.co.jp/)

それぞれの配布物のインストールをするには、ダウンロードした物をどこか からのディレクトリで unzip し、Setup.exe プログラムを実行します。

標準では、MySQL-Win32 は C:\mysql にインストールされるようになっています。 もし違う場所に MySQL をインストールしたいなら、一度 C:\mysql にインストールした後に、そのフォルダを移動します。 MySQL を C:\mysql から移動したならば、 mysqld に対して、移動先を必ず教えねばなりません。もし MySQL を D:\programs\mysql に移動したなら, mysqld を以下のようにして起動します： D:\programs\mysql\bin\mysqld --basedir D:\programs\mysql なお、 C:\mysql\bin\mysqld --help とすると、全てのオプションが表示されます！

正式版の MySQL では、C:\my.cnf ファイルを作成し、そこに MySQL サーバーのオプションを記述することが可能です。 \mysql\my-xxxxx.cnf を C:\my.cnf にコピーし、ご自分の環境に合わせて編集して使用してください。全てのパスには \ ではなくて / を使用しなくてはなりません。もし \ を使用する場合には、これを２倍します。 MySQL では \ はエスケープ文字だからです。 See Option files.

Win95 / Win98 上での MySQL 起動
--------------------------

MySQL は TCP/IP をクライアントからサーバーへの接続に使用します。（これは、あなたのネットワーク上のいかなるマシンからも MySQL サーバーに接続できるでしょう）。 このため、MySQL を起動する前に、あなたは TCP/IP をインストールしなくてはなりません。これは Windows CD-ROM にあります。

もし古い Win95 (for example OSR2) を使用しているなら、これは古い Winsock パッケージを使用しているかもしれません！ MySQL は Winsock 2 を要求します！ 最新の Winsock は Microsoft (http://www.microsoft.com) にあります。 Win98 はデフォルトで新しい Winsock 2 ライブラリですので、これは Win98 には当てはまりません。

2つの違う MySQL サーバーがあります：

mysqld   フルデバッグを有効にして、自動 memory allocation をチェックするようにコンパイル
mysqld-opt   Pentium プロセッサー用に最適化した物

両方とも Intel プロセッサー >= i386 で動作します。

mysqld サーバーを起動するには, MS-DOS から以下のようにしなくてはなりません：

     C:\mysql\bin\mysqld

これは mysqld をバックグラウンドで動かします。

MySQL サーバーの kill には：

     C:\mysql\bin\mysqladmin -u root shutdown

Note that Win95/Win98 don't support creation of named pipes.  On Win95/Win98, you can only use named pipes to connect to a remote MySQL running on an NT server.

If mysqld doesn't start please check whether or not the \mysql\mysql.err file contains any reason for this.  You can also try to start it with mysqld --standalone;  In this case you may get some useful information on the screen that may help solve this.

The last option is to start mysqld with --debug.  In this case mysqld will write a log file in \mysqld.trace that should contain the reason why mysqld doesn't start.  If you make a bug report about this, please only send the lines where something seams to go wrong to the mailing list!

NT 上での MySQL 起動
---------------

The Win95/Win98 section also applies to MySQL on NT, with the following differences:

TCP/IP で MySQL を動かすには、service pack 3(以上) が必須です！

NT では, サーバーの名前は mysqld-nt です.  通常、以下のようにして NT のサービスとして MySQL をインストールしなくてはなりません：

     C:\mysql\bin\mysqld-nt --install

(mysqld や mysqld-opt を NT 上で動作させることも出来ます。しかしこれらは、サービスとしてスタートさせることが出来ず、また、 named pipes の使用も出来ません。)

MySQL サービスの起動と停止は：

     NET START mysql
     NET STOP mysql

この場合、mysqld に、いかなるオプションも使用できないことに注意！

もし mysqld-nt をオプション無しで起動する必要があるならば、 mysqld-nt をスタンドアローンのプログラムとして NT 上で走らせることも出来ます！ もし mysqld-nt をオプション無しで NT 上で起動すると、 mysqld-nt は自分自身をサービスとして立ち上げようとします。デフォルトのサービスオプションを使用して。もし既に mysqld-nt を止めていたなら、 NET START mysql で起動しなくてはなりません。

サービスは MySql という名前で登録されます。 一度インストールしたら、これは Services Control Manager (SCM) Utility (コントロールパネルにある) を使用するか、NET START MySQL コマンドを使用するかして、起動されなくてはなりません。もし、オプションがなにも指定されていないなら、MySQL サービス開始前に、 SCM Utility の "Startup parameters" に記述しなくてはなりません。一度走れば、 mysqld-nt は mysqladmin や SCM utility 、 NET STOP MySQL コマンドで停止できます。もし SCM を使用して mysqld-nt 停止するなら、 mysqld shutdown normally についての変なメッセージがでます。 When run as a service, mysqld-nt has no access to a console and so no messages can be seen.

NT では以下のエラーメッセージが出るかもしれません：

Permission Denied   Means that it cannot find mysqld-nt.exe
Cannot Register     Means that the path is incorrect

もし mysqld-nt をサービスとしてインストールする場合に問題が発生した場合、フルパスで実行してみてください：

     C:\mysql\bin\mysqld-nt --install

もしこれで動作しないようなら、レジストリ内のパスを修正すれば mysqld-nt を起動できるでしょう。

サービスとして mysqld-nt を起動したくないなら以下のようにします：

     C:\mysql\bin\mysqld-nt --standalone

or

     C:\mysql\bin\mysqld --standalone --debug

最新のバージョンでは、デバッグのトレースを C:\mysqld.trace に出します。

Win32 上で MySQL を実行
------------------

MySQLは全ての Win32 プラットフォーム上で TCP/IP をサポートし、 NT 上で named pipe をサポートします。デフォルトは、NT 上でローカルに接続するときにネームド・パイプが使用され、そのほかの全ての場合で TCP/IP が使用されます。ホスト名はどのプロトコルを使用するかを決めます：

Host name   protocol
NULL (none)    NT では最初にネームド・パイプを試み、動かなければ TCP/IP を使用します。 Win95/Win98 では TCP/IP を使用します。
.   ネームド・パイプ
localhost   TCP/IP to current host
hostname    TCP/IP

MySQL クライアントに named pipes を強制的に使用させるには、 --pipe オプションを指定します。 そして、--socket オプションでパイプの名前を指定します。

MySQL が動いているかどうかは、以下のようにして確認できます：

     C:\mysql\bin\mysqlshow
     C:\mysql\bin\mysqlshow -u root mysql
     C:\mysql\bin\mysqladmin version status proc
     C:\mysql\bin\mysql test

もし Win95/Win98 上で mysqld への接続が遅いようなら、DNS の問題かもしれません。この場合、 mysqld を --skip-name-resolve オプションで起動し、MySQL 許可テーブルには、localhost と IP アドレスだけ使用します。 NT上で走る mysqld-nt MySQL サーバーに対しての接続時に DNS を避けるために、 --pipe 引数を指定してネームド・パイプを使用できます。 これはほとんどの MySQL クライアントで動きます。

2つの MySQL コマンドラインツールがあります：

mysql   Compiled on native Win32, which offers very limited text
editing capabilities.
mysqlc   Compiled with the Cygnus GNU compiler and libraries, which offers readline editing.

もし mysqlc.exe を使用したいなら, C:\mysql\lib\cygwinb19.dll を \windows\system (か、似たパス) にコピーしなくてはなりません。

Win32 の MySQL の初期の権限は、ローカルの全てのユーザーに対して、全てのデータベースで全ての権限が与えられています。 MySQL を安全にするために、全てのユーザーにパスワードを設定すべきです。また、mysql.user テーブルから Host='localhost' で User='' となっているレコードを削除すべきです。

root ユーザーにもパスワードを設定すべきです： (The following example starts by removing the anonymous user, that allows anyone to access the 'test' database)

     C:\mysql\bin\mysql mysql
     mysql> DELETE FROM user WHERE Host='localhost' AND User='';
     mysql> QUIT
     C:\mysql\bin\mysqladmin reload
     C:\mysql\bin\mysqladmin -u root password your_password

パスワードを設定した後、もし mysqld サーバーを停止させるなら、以下のようにします：

     mysqladmin --user=root --password=your_password shutdown

If you are using the old shareware version of MySQL 3.21 under Windows, the above command will fail with an error: parse error near 'SET OPTION password'.  This is because the old shareware version, which is based on MySQL 3.21, doesn't have the SET PASSWORD command.  The fix is in this case is to upgrade to the 3.22 shareware version.

With the newer MySQL versions you can easily add new users and change privileges with GRANT and REVOKE commands. See GRANT.

SSH を利用してリモートの MySQL に Win32 から接続
---------------------------------

SSH を利用して、Win32 から、どうやってリモートの MySQL に接続するかの説明です。 (by David Carlson).

  * あなたの windows マシンに SSH クライアントをインストールします - 私はフリー版の SSH クライアントを使用しました。 http://www.doc.ic.ac.uk/~ci2/ssh/. 他の有益な情報は： http://www.npaci.edu/Security/npaci_security_software.html and http://www.npaci.edu/Security/samples/ssh32_windows/index.html.

  * SSH を起動。 Host Name を あなたの MySQL サーバーの名前か IP アドレスにセットします。 userid を、あなたのサーバーへのログイン名にセットします。

  * "local forwards" をクリック。 local port: 3306, host: localhost, remote port: 3306 にそれぞれセット。

  * 全て保存(Save)。 保存しても次回やり直しができます。

  * SSH であなたのサーバーにログイン。

  * なにか ODBC アプリケーション(例えば Access) を起動。

  * ODBC ドライバーを利用して MySQL への新しいファイルとリンクを作成。これは通常の時と作成方法は変わりないですが、サーバーが "localhost" であることが違います

That's it. It works very well with a direct Internet connection. I'm having problems with SSH conflicting with my Win95 network and Wingate - but that'll be the topic of a posting on another software company's usegroup!

Splitting data across different disks under Win32
-------------------------------------------------

On windows MySQL 3.23.16 and above is compiled with the -DUSE_SYMDIR option.  This allows you to put a database on different disk by adding a symbolic link to it (in a similar manner that symbolic links works on Unix).

On windows you make a symbolic link to a database by creating a file that contains the path to the destination directory and saving this in the mysql_data directory under the filename database.sym. Note that the symbolic link will only be used if the directory mysql_data_dir\database doesn't exist.

For example if you want to have database foo on D:\data\foo you should create the file C:\mysql\data\foo.sym that should contains the text D:\data\foo.  After this, all tables created in the database foo will be created in D:\data\foo.

MySQL-Win32 compared to Unix MySQL
----------------------------------

MySQL-Win32 バージョンは現在それ自体とても安定した(stableな)状態で供給されています。 MySQL-win32 バージョンは すべての機能がUNIXバージョンのMySQLと対応しています。ただし、下記のような例外があります。

Win95 とスレッド
     Win95は、各々のスレッドの作成のためにメインメモリのおよそ200バイトをメモリリークします。これのために、もしあなたが多くの接続をすれば、MySQL の各々の接続が新しいスレッドを作成するので、あなたはWin95では長時間、mysqld を実行させるべきではありません！ WinNT and Win98 don't suffer from this bug.

Concurrent reads
     MySQL depends on the pread() and pwrite() calls to be able to mix INSERT and SELECT. As windows doesn't support these calls, MySQL can't currently handle concurrent reads on windows. We plan to fix this by adding an extra mutex to each open file and simulate pread()/pwrite().

ブロック読み込み
     MySQL はそれぞれの接続のためにブロック読み込みを使います。これは以下の事柄を意味しています：

       * 接続は、MySQL のUnixバージョンで起こるように、8時間の後に自動的に接続が断ち切られるわけではありません

       * もし接続が「ハングすれば」、MySQLを終了しないでそれを中断することは、不可能です。

       * mysqladmin kill は、スリープしている接続上では働かないはずです。

       * スリープしている接続があるかぎり、mysqladmin shutdown は、中絶することができません。

     私たちは、近い将来にこれを修正することを計画しています。

UDF 関数
     差し当り、MySQL-Win32 はユーザの定義できる関数をサポートしません。

DROP DATABASE
     複数のスレッドで使われているデータベースはDROPをすることができません。

タスクマネージャーからの MySQL の終了
     Windows95では「Windowsの終了」やタスクマネージャから MySQL を終了することはできません。 mysqladmin shutdown で終了しなければなりません。

大文字小文字を区別しない名前
     Win32ではファイルネームは大文字小文字が区別されます。そのため、Win32用の MySQL ではテーブル名は大文字小文字が区別されます。唯一の制限は、名前が所定のステートメントの至る所の同じケースで与えられなければならないそのデータベースと表です。下のようなクエリーは働きません。それが表の MY_TABLE, my_table 両方を参照するからです。

          SELECT * FROM my_table WHERE MY_TABLE.col=1;

The \ (ディレクトリ名)
     Win95のパス名コンポーネントは、 \ によって離されますが、その文字は同じく MySQL のエスケープ文字でもあります。もしあなたは LOAD DATA INFILE または SELECT ... INTO OUTFILE を使って、UNIXでのファイルネームで / を書くようにしたいなら、その代わりに「\\」と \ をダブルで使わなくてはなりません。

          LOAD DATA INFILE "C:\\tmp\\skr.txt" INTO TABLE skr;
          SELECT * FROM skr INTO OUTFILE 'C:/tmp/skr.txt';

Can't open named pipe エラー
     もしあなたが最新の mysql-clients を持つNTの上で MySQL-Win32 のシェアウェアバージョンを使えば、あなたは、次のエラーを得ることになるはずです:

          error 2017: can't open named pipe to host: . pipe...

     これは、 MySQL のリリースバージョンがデフォルトでNTの上にネームドパイプを使っているために起こっています。あなたは新しい MySQL クライアントにまたは C:\my.cnf ファイルを作るさい(このファイルは以下の情報を含みます)に --host=localhost オプションを使うことによってこのエラーを避けられます。

          [client]
          host = localhost

Access denied for user error
     もしあなたが同じマシン上の MySQL サーバーにアクセスした時 Access denied for user: 'some-user@unknown' to database 'mysql' エラーを得るなら、これはあなたの MySQL があなたのマシンのホスト名を正しく解決できてないことを意味します。

     これを修正するにはあなたはファイル \windows\hosts を作り、以下の情報を書くことによってすべきです。 (注:Windows95,98には\Windowsフォルダ上にサンプルとして「lmhosts.sam」ファイルが既にあるはずです)

          127.0.0.1       localhost

ここにはWin32リリースを助けてくれる誰かのためにいくつかオープンになっている問題があります:

  * Make a single user MYSQL.DLL server.  This should include everything in a standard MySQL server, except thread creation.  This will make MySQL much easier to use in applications that don't need a true client/server and don't need to access the server from other hosts.

  * Add some nice ``start'' and ``shutdown'' icons to the MySQL installation. MySQL.DLL.

  * Create a tool to manage registry entries for the MySQL startup options.  The registry entry reading is already coded into mysqld.cc, but it should be recoded to be more ``parameter'' oriented. The tool should also be able to update the \my.cnf file if the user would prefer to use this instead of the registry.

  * NT上で mysqld をサービスとして --install フラグで登録するとき、もしあなたがコマンドラインの上でデフォルトのオプションを同じく加えることができれば、それは、良いだろう。この問題は差し当たって、 C:\my.cnf ファイルを代わりにすることで代用しています。

  * あなたがラップトップの走るWin95を中断すると、ラップトップのレジュームされる時、 mysqld デーモンは新しい接続を受け入れません。私たちは、これがWin95、TCP/IP、または、 MySQL が持つ問題であるかどうかわかりません。

  * また、タスクマネージャから mysqld を終了させることができればほんとうに親切でしょう。今のところ、あなたは mysqladmin shutdown を使わなければなりません。

  * mysql のコマンドラインツールとして readline をWin32に移植しませんか？

  * 標準の MySQL クライアント(mysql、mysqlshow、mysqladmin、および、mysqldump)のGUI バージョンがあればいいでしょうねぇ。

  * もし net.c のソケットへ「読み込み」と「書き込み」がinterruptibleならば、それはいいのですが。これができればWin32上で mysqladmin kill を使用して開かれたスレッドを終了できるのですが。

  * MySQL-Win32/MyODBC について書かれたWindowsプログラミングのドキュメント…それらが動いていることを確認済みであること。

  * mysqld はデフォルトロケールではなく、常に「C」ロケールで起動します。私たちは、ソート順序のために、 mysqld に、現在のロケールを使わせたい。

  * MysqlManagerにもっと多くのオプションを。

  * クライアントとサーバーのコミュニケーションプロトコルの変更…socketsとTCP/IPの代わりにWindows内部のコミュニケーションを使う

  * UDF 関数の .DLL での実装

  * Add macros to use the faster thread-safe increment/decrement methods provided by Win32.

他のwin32に限定された症状は MySQL-Win32 ディストリビューションに同梱されている README ファイルで説明されています。

OS/2 notes
==========

MySQL uses quite a few open files. Because of this, you should add something like the following to your CONFIG.SYS file:

     SET EMXOPT=-c -n -h1024

If you don't do this, you will probably run into the following error:

     File 'xxxx' not found (Errcode: 24)

When using MySQL with OS/2 Warp 3, FixPack 29 or above is required.  With OS/2 Warp 4, FixPack 4 or above is required. This is a requirement of the Pthreads library.  MySQL must be installed in a partition that supports long file names such as HPFS, FAT32, etc.

The INSTALL.CMD script must be run from OS/2's own CMD.EXE and may not work with replacement shells such as 4OS2.EXE.

The scripts/mysql-install-db script has been renamed: it is now called install.cmd and is a REXX script which will set up the default MySQL security settings and create the WorkPlace Shell icons for MySQL.

Dynamic module support is compiled in but not fully tested. Dynamic modules should be compiled using the Pthreads runtime library.

     gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \
         -o example udf_example.cc -L../lib -lmysqlclient udf_example.def
     mv example.dll example.udf

Note: Due to limitations in OS/2, UDF module name stems must not exceed 8 characters. Modules are stored in the /mysql2/udf directory; the safe-mysqld.cmd script will put this directory in the BEGINLIBPATH environment variable. When using UDF modules, specified extensions are ignored --- it is assumed to be .udf. For example, in Unix, the shared module might be named example.so and you would load a function from it like this:

     CREATE FUNCTION metaphon RETURNS STRING SONAME "example.so";

Is OS/2, the module would be named example.udf, but you would not specify the module extension:

     CREATE FUNCTION metaphon RETURNS STRING SONAME "example";

TcX binaries
============

サービスとして、TcX は MySQL のバイナリ配布を提供しています。これらのコンパイルは TcX 内部でおこなったり、我々にマシンのアクセスを提供してもらっている顧客のマシン上で行っています。

これらの配布物は scripts/make_binary_distribution で作成され、以下のコンパイルオプションで調整されています。

SunOS 4.1.4 2 sun4c with gcc 2.7.2.1
     CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --disable-shared

SunOS 5.5.1 sun4u with egcs 1.0.3a
     CC=gcc CFLAGS="-O6 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory

SunOS 5.6 sun4u with egcs 2.90.27
     CC=gcc CFLAGS="-O6 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory

SunOS 5.6 i86pc with gcc 2.8.1
     CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory

Linux 2.0.33 i386 with pgcc 2.90.29 (egcs 1.0.3a)
     CFLAGS="-O6 -mpentium -mstack-align-double -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -mpentium -mstack-align-double -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static

SCO 3.2v5.0.4 i386 with gcc 2.7-95q4
     CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql

AIX 2 4 with gcc 2.7.2.2
     CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql

OSF1 V4.0 564 alpha with gcc 2.8.1
     CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory

Irix 6.3 IP32 with gcc 2.8.0
     CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql

BSDI BSD/OS 3.1 i386 with gcc 2.7.2.1
     CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql

BSDI BSD/OS 2.1 i386 with gcc 2.7.2
     CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql

上で示したオプション以外で最適化を施した方はだれでも、開発者向けのメーリングリストにポストできます。 developer@lists.mysql.com.

RPM 配布では MySQL 3.22 を user-contributed としています。 3.22 をはじめ、いくつかの RPM パッケージは TcX 製です。

インストール後の設定とテスト
==============

初めて MySQLをインストールしたら(バイナリからでもソースからでもですが)、サーバーを動作させるために、許可テーブルを初期化しなくてはなりません。またマシンの起動時、停止時に、サーバーを自動で開始、停止することもできます。

通常、許可テーブルのインストールとサーバーの開始は、ソースディストリビューションなら以下のようにします：

     shell> ./scripts/mysql_install_db
     shell> cd mysql_installation_directory
     shell> ./bin/safe_mysqld &

バイナリディストリビューションでは次を行ないます:

     shell> cd mysql_installation_directory
     shell> ./bin/mysql_install_db
     shell> ./bin/safe_mysqld &

テストは、MySQL のトップディレクトリーから簡単に実行できます。バイナリ配布を使用する場合、これ(トップディレクトリ)はインストール先のディレクトリーになるでしょう(/usr/local/mysql)。ソース配布の場合、これは MySQL のソースディレクトリです。

コマンドは本節といかに続く節で説明しますが、BINDIR は mysqladmin や safe_mysqld がインストールされたディレクトリを示します。バイナリ配布を使用している場合、BINDIR はバイナリ配布の bin ディレクトリになります。ソースからインストールした場合、BINDIR は、configure で特別指定しない限り、 /usr/local/bin です。 EXECDIR は mysqld サーバーのインストール先です。バイナリ配布を使用している場合、これは BINDIR ディレクトリと同一になります。ソースからインストールした場合、/usr/local/libexec です。

テストについて以下に詳細に説明します:

 1. 必要ならば、mysqld サーバーを起動し MySQL の許可テーブルを初期化します。 (許可テーブルはユーザーがどのような権限をもってサーバーに接続を許すかを決定するものです。) これは通常、mysql_install_db スクリプトで初期化されます。

          shell> scripts/mysql_install_db

     通常、mysql_install_db の実行は初めて MySQL をインストールしたあと一度だけ必要です。  すでにインストールされているものをアップグレードする際にはこの手順は飛ばせます。（しかし、mysql_install_db は実に安全で、すでにテーブルが存在している場合はいかなるテーブルも更新しません。したがって、実行すべきかどうかわからない場合は、mysql_install_db を常に走らせることができます）

     mysql_install_db は 6個のテーブルを作ります (user, db, host, tables_priv, columns_priv and func) mysql データベースに。 初期の権限状態についての説明は Default privileges.  これらの権限は MySQL root ユーザーになんでもできるように許可し、そして、だれもが 'test' という名前か 'test_' ではじまる名前をもつデータベースを作成、使用できるように許可されています。

     もし許可テーブルを設定していない場合、サーバーを起動時に以下のエラーが出ます：

          mysqld: Can't find file: 'host.frm'

     バイナリ配布の MySQL では、もし MySQL を ./bin/safe_mysqld を実行しないで起動した場合に、このエラーがおきます。!

     root で mysql_install_db を実行する必要があるとあなたは思うかもしれません。しかし、 MySQL は root 以外のユーザーで起動できます。データベースディレクトリがサーバーを起動したユーザに対して読み書きが許可されていれば良いのです。 MySQL を一般ユーザーで走らせる方法は Changing MySQL user.

     もし mysql_install_db で問題が出たら、 mysql_install_db. を参照のこと。

     mysql_install_db スクリプトを走らせるにはいくつか選択があります：

       * mysql_install_db を走らせる前に編集して、許可の初期状態を変更してもいいでしょう。これは多くのマシンに同じ権限設定をして MySQL をインストールする際に役立ちます。 この場合、いくつかの INSERT 構文を mysql.user と mysql.db テーブルにたいして追加するようにするだけですみます!

       * もしインストール後に許可を変更したい場合、 mysql -u root mysql で MySQL root ユーザーで接続して直接許可テーブルを変更する SQL 文を実行します。

       * すでに許可テーブルが作成された状態で、完全に許可テーブルを作成し直すことができます。これはすでにインストールされたテーブルがある場合や、mysql_install_db を編集した後にそう思うかもしれません。

     これらの選択については Default privileges からさらに情報が得られます。

 2. MySQL サーバーを以下のようにして起動します：

          shell> cd mysql_installation_directory
          shell> bin/safe_mysqld &

     サーバの起動に問題があれば、Starting server を見てください。

 3. mysqladmin でサーバーが走っているか確認します。サーバーが立ち上がり接続を受け付けるか確認する簡単な方法を以下に示します：

          shell> BINDIR/mysqladmin version
          shell> BINDIR/mysqladmin variables

     例えば、mysqladmin version の出力はあなたのプラットフォームと MySQL のバージョンを出力します。出力は以下の様にでます：

          shell> BINDIR/mysqladmin version
          mysqladmin  Ver 6.3 Distrib 3.22.9-beta, for pc-linux-gnu on i686
          TCX Datakonsult AB, by Monty

          Server version          3.22.9-beta
          Protocol version        10
          Connection              Localhost via UNIX socket
          TCP port                3306
          UNIX socket             /tmp/mysql.sock
          Uptime:                 16 sec

          Running threads: 1  Questions: 20  Reloads: 2  Open tables: 3

     BINDIR/mysqladmin の使用方法は、--help オプションで起動することにより得られます。

 4. サーバーをシャットダウンするには：

          shell> BINDIR/mysqladmin -u root shutdown

 5. サーバーをリスタートするには、safe_mysqld か mysqld を直接実行します。例えば：

          shell> BINDIR/safe_mysqld --log &

     safe_mysqld が失敗するなら、 MySQL のインストールディレクトリーから実行してみてください。もしそれでも起動しないなら、Starting server を参照のこと。

 6. いくつかの簡単なテストでサーバーが動いているか確認できます。以下のようになります：

          shell> BINDIR/mysqlshow
          +-----------+
          | Databases |
          +-----------+
          | mysql     |
          +-----------+

          shell> BINDIR/mysqlshow mysql
          Database: mysql
          +--------------+
          |    Tables    |
          +--------------+
          | columns_priv |
          | db           |
          | func         |
          | host         |
          | tables_priv  |
          | user         |
          +--------------+

          shell> BINDIR/mysql -e "select host,db,user from db" mysql
          +------+--------+------+
          | host | db     | user |
          +------+--------+------+
          | %    | test   |      |
          | %    | test_% |      |
          +------+--------+------+

     他のプラットフォームで MySQL のパフォーマンスを比較するために sql-bench にベンチマークがあります。 sql-bench/Results ディレクトリには、他のデータベースやプラットフォームでベンチを実行した結果があります。全てのテストを実行するには、以下のようにします：

          shell> cd sql-bench
          shell> run-all-tests

     RPM バイナリ配布には sql-bench ディレクトリがありません。 (RPM のソース配布には含まれます) この場合、ベンチマークをインストールしなくてはなりません。 MySQL 3.22 のバイナリ配布から、 mysql-bench-VERSION-i386.rpm という名前で RPM パッケージを作っており、これにはベンチマークのデータとコードが含まれます。

     tests サブディレクトリでテストすることも可能です。例えば、auto_increment.tst の実行は以下のようにします：

          shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tst

     これの結果は ./tests/auto_increment.res ファイルに書き出されます。

mysql_install_db 実行時の問題
-----------------------

この節では mysql_install_db を実行した際にでくわすかもしれない問題について述べます：

mysql_install_db doesn't install the privilege tables

     これは mysql_install_db が権限テーブルをインストールできなかった事のメッセージですが、続いて以下のようにメッセージが出た場合：

          starting mysqld daemon with databases from XXXXXX
          mysql daemon ended

     この場合、注意深く log ファイルを調べてください！エラーメッセージに出ている XXXXXX ディレクトリにログファイルがあり、これに mysqld がなぜスタートしなかったか記されているはずです。もし何が起こったかわからない場合、このログファイルを含んで mysqlbug を使用してバグレポートを投稿してください！ See Bug reports.

There is already a mysqld daemon running

     この場合、 mysql_install_db を実行する必要はありません。 mysql_install_db を実行するのは MySQL を初めてインストールした後、たった一回だけです。

Installing a second mysqld daemon doesn't work when one daemon is running

     これはすでに MySQL がインストールされており、しかし新しいインストールを違うところに行おうとした場合に発生します。 (例えば、一度に二つのインストールを実行した場合など) 一般にこの問題は二つ目のサーバーを動いているサーバーと同じポート、ソケットを使用して起動しようとした場合に発生します。この場合、Can't start server: Bind on TCP/IP port: Address already in use エラーメッセージか Can't start server : Bind on unix socket... エラーメッセージが出ます。新しいサーバーは以下のようにして違うポート、ソケットで起動できます：

          shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
          shell> MYSQL_TCP_PORT=3307
          shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
          shell> scripts/mysql_install_db
          shell> bin/safe_mysqld &

     The environment variables 付録は mysqld に影響する他の環境変数の一覧を含んでいます。See Environment variables。

     この後、二つのデーモンを違うポート、ソケットで実行するように、起動スクリプトを変更します。例えば、safe_mysqld  を二つ書きますが、--socket, --port と --basedir オプションをそれぞれの safe_mysqld に指定します。

/tmp に書き込み許可をあなたが持っていないなら

     もしソケットファイルを標準の場所(/tmp)に作成するための書き込み許可がないなら、あるいは、一時ファイルを /tmp に作成できないなら、 mysql_install_db の実行時、あるいは mysqld の起動／使用時にエラーとなるでしょう。

     違うディレクトリーにソケットファイルや一時ファイルを指定するには：

          shell> TMPDIR=/some_tmp_dir/
          shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysqld.sock
          shell> export TMPDIR MYSQL_UNIX_PORT

     some_tmp_dir は書き込みが可能なディレクトリーを指定しなくてはなりません。 See Environment variables.

     この後、mysql_install_db を走らせ、サーバーを起動する事ができます：

          shell> scripts/mysql_install_db
          shell> BINDIR/safe_mysqld &

mysqld crashes at once

     もし RedHat 5.0 上で 2.0.7-5 より古い glibc を使用している場合、全ての glibc パッチを当てなくてはなりません！これに関しては MySQL メールのアーカイブに情報が多くあります。メーリングリストのアーカイブのリンクは MySQL documentation page (http://www.mysql.com/doc.html). see Linux.

     mysqld を --skip-grant-tables 指定で起動することもできます。そして以下のように mysql を使用して自分自身の手により許可を加えます：

          shell> BINDIR/safe_mysqld --skip-grant-tables &
          shell> BINDIR/mysql -u root mysql

     mysql から手動で mysql_install_db に書かれている SQL コマンドを実行します。許可テーブルをサーバーに読み込ますためには、 mysqladmin flush-privileges か mysqladmin reload を実行します。

MySQL サーバー起動時の問題
----------------

通常 mysqld サーバーの起動は、以下の三つの方法のうち一つで行います：

  * mysql.server による起動。このスクリプトはシステムの起動時、停止時に使われます。詳細は Automatic start

  * safe_mysqld による起動。これは mysqld への適切なオプションを決定し、それらのオプションでサーバーの起動を試みます。

  * NT 上では mysqld を次のようにサービスとしてインストールすべきです:

          bin\mysqld-nt --install               # Install MySQL as a service

     すると、次のように mysqld を起動/停止できます:

          NET START mysql
          NET STOP mysql

     注意: この場合 mysqld に対して他のオプションは使用できません！

     次のようにしてサービスを削除できます:

          bin\mysqld-nt --remove                # remove MySQL as a service

  * mysqld を直接起動。

どの方法でサーバーを起動しても、もし起動に失敗すれば、ログファイルを確認してください。なぜ失敗したか記録されています。ログファイルはデータベースディレクトリにあります。 (バイナリ配布の場合 /usr/local/mysql/data 、ソース配布の場合 /usr/local/var、 Windows では \mysql\mysql.err ) データベースディレクトリに host_name.err と host_name.log というファイル (host_name はあなたのサーバー名) を探してください。以下のようにしてそのファイルの最後の数行を確認します：

     shell> tail host_name.err
     shell> tail host_name.log

mysqld デーモンの起動時に、デーモンはデータディレクトリにディレクトリを変えます。ログファイルと pid (process ID) ファイルがこのディレクトリに書ける事、そしてデータベースがこのディレクトリにある事を、デーモンは要求します。

データディレクトリの場所は配布物のコンパイル時に指定されています。 mysqld があなたのシステム上にデータベースディレクトリを見つけれなかった場合、サーバーは動きません。 mysqld を --help オプションで起動すれば mysqld のデフォルトのパスを知ることができますので、サーバーが起動しない理由が違うパスを使用しているために起こっているかどうかがわかります。パスが違う場合、mysqld のコマンドラインの引数に正しいパスを指定して、デフォルト値を上書きすることが可能です。(これらオプションは safe_mysqld にも同様に使用できます)

通常、MySQL がインストールされたディレクトリのベースディレクトリだけを mysqld に教えればいいはずです。これは --basedir オプションを指定します。 --help オプションを使用すればパスの変更が確認できます。 (--help は必ず 最後に指定のこと) 　例えば：

     shell> EXECDIR/mysqld --basedir=/usr/local --help

パスの設定が思い通りに言ったことを確認したら、 --help オプションを外してサーバーを起動します。

以下のエラーの場合、他のプログラム（か他の mysqld サーバー）が mysqld が使用しようとしている TCP/IP ソケットを使っています：

     Can't start server: Bind on TCP/IP port: Address already in use
       or
     Can't start server : Bind on unix socket...

他の mysqld サーバーが走っていないかを ps で確認します。もし他のサーバーが起動していないなら、 telnet your-host-name tcp-ip-port-number コマンドを実行し、何回か RETURN キーをたたいてみてください。もし、 telnet: Unable to connect to remote host: Connection refused のようなエラーが出た場合、なにかが mysqld が使用しようとしているポートを既に使っています。 See mysql_install_db, and Multiple servers.

safe_mysqld スクリプトは、ソース配布からでもバイナリ配布の MySQL からでも、たとえ違う場所にインストールされていても、サーバーを起動できるように作られています。 safe_mysqld は以下のどれか一つが真であることを期待します：

  * safe_mysqld が起動されたカレントディレクトリからの相対パスに、サーバーとデータベースがある場合。 safe_mysqld は ./bin, ./data ディレクトリ(バイナリ配布物の場合)、あるいは ./libexec, ./var ディレクトリ(ソース配布物の場合)を探します。あなたが MySQL をインストールしたディレクトリ(例えば /usr/local/mysql ディレクトリ) から safe_mysqld を実行した場合、この条件に適合します。

  * サーバーとデータベースが相対パス以下にない場合、safe_mysqld は絶対パスでそれらを探します。典型的なディレクトリは /usr/local/libexec と /usr/local/var です。実際のディレクトリは safe_mysqld がある配布物が作成されるときに決められます。これらは MySQL がインストールされた標準のパスに正しく配置されていなければなりません。

safe_mysqld はサーバーとデータベースを自分が起動されたディレクトリからの相対パスで探します。よって、 safe_mysqld を MySQL のインストールディレクトリから起動する限りは、 MySQL バイナリ配布物を自分の好きなところにインストールできます。その場合の起動は：

     shell> cd mysql_installation_directory
     shell> bin/safe_mysqld &

もし safe_mysqld が MySQL インストールディレクトリから起動しても失敗するなら、 safe_mysqld をあなたのシステム用に mysqld のパスやパス名のオプションを書き換えてもかまいません。この場合、 MySQL をアップグレードした場合、あなたが変更した safe_mysqld は上書きされるので、変更したものはインストール前にコピーしておき、再び戻さなくてはなりません。

もし mysqld がすでに走っている場合、以下のコマンドにてパスの設定を知ることができます：

     shell> mysqladmin variables

     or

     shell> mysqladmin -h 'your-host-name' variables

もし safe_mysqld がサーバーを起動しても接続できないようなら、 /etc/hosts ファイルに以下のような記述を持たせてください：

     127.0.0.1       localhost

この問題はスレッドライブラリーがなくて MySQL を MIT-pthreads を使用するようにして作ったシステムにだけ起こります。

Windows では、次のようにして mysqld の起動を試みることができます:

     C:\mysql\bin\mysqld --standalone --debug

これは、バックグランドで動作せず、\mysqld.traec にトレースを書き出します。これは問題の原因を解決する手助けになります。See Win32。

MySQL の自動起動と自動停止
----------------

mysql.server スクリプトは start, stop 引数を指定することによりサーバーを起動、停止できます：

     shell> mysql.server start
     shell> mysql.server stop

mysql.server は MySQL インストールディレクトリの share/mysql ディレクトリ、または MySQL ソースツリーの support-files ディレクトリにあります。

mysql.server はサーバーを起動時する前に MySQL がインストールされたディレクトリにディレクトリを変え、safe_mysqld を起動します。もし標準以外にインストールしているバイナリ配布を使用しているなら、 mysql.server を編集する必要があるかもしれません。 safe_mysqld を起動する前に正しいディレクトリに cd するように変更します。 safe_mysqld に他のオプションを与えるように mysql.server を変えても構いません。他のユーザーで実行したい場合、mysql_daemon_user=root を変更しても構いません。 safe_mysqld に他のオプションを与えるために、 mysql.server を変更しても構いません。

mysql.server stop はサーバーにシグナルを送ってサーバーを停止します。 mysqladmin shutdown で手動でサーバーを落とすこともできます。

MySQL を使用している製品のために、これらスタート、ストップを /etc/rc* に書きたいと思われるかもしれません。ここでの注意点は、変更した mysql.server は、 MySQL をアップグレードしたときに上書きされるということです。よって、変更したものはインストール前にコピーを取っておくべきです。

もしあなたのシステムが /etc/rc.local を起動スクリプトとして使用しているなら、以下のようにその中に記述します：

     /bin/sh -c 'cd /usr/local/mysql ; ./bin/safe_mysqld &'

グローバル設定ファイルである /etc/my.cnf に、 mysql.server のオプションを記述することも可能です。/etc/my.cnf ファイルは以下のような記述になっています：

     [mysqld]
     datadir=/usr/local/mysql/var
     socket=/tmp/mysqld.sock
     port=3306

     [mysql.server]
     user=mysql
     basedir=/usr/local/mysql

mysql.server スクリプトは以下の変数を使用します： user, datadir, basedir, bindir そして pid-file.

See Option files.

オプションファイル ( my.cnf )
--------------------

MySQL 3.22 のサーバー、クライアントともに、オプションファイルからデフォルトの起動オプションを読み込むことができます。

UNIX では MySQL は以下のファイルからデフォルトオプションを読みます：

ファイル名   意味
/etc/my.cnf   全体のオプション
DATADIR/my.cnf   サーバ固有オプション
~/.my.cnf   ユーザ固有オプション

DATADIR は MySQL データディレクトリです (普通 /usr/local/mysql/data or /usr/local/var). このディレクトリはconfigure時に決定されており、 --datadir を mysqld 起動時に指定しても変更されません。 (サーバーはコマンドラインの引数を処理する前にオプションファイルを探します。よって、--datadir 引数を指定してもオプションファイルを探す場所を指定することにはなりません。)

Win32 では MySQL は以下のファイルからデフォルトオプションを読みます：

ファイル名   意味
windows-system-directory\my.ini
C:\my.cnf   全体のオプション
C:\mysql\data\my.cnf   サーバ固有オプション

注意: Win32 では \ の代わりに / で全てのパスを記述すべきです。\ を使用する場合、\ は MySQL のエスケープ文字なので、これを二重に記述する必要があります。

MySQL は上記の表にかかれている順にオプションファイルを読みます。もし複数オプションファイルがあった場合、後から読まれた設定が有効になります。全てのオプションはコマンドラインの引数に上書きされます。いくつかのオプションは環境変数に定義できます。オプションファイルとコマンドラインの引数は環境変数を上書きします。

以下のプログラムはオプションファイルをサポートします：mysql, mysqladmin, mysqld, mysqldump, mysqlimport, myisamchk and myisampack.

オプションファイルには、プログラムがサポートしているコマンドラインの long オプション(例えば、-u ではなくて --user の方)を書くことができます。プログラムを --help で起動すれば、設定可能な変数名が得られます。

オプションファイルの書式は以下です：

#comment
     コメントは # か ; 文字で始めます。空の行は無視します。

[group]
     グループ宣言。 group はオプションを定義するプログラムかグループの名前です。この宣言の後、オプション か set-variable 行で、このグループにオプションを与えます。このセクションの範囲は、他のグループ宣言の行が来るか、ファイルの最後に来るまでです。

option
     これはコマンドラインの --option と等価です。

option=value
     これはコマンドラインの --option=value と等価です。

set-variable = variable=value
     これはコマンドラインの --set-variable variable=value と等価です。これは mysqld 変数で使用される形式です。

client グループは、全ての MySQL クライアント(mysqldは除)に対してオプションを定義します。これはサーバーに接続する際に使用するパスワードを指定できるグループです。 (この場合、オプションファイルは自分だけが読み書きできるようにしてください)

オプションや値の善後にある全てのブランク文字は自動で取り除かれます。値として、\b,\t, \n, \r, \\ and \s のエスケープシーケンスが使用できます。 (\s == blank).

オプションファイル例：

     [client]
     port=3306
     socket=/tmp/mysql.sock

     [mysqld]
     port=3306
     socket=/tmp/mysql.sock
     set-variable = key_buffer_size=16M
     set-variable = max_allowed_packet=1M

     [mysqldump]
     quick

ユーザーオプションファイル例：

     [client]
     # The following password will be sent to all standard MySQL clients
     password=my_password

     [mysql]
     no-auto-rehash

もしソース配布を持っているなら、 my-xxxx.cnf という名前のサンプルファイルを support-files ディレクトリに見ることができます。もしバイナリ配布を使用しているなら、 DIR/share/mysql ディレクトリを探してください (ここで DIR は MySQL がインストールされたディレクトリのパス名で、普通は /usr/local/mysql)。この my-xxxx.cnf ファイルを自分のディレクトリに .my.cnf という名前でコピーして使用できます。

MySQL プログラムにオプションファイルを読ませないようにするには、コマンドラインの一番最初に --no-defaults を書きます。これはオプションの最初でないと有効になりません！どのオプションが定義されているか確かめるには、--print-defaults を最初のオプションに指定します。

特定のコンフィグファイルを強制的に使用したい場合、オプション --defaults-file=デフォルトファイルのフルパス を使用できます。これを行なう場合、指定したファイルだけが読まれます。

開発者向け情報：　オプションファイルの操作は全てのオプションをコマンドラインの引数より先に処理するように簡単に埋め込まれています。これはオプションを最後に処理するプログラムを複数立ちあげる場合に都合よく動きます。もしオプションファイルを読み込む機能のない古いプログラムを使用しているなら、たった二行だけ注意して書けばいいだけです。この動作については MySQL クライアントプログラムのコードを参考にしてください。

MySQL のアップグレード/ダウングレード時に特別に行なうことが何かあるか？
=======================================

MySQL 形式とデータファイルは、MySQL が同じベースバージョンである限り、同じアーキテクチャ上の異なるバージョン間でいつでも移動できます。現在のベースバージョンは 3 です。MySQL の実行時に文字セットが変更された場合(これはソート順も変更します)、全てのテーブルに myisamchk -r -q を行なう必要があります。そうしなければ、インデックスが正しい順になりません。

もしあなたが神経質だったり新しいバージョンを恐れている場合、いつでもあなたの古い mysqld を mysqld-'old-version-number' のような何かにリネームできます。もし新しい mysqld が予期せぬ何かを行った場合、単純にそれをシャットダウンし、古い mysqld を再起動することができます！

アップグレード時には、もちろん、古いデータベースをバックアップもしておくべきです。時々は少し神経質になるのは良いことです！

アップグレード後、再コンパイルされたクライアントプログラムで、 Commands out sync や予期せぬコアダンプのような問題が起きる場合、おそらく、プログラムのコンパイル時に古いヘッダやライブラリファイルを使用したのでしょう。この場合、mysql.h ファイルと libmysql.a ライブラリが、新しい MySQL 配布からのものであるかどうかを確かめるために、日付をチェックすべきです。もし違っていれば、プログラムを再コンパイルしてください！

もし新しい mysqld サーバーが起動できないとか、パスワード無しで接続できないとか、いくつかの問題が発生した場合、以前のインストールでできた古い my.cnf ファイルがあるかどうかを確認してください！ program-name --print-defaults で確認できます.  もしこの出力がプログラムの名称以外の物を返した場合、有効になっている my.cnf ファイルがあります！

新しいリリースの MySQL をインストールした場合に常に Msql-Mysql-modules を再構築、再インストールすることはいい考えです。すべての DBI スクリプトが MySQL のアップグレード後にコアダンプする兆候に気づいた場合は、特にそうしてください。

3.22 から 3.23 バージョンへのアップグレード
---------------------------

MySQL 3.23 は新しい MyISAM 型のテーブルと、古い ISAM 型のテーブルをサポートします。 3.23 を使用する際、古いテーブル(ISAM) を変換する必要はありません。デフォルトでは、新しく作られるテーブルが MyISAM 型になります。 (これは mysqld を --default-table-type=isam オプションで起動することにより、変更できます)。 ISAM テーブルを MyISAM に変更するには、 ALTER TABLE を使用するか、mysql_convert_table_format perl スクリプトを使用します。

3.22 と 3.21 のクライアントは問題なく 3.23 サーバーで動作します。

以下に、3.23 にアップグレードするときに、注目する必要があるものを列挙します：

  * IF のデフォルトの戻り値型は現在両方の引数に依存します。最初の引数だけではありません。

  * AUTO_INCREMENT 負数では働きません。

  * INNER と DELAYED は、予約語になりました。

  * FLOAT(X) は本当の浮動小数点型になりました。桁数固定の値ではありません。

  * DECIMAL(length,dec) 宣言時、length 引数はもはや符号や小数点の場所を含みません。

  * TIME 文字列は以下のフォーマットのいずれかでなければなりません： [[[DAYS] [H]H:]MM:]SS[.fraction] か [[[[[H]H]H]H]MM]SS[.fraction]

  * LIKE は、同一文字の比較 '=' ルールを使用して、比較を行うようになりました。もし古い比較方法にするならば、 MySQL を CXXFLAGS=-DLIKE_CMP_TOUPPER フラグでコンパイルします。

  * REGEXP は、通常の文字列(非 binary) では、ケース非依存になりました。

  * MyISAM テーブル(.MYI) の検査・修復には、CHECK TABLE を使用するか、myisamchk を使用します。 isamchk は ISAM(.ISM) テーブル用に使用します。.

  * もし、3.22 と 3.23 の間で互換性を持たせて  mysqldump を行いたいならば、 --opt や --full オプションを mysqldump に指定してはいけません。

  * 全ての DATE_FORMAT() をチェックしてください。各フォーマット文字の前には % 文字が必要になりました。 (MySQL 3.22 バージョン以降ではこの文法が許されます。)

  * mysql_fetch_fields_direct が関数になり (今まではマクロだったのが)、 MYSQL_FIELD 型ではなく MYSQL_FIELD ポインター型を返します。

  * mysql_num_fields() は、 MYSQL* object をもはや使うことができません。 (これは今、 MYSQL_RES* を引数に取る関数になりました)。代わりに、 mysql_field_count() を使用すべきです。

  * MySQL 3.22 では, SELECT DISTINCT ... の出力はほとんどいつもソートされました。 3.23 では, ソートを行った結果を得るには GROUP BY か ORDER BY を使用しなくてはなりません。

  * もし、一致するレコードが無かった場合、SUM() は 0 の代わりに NULL を返すようになりました。これは ANSI SQL 準拠です。

  * 新しい予約語: CASE, THEN, WHEN, ELSE and END

  * NULL 値での AND や OR は現在 0 ではなく NULL を返します。 This mostly affects queries that uses NOT on an AND/OR expression as NOT NULL = NULL.

3.21 から 3.22 バージョンへのアップグレード
---------------------------

3.21 と 3.22 の間には互換性に影響する変更はありません。DATE 型を伴って生成された新しいテーブルは、日付の格納に新しい方法を使用することだけが pitfall です。これらの新しいフィールドに古いバージョンの mysqld からアクセスすることはできません。

MySQL 3.22 インストール後、新しいサーバを開始して、 mysql_fix_privilege_tables スクリプトを実行すべきです。これは GRANT コマンドを使用するために必要な権限を追加します。これを忘れると、ALTER TABLE や CREATE/DROP INDEX を使用しようとした時に Access denied になります。MySQL root ユーザがパスワードを要求する場合、mysql_fix_privilege_tables への引数としてそれを与えてください。

C API インタフェース mysql_real_connect() は変更されました。この関数を呼び出す古いクライアントプログラムを持っている場合は、新しい db 引数に 0 を置く(またはより速い接続のために db 要素を送るようにクライアントをコーディングしなおす)必要があります。 mysql_real_connect() を呼び出す前に mysql_init() を呼ばなくてはなりません！この変更は、MYSQL の構造体にオプションを保存するための新しい mysql_options() 関数を有効にします。

mysqld 変数 key_buffer は key_buffer_size に名前が変わりました。しかし、まだ前の名前もスターとアップファイル中で使用できます。

3.20 から 3.21 バージョンへのアップグレード
---------------------------

既に 3.20.28 より前のバージョンが稼働していて、3.21.x に変更したい場合は、次を行なう必要があります:

safe_mysqld --old-protocol で mysqld 3.21 サーバを起動すれば、3.20 配布からのクライアントでそれを使用できます。この場合、新しいクライアント関数 mysql_errno() はサーバのエラーは何も返さず、 CR_UNKNOWN_ERROR だけを返します (ただしクライアントのエラーについては働きます)。そして サーバは古い password() チェックを新しいものの代わりに使用します。

mysqld に --old-protocol オプションを使わない場合、次の変更をする必要があります:

  * 全てのクライアントコードは再コンパイルする必要があります。ODBC を使用している場合は新しい MyODBC 2.x ドライバを入手する必要があります。

  * mysql.user テーブル内の password フィールドを CHAR(16) に変換するために、スクリプト scripts/add_long_password を実行する必要があります。

  * 全てのパスワードは mysql.user テーブル内に再配置する必要があります(31ビットパスワードの代わりに、62ビットを得るために)。

  * テーブル形式は変更されていないので、どのテーブルも変換する必要はありません。

MySQL 3.20.28 とそれ以降は、クライアントに影響を及ぼさずに、新しい user テーブル形式を処理することができます。3.20.28 より前の MySQL バージョンを持っている場合は、user テーブルを変換すると、パスワードはその上ではもう働きません。安全のため、最初に少なくとも 3.20.28 にアップグレードし、それから 3.21.x にアップグレードすべきです。

新しいクライアントコードは 3.20.x mysqld サーバで動作するので、もし 3.21.x で問題があった場合は、クライアントをもう一度再コンパイルする必要はなく、古い 3.20.x サーバを使用することができます。

mysqld に --old-protocol オプションを使用しない場合、古いクライアントはエラーメッセージを発します:

     ERROR: Protocol mismatch. Server Version = 10 Client Version = 9

新しい Perl インタフェース DBI/DBD は古い mysqlperl インタフェースもサポートします。mysqlperl を使用する場合に行う必要のある変更は、connect() 関数の引数の変更だけです。新しい引数は: host, database, user, password (user と password 引数の順番が変更されました)。 See Perl DBI Class.

次の変更は古いアプリケーションでのクエリに影響します:

  * HAVING は現在 ORDER BY 節より前になければいけません。

  * LOCATE() へのパラメータは交換されました。

  * 新しい予約語がいくつかあります。最も注意すべきは DATE, TIME そして TIMESTAMP です。

他のアーキテクチャへのアップグレード
------------------

もし、MySQL 3.23 を使用しているならば、違うアーキテクチャのマシンに、.frm, .MYI,.MYD ファイルをコピーすることが出来ます。ただし、両者間で、同じ浮動小数点のフォーマットをサポートしている場合に限ります。 (MySQL takes care of any byte swapping issues).

現在 MySQL データとインデックスファイル (ISAM *.ISD と *.ISM ファイル) はアーキテクチャ依存で、いくつかのケースでは OS 依存です。アプリケーションを、現在のマシンとは異なるアーキテクチャ/OS を持つ他のマシンに移したい場合は、単純にファイルを他のマシンにコピーすることでデータベースを移行しようとすべきではありません。mysqldump を使用すべきです。

デフォルトでは mysqldump は、完全な SQL ステートメントファイルを生成します。それからそのファイルを他のマシンへ転送し、mysql クライアントへの入力として与えることができます。

有効なオプションが何かを見るためには、mysqldump --help を試してください。データを MySQL のより新しいバージョンに移す場合、速くコンパクトなダンプを得るために、より新しいバージョンで mysqldump --opt を使用すべきです。

２つのマシン間でデータベースを移動する最も簡単な (しかし最も速くはない) 方法は、データベースが置かれているマシン上で次のコマンドを実行することです:

     shell> mysqladmin -h 'other hostname' create db_name
     shell> mysqldump --opt db_name \
             | mysql -h 'other hostname' db_name

遅いネットワーク上でリモートマシンからデータベースをコピーしたい場合は、次を使用できます:

     shell> mysqladmin create db_name
     shell> mysqldump -h 'other hostname' --opt --compress db_name \
             | mysql db_name

ファイル内の結果を格納することもできます (この例では圧縮されています):

     shell> mysqldump --quick db_name | gzip > db_name.contents.gz

データベースの中身を含んでいるファイルを、目的のマシンに転送して、次のコマンドを実行してください:

     shell> mysqladmin create db_name
     shell> gunzip < db_name.contents.gz | mysql db_name

データベース転送を実行するために、mysqldump と mysqlimport も使用できます。大きなテーブルでは、これは単純な mysqldump の使用よりもとても速いです。次に示すコマンドでは、DUMPDIR は mysqldump からの出力を格納するために使用するディレクトリの完全なパス名を表わしています。

まず、出力ファイルのためのディレクトリを作成して、データベースをダンプします:

     shell> mkdir DUMPDIR
     shell> mysqldump --tab=DUMPDIR db_name

それから、DUMPDIR ディレクトリ内のファイルを目的のマシン上の対応するディレクトリに転送し、MySQL にファイルをロードします:

     shell> mysqladmin create db_name           # create database
     shell> cat DUMPDIR/*.sql | mysql db_name   # create tables in database
     shell> mysqlimport db_name DUMPDIR/*.txt   # load data into tables

mysql データベースのコピーも忘れないでください。それは承認テーブル (user, db, host) が格納されるためです。 mysql データベースをその場所に置くまで、新しいマシン上では MySQL root ユーザとしてコマンドを実行する必要があります。

新しいマシン上へ mysql データベースを導入した後、サーバが承認テーブル情報を再ロードするために、mysqladmin flush-privileges を実行してください。

MySQL はどのように標準互換か？
******************

MySQL の ANSI SQL92 に対する拡張
=========================

MySQL は、他の SQL データベース内に見られないであろう、いくつかの拡張を含んでいます。あなたがそれらを使用する場合、コードは他の SQL サーバに移行できなくなるので注意してください。いくつかのケースでは、形式 /*! ... */ のコメントを使用することで、MySQL 拡張を含む移行可能コードを書くことができます。この場合、MySQL はコメント内のコードを実行しますが、ほかのSQLサーバーはこれを無視します。例えば:

     SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...

'!' の後ろにバージョン番号を追加すると、文法は MySQL バージョンが使用されるバージョン番号と等しいか大きい場合にのみ実行されます:

     CREATE /*!32302 TEMPORARY */ TABLE (a int);

上記は 3.23.02 かそれ以上の場合という意味で、そのとき MySQL は TEMPORARY キーワードを使用します。

MySQL 拡張を以下に示します:

  * フィールド型 MEDIUMINT, SET, ENUM そして様々な BLOB と TEXT 型。

  * フィールド属性 AUTO_INCREMENT, BINARY, NULL, UNSIGNED そして ZEROFILL。

  * 全ての文字列比較はデフォルトではケース非依存で、現在の文字セット(デフォルトでは ISO-8859-1 Latin1)に従ったソート順です。これを好まない場合は、 BINARY 属性であなたのフィールドを宣言すべきです。これは、MySQL サーバホストの上で使用される ASCII 順に従って比較が実行されるようになります。

  * MySQL はデータベースをMySQL データディレクトリ以下のディレクトリに、テーブルをデータベースディレクトリ以下のファイル名にマップします。これは２つの関係を持ちます:

       - ケース依存のファイル名を持つ OS (UNIXのような)上の MySQL では、データベース名とテーブル名はケース依存です。テーブル名の記憶に問題がある場合、常にデータベースとテーブルを小文字で生成するという具合に、一貫して同じように命名するようにします。

       - テーブルのバックアップ, リネーム, 移動, 削除, コピーに標準システムコマンドを使用できます。例えば、テーブルをリネームするには、テーブルに対応する .MYD, .MYI, .frm ファイルをリネームしてください。

  * SQL 文では、 db_name.tbl_name 構文を使用して違うデータベースのテーブルにアクセスできます。いくつかのSQLサーバーは同様の機能を提供しますが、これを User space でコールします。 MySQL は以下のようなテーブルスペースをサポートしません: create table ralph.my_table...IN my_tablespace.

  * 数値フィールド上での LIKE が許されます。

  * SELECT ステートメント内の INTO OUTFILE と STRAIGHT_JOIN の使用。See SELECT.

  * どのようにテーブルが結合されるかの詳細を得るための EXPLAIN SELECT。

  * インデックス名、フィールドの一部のインデックス、そして CREATE TABLE ステートメント内の INDEX または KEY の使用。 See CREATE TABLE.

  * CREATE TABLE での TEMPORARY か IF NOT EXISTS の使用。

  * 'list' 要素が一つ以上の COUNT(DISTINCT list) の使用。

  * ALTER TABLE ステートメント内の CHANGE col_name, DROP col_name, DROP INDEX の使用。 See ALTER TABLE.

  * ALTER TABLE ステートメント内の IGNORE の使用。

  * ALTER TABLE ステートメント内の複数の ADD, ALTER, DROP, CHANGE 節の使用。

  * キーワード IF EXISTS 付きの DROP TABLE の使用。

  * 複数のテーブルを一回の DROP TABLE で破棄できる

  * DELETE ステートメントの LIMIT 節。

  * INSERT と REPLACE ステートメントの DELAYED 節。

  * INSERT, REPLACE, DELETE, UPDATE ステートメントの LOW_PRIORITY 節。

  * LOAD DATA INFILE の使用。多くの場合、この構文は ORACLE の LOAD DATA INFILE と互換があります。See LOAD DATA.

  * OPTIMIZE TABLE ステートメント。 See OPTIMIZE TABLE.

  * SHOW ステートメント。 See SHOW.

  * ' だけでなく " または ' によって文字列を括ることが可能。

  * エスケープ \ 文字の使用。

  * SET OPTION ステートメント。See SET OPTION.

  * GROUP BY 部に全てのフィールドを持つ必要はありません。 This gives better performance for some very specific, but quite normal queries. See Group by functions.

  * 異なる SQL 環境から来たユーザに対し、より簡単にするため、MySQL は多くの関数に別名をサポートしています。例えば、全ての文字列関数は ANSI SQL と ODBC 構文の両方をサポートします。

  * MySQL は || と && 演算子を、C プログラミング言語
     のように、論理和と論理積を意味すると理解します。MySQL では
     || と OR、&& と AND は同義語です。この良い構
     文のため、MySQL は ANSI SQL の文字列結合演算子 || をサポー
     トしません。CONCAT() を代わりに使用してください。CONCAT()
     は任意の数の引数を使用できるので、|| 演算子の使用を
     MySQL に変換するのは簡単です。

  * CREATE DATABASE または DROP DATABASE. See CREATE DATABASE.

  * MOD() と同義の %。 N % M は MOD(N,M) と等価です。 % は C プログラマーと PostgreSQL との互換のためにサポートされます。

  * フィールドステートメントでの =, <>, <= ,<, >=, >, <<, >>, <=>, AND, OR, LIKE。例えば：

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

  * LAST_INSERT_ID() 関数。 See mysql_insert_id().

  * REGEXP または NOT REGEXP。

  * 1つまたは2以上の引数での CONCAT() または CHAR()。 MySQL では、これらの関数は任意の数の引数を取ることができます。

  * BIT_COUNT(), CASE, ELT(), FROM_DAYS(), FORMAT(), IF(), PASSWORD(), ENCRYPT(), md5(), ENCODE(), DECODE(), PERIOD_ADD(), PERIOD_DIFF(), TO_DAYS(), WEEKDAY() 関数。

  * サブ文字列の整形のために TRIM() を使用できます。ANSI SQL は一文字の削除だけをサポートします。

  * GROUP BY 関数 STD(), BIT_OR() そして BIT_AND()。

  * DELETE + INSERT の代わりの REPLACE の使用。 See REPLACE.

  * FLUSH flush_option 構文。

  * := でステートメント内での変数の設定が可能:

          SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg FROM test_table;
          SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;

ANSI モードでの MySQL の実行
====================

--ansi オプションつきで mysqld を開始すると、その MySQL の振舞いが変わります。

  * || は OR ではなく文字列結合です。

  * 関数名と '(' の間に任意の数のスペースを置くことができます。これはすべての関数を予約語にします。

  * " は(MySQL ` 引用文字に似た)識別子引用文字になり、文字列引用文字ではありません。

  * REAL は DOUBLE の同義語ではなく FLOAT の同義語になります。

MySQL と ANSI SQL92 との違い
=======================

我々は MySQL を ANSI SQL 標準と ODBC SQL 標準に従うように試みていますが、いくつかのケースで MySQL は何か違いがあります:

  * -- は空白が続く場合だけコメントになります。See Missing comments。

  * VARCHAR フィールドでは、値が格納される時に末尾の空白が削除されます。 See Bugs。

  * いくつかのケースで、CHAR フィールドは黙って VARCHAR フィールドに変更されます。See Silent column changes。

  * テーブルを削除する時に、テーブルについての権限は自動的には破棄されません。テーブルについての権限を破棄するには、明示的に REVOKE を発行する必要があります。See GRANT.

  * NULL AND FALSE は FALSE ではなく NULL と評価されます。このケースで、多くの余計な条件を評価する必要があることは良いことではないと、我々は考えているからです。

MySQL に無い機能
===========

次の機能が MySQL の現在のバージョンにはありません。新しい拡張の優先度については、次を参考にしてください the MySQL TODO list (http://www.mysql.com/Manual_chapter/manual_Todo.html)。これはこのマニュアル中の TODO リストの最新バージョンです。See TODO。

Sub-selects
-----------

次は MySQL ではまだ働きません:

     SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);

しかし多くの場合、sub select を使わないクエリに書き直すことができます:

     SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
     SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id IS NULL

さらに複雑なサブクエリでは、サブクエリを保持するために一時テーブルを作成できます。しかし、この方法でも動かない場合があります。このケースには、 DELETE ステートメントでもっとも頻繁に遭遇します。DELETE ステートメントでは、標準 SQL では（sub select の中を除いて）join をサポートしていません。サブクエリが MySQL にサポートされるまで、この状況には２つの選択肢があります。

最初の選択肢は、手続きプログラミング言語（Perl や PHP のような）を使用して、 SELECT クエリを発行して削除されるレコードのプライマリキーを獲得し、それから DELETE ステートメント（DELETE FROM ... WHERE ... IN (key1, key2, ...)）を構築するためにその値を使用することです。

二番目の選択肢は、対話型 SQL を使用し、DELETE ステートメントのセットを（標準 || オペレータの代わりに）MySQL 拡張 CONCAT() を使用して、自動的に組み立てることです。例えば:

     SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', tab1.pkid, ';')
       FROM tab1, tab2
      WHERE tab1.col1 = tab2.col2;

このクエリをスクリプトファイル中に置き、入力を mysql コマンドラインインタプリタに切替え、その出力を二番目のインタプリタインスタンスにパイプします:

     prompt> mysql --skip-column-names mydb < myscript.sql | mysql mydb

MySQL は INSERT ... SELECT ... と REPLACE ... SELECT ... だけをサポートします。独立した sub-selects はおそらく 3.24.0 で有効になります。しかし今は他の文脈内で関数 IN() を使用できます。

SELECT INTO TABLE
-----------------

MySQL はまだ Oracle SQL extension: SELECT ... INTO TABLE ... をサポートしません。 MySQL は INSERT INTO ... SELECT ... をサポートします。これは基本的に同じことです。

代わりに、INSERT INTO ... SELECT ... や CREATE TABLE ... SELECT が使用できます。 See INSERT.

トランザクション
--------

MySQL は現在トランザクションをサポートするため、次の議論は非トランザクション安全テーブル型を使用する場合にだけ有効です。See COMMIT。

``なぜ MySQL はトランザクションのデータベースでないのか？'' とか ``なぜ MySQL はトランザクションをサポートしないのか？'' といった質問がしばしばなされます。

MySQL は、データの取り扱いに対し、他のパラダイム、 ``アトミック・オペレーション''をサポートする事を意図して決定しました。アトミック・オペレーションが同等かあるいはより良いパフォーマンスを提供するというのが、我々の経験、および考えです。それでも、我々はトランザクション的データベースパラダイムとプランを評価し、理解しています。次の数リリースのうちに、テーブル単位を基本に、トランザクション安全テーブルを導入します。その時我々は、ユーザーが、スピード重視でアトミック・オペレーションを使用するのか、あるいはアプリケーションでトランザクションの機能を使うのか、を、選択できるようにしようと考えています。

厳密に integrity 維持するには MySQL の機能をどのように使用するのでしょう？ そして、トランザクション的パラダイムでこれらの機能をどのように比較するのでしょう？

最初に、トランザクションのパラダイムでは、もし、あなたのアプリケーションが 基本となる部分で ``commit'' の代わりに ``rollback'' の呼び出しに依存しているなら、トランザクションはより便利になるでしょう。おまけに、トランザクションは完了できなかった更新や不整合を起こしたデータが、確実にデータベースに登録されないようにできます。そのサーバーには、自動的な rollback をする機会が与えられ、あなたのデータは守られるでしょう。

MySQL はほとんどの場合、更新前の簡単なチェックを含ませることができたり、あるいはデータベースの矛盾を検査して自動修復や警告の表示を行ったりする簡単なスクリプトを実行することができるような、ポテンシャルをあなたに提供します。 MySQL ログの使用や外部へのログの追加を行ったりする事で、通常、データに不整合のおきたテーブルを完全に修復できることに注意してください。

さらに、``fatal'' transactional updates はアトミックで書き換えることができます。実際、トランザクションが解決する全ての integrity problems は LOCK TABLES や  atomic updates で置き換えることが出来、さらにこれは、トランザクションのデータベースにある一般的な問題である、データベースからの自動的な中断を得ること無しに、可能なはずです。 In fact,we will go so far as to say that all integrity problems that transactions solve can be done with LOCK TABLES or atomic updates, ensuring that you never will get an automatic abort from the database, which is a common problem with transactional databases.

もしサーバーがダウンすればトランザクションでも全てを失うことを阻止できません。この場合、トランザクションのシステムでもデータを全て失うでしょう。 The difference between different systems lies in just how small the time-lap is where they could lose data. No system is 100% secure, only ``secure enough''. Even Oracle, reputed to be the safest of transactional databases, is reported to sometimes lose data in such situations.

MySQL を安全にするには、バックアップを取ることと、更新ログを有効にすることだけです。これで、あなたが他のトランザクションを持つデータベースで行っているようないかなる場面での修復が可能です。もちろん、バックアップをとることは、どのデータベースを使用しているかに関わらず、常に良いことです。

The transactional paradigm has its benefits and its drawbacks. Many users and application developers depend on the ease with which they can code around problems where an ``abort'' appears or is necessary, and they may have to do a little more work with MySQL to either think differently or write more. If you are new to the atomic operations paradigm, or more familiar or more comfortable with transactions, do not jump to the conclusion that MySQL has not addressed these issues. Reliability and integrity are foremost in our minds.  Recent estimates are that there are more than 1,000,000 mysqld servers currently running, many of which are in production environments.  We hear very, very seldom from our users that they have lost any data, and in almost all of those cases user error is involved. This is in our opinion the best proof of MySQL's stability and reliability.

Lastly, in situations where integrity is of highest importance, MySQL's current features allow for transaction-level or better reliability and integrity. If you lock tables with LOCK TABLES, all updates will stall until any integrity checks are made.  If you only obtain a read lock (as opposed to a write lock), then reads and inserts are still allowed to happen.  The new inserted records will not be seen by any of the clients that have a READ lock until they relaease their read locks.  With INSERT DELAYED you can queue insert into a local queue, until the locks are released, without having to have the client to wait for the insert to complete.

``Atomic'', in the sense that we mean it is nothing magical, it only means that you can be sure that while each specific update is running no other user can interfere with it and that there will never be an automatic rollback (which can happen on transaction based systems if you are not very careful).  MySQL also guarantees that there will not be any dirty reads.

We have thought quite a bit about integrity and performance and we believe that our atomic operations paradigm allows for both high reliability and extremely high performance, on the order of three to five times the speed of the fastest and most optimally tuned of transactional databases. We didn't leave out transactions because they are hard to do; The main reason we went with atomic operations as opposed to transactions is that by doing this we could apply many speed optimizations that would not otherwise have been possible.

Many of our users who have speed foremost in their minds are not at all concerned about transactions. For them transactions are not an issue. For those of our users who are concerned with or have wondered about transactions vis a vis MySQL, there is a ``MySQL way'' as we have outlined above. For those where safety is more important than speed, we recommend them to use the BDB tables for all their critical data. See BDB.

One final note: we are currently working on a safe replication schema that we believe to be better than any commercial replication system we know of. This system will work most reliably under the atomic operations, non-transactional, paradigm. Stay tuned.

ストアドプロシジャとトリガ
-------------

ストアドプロシジャは、サーバ内でコンパイルでき格納できる SQL コマンドのセットです。一度これが行なわれると、クライアントはクエリ全体の再発行を保持する必要がなく、ストアドプロシジャを参照できます。これはさらにより速い速度を提供します。クエリは一度だけ解釈され、より少ないデータがサーバとクライアント間で送信されるからです。サーバ内に関数ライブラリを持つことにより概念レベルを上げることもできます。

トリガは特別なイベントが発生した時に呼び出されるストアドプロシジャです。例えば、トランザクションテーブルからレコードが削除される度にトリガされ、トランザクションが削除された時に自動的に対応する顧客を顧客テーブルから削除するというストアドプロシジャをインストールすることができます。

計画されている言語の更新はストアドプロシジャを処理できるようになりますが、トリガは除きます。トリガは通常全てを、それらを必要としないクエリでさえも遅くします。

MySQL がストアドプロシジャを得る時を知るには、TODO を参照してください。

外部キー
----

注意: SQL の外部キーはテーブルを結合するためには使用できませんが、指示の完全性の検査のために良く使用されます。SELECT ステートメントで複数テーブルから結果を得たい場合、テーブルの結合によってこれを行ないます！

     SELECT * from table1,table2 where table1.id = table2.id;

See JOIN. See example-Foreign keys.

MySQL 内での FOREIGN KEY 構文は、他の SQL ベンダの CREATE TABLE コマンドとの互換のためだけに存在します; これは何も行ないません。ON DELETE ... がない FOREIGN KEY 構文は、目的の作成のために主に使われます。いくつかの ODBC アプリケーションは、自動的に WHERE 節を提供するために、これを使用しますが、しかしこれは通常簡単に無効にできます。FOREIGN KEY は時々強制チェックとして使用されます。しかし、テーブルに正しい順で行が挿入される場合、このチェックは実際には不要です。いくつかのアプリケーションがそれが存在することを要求するため MySQL はこれらの節だけをサポートします（それが動作するかどうかに関わらず！）。

MySQL では、外部キーを持つテーブルからレコードを削除する時に適切な DELETE ステートメントをアプリケーションに追加することで、 ON DELETE ... が実装されていないという問題を回避できます。実際には、これは速く(いくつかの場合はより速く)そして外部キーの使用よりもさらに可搬性があります。

近い将来、少なくとも情報が保存され、そして mysqldump と ODBC によって取り出されるように、我々は FOREIGN KEY 実装を拡張します。

外部キーを使用しない理由
............

我々がどこから始めるのかわからない FOREIGN KEY には多くの問題があります:

  * 外部キーは人生をとても複雑にします。外部キー定義はデータベースに格納しなければならず、それの実装は移動、コピー、削除できるファイルを使用するという ``良いアプローチ'' 全てを破棄するからです。

  * INSERT と UPDATE ステートメントへの速度の影響はものすごく、そしてこの場合、ほとんど全ての FOREIGN KEY チェックは役に立ちません。通常は、正しいテーブルに正しい順でレコードを挿入するためです。

  * 一つのテーブルの更新時にもっと多くのテーブル上でロックを保持する必要もあります。副作用がデータベース全体を通して発生するからです。まず一つのテーブルからレコードを削除して、それから他のテーブルからそれらを削除するほうがとても速いです。

  * テーブルから完全な削除を行なってから全てのレコードを（新しいソースやバックアップから）リストアすることによって、テーブルを復元することはもうできません。

  * 外部キーを持つ場合、テーブルのダンプとリストアは特定の順に行なわないとできません。

  * 一回の create ステートメントで各テーブルを再生成することをテーブルにできなくするような ``許された'' 巡回定義を行なうことはとても簡単です。その定義が動作して使用できたとしてもです。

外部キーの良い面は、ODBC と他のいくつかのクライアントプログラムに、どのようにテーブルが接続されるかを見る機能を与え、これを使用して接続図を示し、生成アプリケーションの手助けをすることだけです。

MySQL は間もなく、クライアントがどのようにオリジナル接続が作成されたかを問い合わせ、回答を受けられるように FOREIGN KEY 定義を格納します。現在の .frm ファイル形式にはそれを置く場所はありません。

ビュー
---

MySQL はビューをサポートしません。しかしこれは TODO にあります。

コメント開始としての --
-------------

他のいくつかの SQL データベースは、-- をコメントの開始のために使用します。MySQL は # をコメント開始文字とします。 mysql コマンドラインツールが -- で始まる全ての行を削除したとしてもです。MySQL では C コメントスタイル /* これはコメント */ も使用できます。See Comments。

MySQL 3.23.3 以上は -- をサポートしません; この退化したコメントスタイルは、次のコードのように !payment! の payment の値を自動的に挿入するような何かを使用して自動的に生成される SQL クエリで多くの問題を引き起こすためです:

     UPDATE tbl_name SET credit=credit-!payment!

payment の値が負の場合に何が起きると思いますか？

1--1 は正しい SQL なので、我々は -- をコメント開始と見なすことはひどいことだと思います。

しかし MySQL 3.23 では次を使用できます:  1-- これはコメント

以降の説明では、3.23 よりも前の MySQL バージョンを実行している場合だけが対象です:

テキストファイルの SQL プログラムが -- コメントを含んでいる場合、次を使用すべきです:

     shell> replace " --" " #" < text-file-with-funny-comments.sql \
              | mysql database

通常の次の代わりに:

     shell> mysql database < text-file-with-funny-comments.sql

次の方法でも、コマンドファイル中の -- コメントを # コメントに変更できます:

     shell> replace " --" " #" -- text-file-with-funny-comments.sql

それらは次のコマンドで戻してください:

     shell> replace " #" " --" -- text-file-with-funny-comments.sql

MySQL が準拠している標準
===============

Entry level SQL92. ODBC level 0-2.

COMMIT/ROLLBACK なしでうまくやる方法
==========================

The following mostly apply only for ISAM, MyISAM and HEAP tables; If you only use transaction safe tables (BDB tables) in an a update you can do COMMIT and ROLLBACK also with MySQL.  See COMMIT.

The problem with handling COMMIT-ROLLBACK efficiently with the above table types would require a completely different table layout than MySQL uses today. この型のテーブルは、自動的にテーブルをクリーンアップする拡張スレッドも必要とし、ディスク使用量はさらに大きくなります。 これは MySQL を現在よりも 2〜4 倍遅くしてしまいます。

今、我々は SQL サーバ言語(ストアドプロシジャのようなもの)の実装にさらに賛成です。これで、本当に COMMIT-ROLLBACK を必要とするのはめったにありません。これはさらに良い性能も与えるでしょう。

トランザクションを必要とするループは、通常は LOCK TABLES の助けでコード化でき、そして fly 上でレコードの更新時にはカーソルは必要としません。

我々 TcX で本当に必要としているのは、100% 標準のデータベースではなくて、本当に速いデータベースです。速度低下なしでそれらの機能を実装する方法を見つけたときには、我々はそれを行なうでしょう。しばらくは行なうべきさらに重要なことが多くあります。今の我々の優先度については TODO をチェックしてください。高レベルのサポートを持つ顧客はこれを変えることができ、再び優先順位づけが行なわれます。

現在の問題は実際には ROLLBACK です。ROLLBACK なしでも LOCK TABLES で COMMIT アクションのいくつかの種類を行なうことができます。ROLLBACK をサポートするためには、更新される全ての古いレコードを格納し、ROLLBACK が発行された場合に開始位置に全てを戻すように、MySQL を変更しなければなりません。単純な場合には、これを行なうには難しくありません(現在の isamlog をこの目的に使用します)。しかし、ALTER/DROP/CREATE TABLE での ROLLBACK の実装を行うことはとても困難です。

ROLLBACK の使用の回避のために、次の方法を使用することができます:

 1. LOCK TABLES ... をアクセスしたいテーブルの全てをロックするために使用します

 2. 条件のテスト。

 3. 全て OK なら更新。

 4. UNLOCK TABLES をロックの解除に使用します

これは普通は ROLLBACK 可能なトランザクションの使用よりも速いですが、常にではありません。この解が処理できない状況は、更新中に誰かがスレッドを kill する時だけです。この場合、全てのロックはリリースされますが、いくつかの更新は実行されません。

1回のオペレーション中でレコードを更新する関数も使用できます。次のテクニックによってとても効率的なアプリケーションを得ることができます。

  * フィールドを現在の値と比較して変更する

  * 実際に変更されたフィールドだけを更新する

例えば、いくつかの顧客情報で更新を行なっている時、我々は変更された顧客データだけを更新し、変更されていないデータはテストせず、変更されたデータに依存して変更されたデータがオリジナルの行と比較されます。変更のテストは UPDATE ステートメント内の WHERE 節で行われます。レコードが更新されなかった時は、我々はクライアントにメッセージ: "Some of the data you have changed has been changed by another user" を与え、そしてそれから古い行と新しい行をウィンドウ内で表示します。ユーザは顧客レコードのどちらのバージョンを使用すべきかを決定できます。

これは ``column locking'' に似たものを我々に与えますが、実際には十分です。なぜなら、我々はそれらの現在の値に関連した値を持つフィールドだけを更新するからです。これは、典型的な UPDATE ステートメントが次のように見えるということを意味します:

     UPDATE tablename SET pay_back=pay_back+'relative change';

     UPDATE customer
       SET
         customer_date='current_date',
         address='new address',
         phone='new phone',
         money_he_owes_us=money_he_owes_us+'new_money'
       WHERE
         customer_id=id AND address='old address' AND phone='old phone';

見ての通り、他のクライアントが pay_back または money_he_owes_us フィールドの値を変更したとしても、これはとても効率的で働きます。

多くの場合、ユーザは ROLLBACK そして/または LOCK TABLES がいくつかのテーブルでユニークな識別子を管理することを望みます。これは、 AUTO_INCREMENT フィールドと SQL LAST_INSERT_ID() 関数や C API 関数 mysql_insert_id の使用によって、さらに効率的に処理できます。 See mysql_insert_id().

TcX では、我々はいつでもそれを回避してコード可能なので、我々は行レベルロックを必要としていません。本当に行ロックを必要とするケースもありますが、しかしこれは非常にまれです。行レベルロックを望むのなら、テーブル内でフラグ項目を使用して、次のようにして行なえます:

     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 のユーザー権限はどのように動くか？
***********************

MySQL は先進的な非標準のセキュリティ/特権システムを持っています。本章ではどのようにそれが動くかを述べます。

セキュリティ概要
========

よくあるセキュリティの間違いを避けるために、インターネットに接続されたコンピュータ上で MySQL を使用する誰もが、このセクションを読むべきです。

``セキュリティ'' の議論では、すべての該当するアタックタイプ (eavesdropping, altering, playback, Denial of Service)に対して、すべてのサーバホスト(単なる MySQL サーバではなく)の完全な保護の必要を強調します。We do not cover all aspects of availability and fault tolerance here.

MySQL は、ユーザが実行しようとするすべての接続、クエリ、その他のオペレーションに対して、アクセス制御リスト(ACLs: Access Control Lists)セキュリティを使用します。MySQL クライアントとサーバの間で SSL 暗号化接続のサポートもいくつかあります。ここで議論されるコンセプトの多くは、 MySQL に特有のものではありません; 同じ一般的なアイデアはほとんどすべてのアプリケーションに適用します。

MySQL 実行時、可能な限りいつでもこれらのガイドラインに従ってください:

  * MySQL ACL システムの理解に努めるべきです。 GRANT と REVOKE コマンドは MySQL へのアクセスを制限するための物です。必要以上の権限を誰にも与えないでください。全てのホストに対して、何か出来るような許可を与えてはいけません。

     Checklist:

       * mysql -u root を行ってみます。

          パスワードを尋ねられること無しにサーバへの接続ができる場合、問題があります。どのユーザでも(root でなくても)、MySQL サーバに完全な権限で接続できます！ root パスワードの設定についての項目に特別な注意を払って MySQL インストール説明を見直してください。

       * SHOW GRANTS を使用し、だれがなんのアクセスを持つかチェックします。必要ない権限を、REVOKE コマンドを使用して削除してください。

  * いかなる平文パスワードもデータベースに保存しないようにします。あなたのコンピュータが妥協される時、新入者はパスワードの完全なリストを得て、それらを使用できます。代わりに MD5() や他の one-way hashing 関数を使用してください。

  * 辞書にのっている単語をパスワードに使用してはいけません。 それらを破るプログラムがあるのです。 ``xfish98'' のようなパスワードは悪い例です。これよりは ``duag98'' の方がよいでしょう。 これは "fish" を打つ際に、キーを一つずつずらしたものです。 他の方法としては、 "Mhall" 、これは "Mary had a little lamb" という文の頭文字を羅列したものです。これを知っている物には打ちやすいパスワードですが、知らない者にとっては、類推することが難しいパスワードです。

  * ファイアーウォールを導入します。This protects from at least 50% of all types of exploits in any software. MySQL をファイアーウォールで守られた方に置くか、 DMZ (緩衝地帯, 非武装地帯) に置きます。

     Checklist:

       * インターネットから nmap のようなツールを使用して、あなたのマシンのポートをスキャンしてみます。 MySQL はデフォルトで 3306 番を使用しています。このポートには、ほとんどの場合、アクセスできないようにすべきです。

          MySQL ポートがオープンしているかどうかをチェックする他の簡単な方法は、いくつかのリモートマシンから telnet server_host 3306 を実行することです。ここで server_host はあなたの MySQL サーバのホスト名です。接続し、いくつかのゴミ文字が得られた場合、ポートはオープンしています。それをオープンしておく正当な理由が本当にない限り、ファイアーウォールやルータでクローズすべきです。telnet がハングする場合、すべて OK です。ポートはブロックされています。

  * ユーザーから入力されたデータは信頼しないで下さい。ユーザーは、Webのフォーム、URL、あるいはあなたのカスタムプログラムから特定の文字を入れることが可能です。 もしユーザーがフォームに ; DROP ALL DATABASES ; のような文字を入力しても、あなたのアプリケーションは安全ですか？これは極端な例ですが、それらに対して準備しない場合、似たようなテクニックを使用するハッカーの結果として、大きなセキュリティリークとデータ喪失が発生し得ます。

     数値データのチェックも忘れないでください。よくある間違いは文字列しか保護しないことです。時々、人はデータベースが保護される必要のない公に有効なデータだけを含んでいるかどうかを考えます。これは間違いです。少なくとも、 Denial-of-Service タイプのアタックはそのようなデータベースでも実行されます。このタイプのアタックから保護するもっとも簡単な方法は、数値定数の回りにアポストロフィを使用することです: SELECT * FROM table WHERE ID=234 の代わりに SELECT * FROM table WHERE ID='234'。MySQL は自動的にこの文字列を数値に変換し、そこからすべての非数値シンボルを取り除きます。

     チェックリスト:

       * すべての WWW アプリケーション:

            * あなたの WWW の全てのフォームに、' と " を入力することを試みてください。もしなんらかの MySQL エラーがでたら、あなたのサイトを停止したほうがよいでしょう。

            * あなたの URL に %22 ("), %23 (#) , %27 (') をつけてみて、動的URLをいろいろ変更して試してみてください。

            * 動的 URL のデータタイプを数値から上述の例の文字を含む文字列に修正してみてください。アプリケーションはこれと似たようなアタックに対して安全であるべきです。

            * 数値フィールドに対して、文字、スペース、特殊文字の入力を試みてください。アプリケーションは、それらを MySQL に送る前に取り除くか、あるいはエラーを出すべきです。 検査しない値を MySQL に送ることは危険です。

            * MySQL にデータを送る前に、そのサイズをチェックします。

            * あなたのアプリケーションが、管理目的であなたが使用するのと異なるユーザ名を使用してデータベースに接続することを考慮してください。必要以上のアクセス権をアプリケーションに与えないで下さい。

       * PHP ユーザ:

            * addslashes() 関数を調べます。

       * MySQL C API ユーザ:

            * mysql_escape() API コールがあるか調べます.

       * MySQL++ ユーザ:

            * Check out the escape and quote modifiers for query streams.

       * Perl DBI ユーザ:

            * Check out the escape and quote modifiers (?) for query streams.

            * Check out the quote() method.

  * 生のデータ(暗号化されていないデータ)をインターネット越しに送ってはいけません。 This data is accessible to everyone who have interest to trap this information and reuse it somewhere. もし送る必要があるなら、SSL のような暗号化された通信を使用すべきです。 MySQL supports internal SSL connections beginning from version 3.23.9. SSH port-forwarding can be used to create an encrypted (and compressed) tunnel for the communication.

  * "tcpdump", "strings" ユーティリティを使うことを学んで下さい. 以下のコマンドで、ほとんどの場合、暗号化されていない MySQL のデータが見えるでしょう：

          shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings

     (この例は Linux のものです。他のシステムでは少し違うでしょう). Warning: If you do not see data this doesn't actually always mean that it is encrypted. If you need high security you should consult with security expert.

MySQL をクラッカーに対して安全にする方法
=======================

MySQL サーバーに接続するときは、パスワードを使用すべきです。パスワードはコネクション間で、べたテキストでは流れません。

その他の全ての情報はテキストで転送され、これは接続を覗くことが出来る人に読まれます。もしこれを心配するなら、圧縮プロトコル(MySQL 3.22 以上)を使用することが出来ます。より安全にしたい場合、 ssh (http://www.cs.hut.fi/ssh) をインストールすべきです。これを使用すれば、MySQL サーバーと MySQL クライアント間の TCP/IP コネクションは全て暗号化されます。

MySQL システムを安全にするためには、次のことを考えるべきです:

  * 全ての MySQL ユーザにパスワードを使用すべきです。 other_user にパスワードが設定されていない場合、誰でも mysql -u other_user db_name として簡単に他の人としてログインできることを覚えてください。これは全てのクライアント／サーバアプリケーションで一般的な振る舞いです。全てのユーザのパスワードは、 mysql_install_db スクリプトを実行前に編集することで、または MySQL root ユーザだけは次のようにして変更することができます。

          shell> mysql -u root mysql
          mysql> UPDATE user SET Password=PASSWORD('new_password')
                     WHERE user='root';

  * MySQL デーモンを Unix の root ユーザーで実行しないでください。 It is very dangerous as any user with FILE privileges will be able to create files as root (e.g. ~root/.bashrc). To prevent this mysqld will refuse to run as root unless it is specified directly via --user=root option.

     mysqld は任意のユーザで実行できます。より安全にするため、新しく Unix ユーザ mysql を追加することもできます。 mysqld を 他の Unix ユーザーで起動したとしても、 MySQL の user テーブルの root ユーザーの名前を変更する必要はありません。なぜなら、 MySQL ユーザーの名前は Unix のユーザー名とはなんの関係もないからです。 root ユーザ名を変更する必要はありません。 mysqld を他の Unix ユーザで起動するために、mysql.server 編集してもよいでしょう。通常、これは su コマンドで行われます。より詳しい情報は → Changing MySQL user.

  * mysql.server スクリプト内に Unix root ユーザーのためにパスワードを書いた場合、このスクリプトは root だけが読めるようにしなくてはなりません。

  * データベースディレクトリは mysqld を実行している Unix ユーザだけが読み込み／書き込み可能なことをチェックしてください。

  * On Unix platforms, do not run mysqld as root unless you really need to. Consider creating a user named mysql for that purpose.

  * process 権限を全てのユーザに与えないでください。この許可がある人は誰でも mysqladmin processlist コマンドで実行されているクエリーの中身を見ることができます。もし誰かが、UPDATE user SET password=PASSWORD('not_secure') クエリーを実行していたとして、それが見えてしまいます。

     mysqld は process 権限を持つユーザに対する特別な接続をリザーブします。そのため、たとえ全ての通常接続が使われたとしても、MySQL root ユーザだけは、ログインでき、いろいろチェックできます。

  * file を全てのユーザに与えないでください。ユーザがこの権限を持つ場合、mysqld デーモンを実行している Unix ユーザーの権限でファイルシステム内のどこにでもファイルを書き込むことができます！これを少し安全にするために、SELECT ... INTO OUTFILE で作成される全てのファイルは全員に読み込み可能で生成され、既存のファイルには上書きできません。

     file 権限はサーバーを走らせている UNIX ユーザーがアクセスできる全てのファイルを読むために使用されかもしれません。例えば、 /etc/passwd をテーブルに取り込むために LOAD DATA が使用されると、 SELECT でその内容が読めることになります。

  * あなたの DNS を信用しない場合、権限テーブル内にはホスト名の代わりに IP を使用すべきです。mysqld への --secure オプションは原理上はホスト名を安全にします。どんな場合でも、ワイルドカードを含んだホスト名を、許可テーブルに登録する事は本当に注意深くすべきです！

mysqld への次のオプションはセキュリティに影響します:

--secure
     gethostbyname() から返される ip がオリジナルのホスト名に戻せるかどうかをチェックします。これは、外の誰かが他のホストを真似てアクセスを得ることを難しくします。このオプションはいくつかの正しいホスト名チェックも追加します。これは、時にチェックに長い時間がかかるため、MySQL 3.21 ではデフォルトではオフにされています。MySQL 3.22 ではこのオプションはデフォルトで有効になっていますが、ホスト名をキャッシュするようになっています。

--skip-grant-tables
     特権システムを全く使用しません。これは全員に全てのデータベースへの完全なアクセス を与えます！ (mysqladmin flush-privileges か mysqladmin reload を実行することで、起動しているサーバーは特権システムを使用するようになります。)

--skip-name-resolve
     ホスト名を解析しません。権限テーブル中の全ての Hostフィールドは IP アドレスか localhost でなければなりません。

--skip-networking
     ネットワーク (TCP/IP) 経由の接続を許可しません。mysqld への全ての接続は、 Unix ソケットで行われます。MIT-pthreads は Unix ソケットをサポートしないため、このオプションは MIT-pthreads を使用するシステム上では、うまく動きません。

特権システムの行うこと
===========

MySQL 特権システムの基本機能は、与えられたホストから接続するユーザを認証すること、そしてデータベースに対する select, insert, update, delete 等の権限を与えることです。

拡張機能は匿名ユーザをもつ能力を含み、LOAD DATA INFILE のような MySQL 固有の機能を使用する許可を与えます。

MySQL ユーザ名とパスワード
================

MySQL によって使用されるユーザー名とパスワードの使用のされ方と、 UNIX, Windows で使用される方法とは、いくつか異なる点があります。

  * MySQL データベースのアクセス認証に使用するユーザー名は、 UNIX のログインユーザやWindowsのユーザー名で行うことはありません(一致していません)。利便性をはかるため、多くの MySQL クライアントは現在のログインしているユーザ名を MySQLのユーザー名としてログインを試みます。しかしこれは -u か --user スイッチで変更できます。これは、全てのユーザに対しパスワードを設定しておかないと、全くデータベースを安全にできないことを意味します。もしパスワードを全ユーザーに設定しておかないと、そのユーザー名で認証なしにサーバーに接続できます。

  * MySQL のユーザー名は 16文字まで(英数半角)使用できます。 UNIXはだいたい8文字ですが。(8文字をこえるシステムもある)

  * MySQL ユーザーのパスワードは、Unix のパスワードと違います。よって、それらのマシン上で Unix のログインパスワードとデータベースのパスワードは同じにする必要はありません。

  * MySQL は Unix のログインパスワードとは全く違う、独自の暗号化されたパスワードだけを使用します。 PASSWORD() と ENCRYPT() 関数の説明を参照 → Miscellaneous functions.

MySQL サーバーに接続
=============

MySQL クライアントプログラムは、共通の決まった引数を持ちます：接続したいホスト名、接続ユーザー名、そしてパスワードです。例えば、mysql コマンドは以下のような引数を持ちます (オプションの引数は [ と ] で囲まれている部分です)

     shell> mysql [-h host_name] [-u user_name] [-pyour_pass]

-h, -u, -p オプションは以下と等価です。 --host=host_name, --user=user_name, --password=your_pass -p とパスワードの間にはスペースがないことに注意

注意: コマンドラインにパスワードを与えるのは安全ではありません！システムに入っている如何なるユーザーも ps auxww のようなコマンドを使用する事でパスワードを見付ける事ができます see Option files.

mysql コマンドはコマンドラインに引数がなければ接続にデフォルト値を用います。

  * デフォルトのホスト名は localhost, ユーザー名は Unix のログイン名です。

  * (-p が指定されていなければパスワードは与えられません)

Unix のログインユーザーが joe の場合、以下のコマンドは等価です：

     shell> mysql -h localhost -u joe
     shell> mysql -h localhost
     shell> mysql -u joe
     shell> mysql

他の MySQL クライアントも同じように動作します。

Unix システムでは、ある値をデフォルト値にして接続に使用することができます。そうすることにそり、毎回毎回コマンドラインに引数を与えなくてすむようになります：

  * 自分のホームディレクトリに .my.cnf を作り、そのファイルの中の [client] セクションに接続用のパラメターを記述できます。その記述は以下のようです：

          [client]
          host=host_name
          user=user_name
          password=your_pass

     See Option files.

  * 接続のパラメターに環境変数を使用することもできます。ホスト名は MYSQL_HOST 環境変数を使用します。 MySQL のユーザー名は USER (これは Windows のみ) に設定された値を使用します。パスワードは MYSQL_PWD 環境変数を見ますが、これは危険です。(次の節参照) see Environment variables.

パスワードを安全にする
-----------

自分のパスワードを他人にさらけ出すのは勧められることではありません。それぞれの方法に於ける危険度に応じ、以下に示す方法でクライアントプログラムにあなたのパスワードをあたえて走らせることができます：

  * -pyour_pass か --password=your_pass オプションをコマンドラインで使用します。これは便利ですが安全ではありません。あなたのパスワードは (ps コマンドのような) システムの状態を見るコマンドにて見ることができます。 (MySQL クライアントは初期化過程においてコマンドラインの引数をゼロで上書きして見せないようにしているのですが、瞬間ですが値が見えてしまうのです)

  * -p あるいは --password オプションを your_pass を与えないで使用します。この場合、クライアントプログラムはターミナルを通じてパスワードの入力を促してきます:

          shell> mysql -u user_name -p
          Enter password: ********

     クライアントはあなたの入力したパスワードを * 文字で端末に返していますので、画面をのぞき込まれたとしてもパスワードはわかりません。

     これはコマンドラインにパスワードを指定するより安全です。他のユーザーには見えませんから。しかしこのパスワードを毎回入れる方法は対話式のプログラムを実行する場合だけに使用できる手です。もし非対話式のスクリプトからクライアントプログラムを起動したい場合、パスワードを端末から入れる機会がありません。 On some systems, you may even find that the first line of your script is read and interpreted (incorrectly) as your password!

  * 設定ファイルにパスワードを書いておくこともできます。例えば、自分のホームディレクトリーにある .my.cnf ファイルの [client] セクションに、以下のような形で書きます：

          [client]
          password=your_pass

     もし .my.cnf ファイルにパスワードを書いているなら、ファイルはグループやその他のユーザーが読み書きできないようにすべきです。ファイルのモードは 400 か 600 にします。

     See Option files.

  * MYSQL_PWD 環境変数にパスワードを設定することもできます。しかしこの方法はきわめて危険であるので、使用すべきではありません。 ps のあるバージョンでは、実行中のプロセスの環境変数を表示するオプションがあります；もし MYSQL_PWD 環境変数にパスワードを設定していると全てべたで見れます。このバージョンの ps を持っていないシステムだとしても、プロセスの環境変数を調べる方法がないとはいえないので、この方法はあまりいい方法ではありません。 See Environment variables.

まとめると、より安全な方法は、パスワードプロンプトを返すクライアントプログラムを実行するか、適切なパーミッションをかけた .my.cnf ファイルにパスワードを書くかです。

MySQL が提供する権限
=============

権限の設定は mysql データベースの user, db, host, tables_priv, columns_priv で行います。 (mysql はデータベースの名前です) MySQL サーバーは、サーバーの起動時か Privilege changes で説明されている方法により、これらのテーブルから権限の設定を読み込みます。

MySQL が提供する権限の名称は, 本マニュアルでは以下の表の名称を用います。この表の項目名がそれぞれの許可される権限とその説明に対応しています：

Privilege    Column         Context
select        Select_priv     tables
insert        Insert_priv     tables
update        Update_priv     tables
delete        Delete_priv     tables
index         Index_priv      tables
alter         Alter_priv      tables
create        Create_priv     databases, tables or indexes
drop          Drop_priv       databases or tables
grant         Grant_priv      databases or tables
references     References_priv   databases or tables
reload        Reload_priv     server administration
shutdown      Shutdown_priv   server administration
process       Process_priv    server administration
file          File_priv       file access on server

select, insert, update, delete の権限は、存在しているデータベースのテーブルに対して許可されます。

もしテーブルから行を取り出すだけなら、SELECT 構文を実行するためには select 権限だけあればかまいません。だけでなく、サーバーのどのデータベースにアクセスを許可されていない場合でも、ある種の SELECT は実行することができます。例えば、簡単な計算を mysql クライアントで行う場合です：

     mysql> SELECT 1+1;
     mysql> SELECT PI()*2;

index 権限はインデックスの作成と破棄(削除)を許可します。

alter 権限は ALTER TABLE の実行を許可します。

create と drop 権限は、新しいデータベースやテーブルの作成、あるいは既に存在するデータベース、テーブルの破棄(削除)を許可します。

注意： mysql データベースに登録されているユーザーに drop 権限を与えると、そのユーザーは MySQL のアクセス権限が格納されているデータベースを破棄できます！

grant 権限は、あなたが他のユーザーに対して自分の権限を持たせる事を許可します。

file の権限を与えると、LOAD DATA INFILE と SELECT ... INTO OUTFILE 構文を使用して、サーバーのファイルを読み書きする事ができます。 MySQL サーバーがが読み書きできるファイルに対して、この権限が与えられたユーザーはファイルを読み書きできます。

残りの権限はアドミン操作に関する許可で、mysqladmin コマンドを使用して実行します。次の表に mysqladmin コマンドのどれが、どの権限に対応しているかを示します：

Privilege    Commands permitted to privilege holders
reload       reload, refresh,
flush-privileges,
flush-hosts, flush-logs, flush-tables
shutdown     shutdown
process      processlist, kill

reload コマンドはサーバーに権限の設定を再読込させるように伝えます。 refresh コマンドは全てのテーブルをフラッシュし、ログファイルを開き直します。 flush-privileges は reload と同義です。その他の flush-* コマンドは refresh の動作とよく似ていますが、適用範囲を絞っており、ちょっとした場合に有効です。例えば、ログファイルだけをフラッシュしたい場合、 refresh を行うよりも flush-logs がいいです。

shutdown コマンドは、サーバーをシャットダウンします。

processlist コマンドはサーバーが実行しているスレッドの情報を表示します。 kill コマンドはサーバーのスレッドをkillします。自分のスレッドは常に表示、killできますが、他人のスレッドをそうするには process 権限が必要です。

ある権限を欲しがるユーザーだけにその権限を許可するのはよい考えですが、権限を与えるときには、特定の事項を熟知していなければなりません：

  * grant 権限を許可されたユーザーは、他のユーザーの権限を変える事ができます。二人のユーザー間で違っている権限と grant 権限を入れ換えることができます。

  * alter 権限は、テーブル名の変更を行うことにより特権システムを破るために使用されるかもしれません。

  * file 権限は、サーバー上にある全ての読み込み可能なファイルをデータベースに取り込むことができ、これは SELECT 文でアクセスできます。 This includes the contents of all databases hosted by the server!

  * shutdown 権限は、他のユーザーに対するサービスを、サーバーを停止することによって、拒否するようにできます。

  * process 権限は実行されているクエリーをプレーンテキストで見ることに使えます。パスワードの設定、変更のクエリーも含みます。

  * mysql データベースに対しての権限は、パスワードの変更と他の権限の設定を変更ができます。パスワードは暗号化されて登録されており、悪意のあるユーザーでも単純に読むことはできませんが、この権限を許可されたそのユーザーは、パスワードを違うものに変えることができます。

以下は MySQL の特権システムで行うものではありません：

  * アクセスを拒否するユーザーを特定して設定することはできません。完全に一致したユーザーからの接続を拒否できません。

  * データベース内のテーブルの作成、破棄の権限を持つが、データベースそのものを作成、破棄できる、そのようなユーザーを設定できません。

特権システムはどのように動くか？
================

MySQL の特権システムは、全てのユーザーが与えられた許可の範囲内で動く事を保証します。 MySQL サーバーに接続するとき、本人の身元は、接続元のホスト と接続に使用するユーザー名 によって確認されます。このシステムは、あなたの身元とあなたが要求することが何か によって、権限を与えます。

MySQL はあなたのホスト名とユーザー名の両方をあわせてチェックします。これはインターネット上に同じ名前のユーザーがどこかにいるかもしれないということからそうしています。例えば、whitehouse.gov から接続してきた bill と、 microsoft.com から接続してきた bill は同一人物である必要はありません。 MySQL はこの違うホストから接続してきた同名のユーザーを以下のようにして扱います： whitehouse.gov から接続した bill にある許可をあたえ、それとは違う許可を microsoft.com から接続してきた bill に与えます。

MySQL のアクセスコントロールは以下の二つからなります：

  * Stage 1: サーバーは接続許可があるかどうかをチェックします。

  * Stage 2: 接続許可後、サーバーはそれぞれのリクエストをチェックします。あなたが要求してきた事柄を、あなたが実行できるかどうかをチェックします。例えば、あるデータベースのテーブルの行の取り出しやテーブルの破棄をあなたが命令した場合、サーバーは、あなたにそのテーブルに対する select 許可があるのか、データベースに対して drop する許可が与えられているのか、を確認します。

サーバーは mysql データベースの user, db, host ３つのテーブルから、この２つのアクセス制限を決定します。このテーブルのフィールドは以下のようになっています：

Table name   user   db   host

Scope fields   Host            Host          Host
  User            Db            Db
  Password        User

Privilege fields   Select_priv   Select_priv   Select_priv
  Insert_priv     Insert_priv   Insert_priv
  Update_priv     Update_priv   Update_priv
  Delete_priv     Delete_priv   Delete_priv
  Index_priv      Index_priv    Index_priv
  Alter_priv      Alter_priv    Alter_priv
  Create_priv     Create_priv   Create_priv
  Drop_priv       Drop_priv     Drop_priv
  Grant_priv      Grant_priv    Grant_priv
  References_priv
  Reload_priv
  Shutdown_priv
  Process_priv
  File_priv

　アクセスコントロールの第2段階(要求承認)のために、サーバーはこれら 3 つのテーブルによって決められた許可を基本としますが、もしテーブルに対する要求であるならば、tables_priv と columns_priv テーブルをさらに調べます。これらのテーブルのフィールドは以下のようになっています：

Table name     tables_priv   columns_priv

Scope fields   Host          Host
  Db            Db
  User          User
  Table_name    Table_name
                       Column_name

Privilege fields   Table_priv     Type
  Column_priv

Other fields   Timestamp     Timestamp
  Grantor

　テーブルの各フィールドを分類すると、２種類にわかれます：適用範囲を指定するフィールド(以下　スコープフィールド)と許可を定義するフィールド(以下　権限フィールド)です。

　スコープフィールドは、権限テーブルの登録ごとに、その適用範囲を決めます。例えば、 user テーブルの Host と User に 'thomas.loc.gov' と 'bob' が登録されている場合、サーバーへの接続は ホスト thomas.loc.gov から来た 'bob' に許可されます。同様に、db テーブルの  Host, User, Db に 'thomas.loc.gov', 'bob', 'reports' が登録されていると、ホスト thomas.loc.gov から来た bob に対し reports データベースへの接続が許されます。 tables_priv と columns_priv テーブルは、テーブルか、テーブルとフィールドを対にしたスコープフィールドを含みます。

　アクセスのチェックは、Host の値はケース非依存で比較されます。 User, Password, Db, Table_name の値はケース依存で比較されます。 Column_name の値は MySQL 3.22.12 以上ではケース非依存で比較されます。 (3.22.11 までは ケース依存です)

権限フィールドは、テーブルに登録されることにより有効になった許可をしめし、これはどの操作が実行できるかを示します。サーバーは許可テーブルの情報をユーザーの権限を得るためにまとめます。このユーザーの権限許可を割り出す方法は Request access に述べておきます。

スコープフィールドは文字で定義され、デフォルト値は空文字になっています：

Field name   Type
Host           CHAR(60)
User           CHAR(16)
Password       CHAR(16)
Db             CHAR(64)   (CHAR(60) for the
tables_priv and columns_priv tables)
Table_name     CHAR(60)
Column_name    CHAR(60)

user, db, host テーブルでは、全ての権限フィールドは ENUM('N','Y') で定義されます。この値は 'N' か 'Y' のどちらかで、デフォルト値は 'N' です。

tables_priv と columns_priv テーブルでは、権限フィールドは SET フィールドとして定義されます：

Table name   Field name   Possible set elements
tables_priv   Table_priv   'Select', 'Insert',
'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'
tables_priv   Column_priv   'Select', 'Insert',
'Update', 'References'
columns_priv   column_priv   'Select', 'Insert',
'Update', 'References'

サーバーは以下のように許可テーブルを使用します：

  * user テーブルのスコープフィールドは、接続要求を受け入れるか拒否するかを決定します。 For allowed connections, any privileges granted in the user table indicate the user's global (superuser) privileges. These privileges apply to all databases on the server. (訳注：例えば、user テーブル の権限を 'Y' にした場合、どんなに Db や Host で 'N' にしたとしても 'Y' のままである。ようは user テーブルの権限許可 'Y' が全てに反映されてしまうという事。 user テーブルには最低限の許可を与えるようにし、 Db や Host ごとに、それぞれの権限許可を定義する方が無難。 )

  * db と host テーブルは一緒に使用されます：

       - db テーブルのスコープフィールドはどのホストからどのデータベースのアクセスできるかを決定します。権限フィールドは、どういった操作ができるか定義します。

       - host テーブルは、db テーブルの登録ににホストを与えた場合に、 db テーブルの拡張として使用されます。例えば、ネットワーク上の限定したマシンからデータベースを使用したい場合、 db テーブルの Host の値は空にしておきます。そして host テーブルにそれぞれのホストについての登録を行います。この機構は、 Request access で詳細に述べられています。

  * tables_priv と columns_priv テーブルは db テーブルに似ていますが、それらはより細かく定義できます；データベースレベルではなく、テーブルとフィールドのレベルで与えます。

管理者権限 (reload, shutdown,など) は user テーブルにだけ定義するように。これは、管理者操作はデータベースではなくサーバーへの操作であり、他の許可テーブルにある必要がないからです。またこうしておくと、管理者操作の許可は、user テーブルの定義だけを見ればわかるようになります。

file 操作の権限は user テーブルにだけ定義するように。これは管理者操作ではありませんが、アクセスしているデータベースにかかわらず、サーバー内のファイルを読み書きできるのです。

mysqld サーバーは起動時にこれらのテーブルを読み込みます。許可テーブルの変更を反映させる方法はこちらを参照のこと → Privilege changes

これらのテーブルの登録を変更した場合、思ったとおりの権限状態になっている事を確認することはいいことです。問題の解決には, Access denied.  セキュリティに関するアドバイスは Security.

便利なツールとして mysqlaccess スクリプト( Yves Carlier 作)が MySQL の配布に含まれています。 mysqlaccess を  --help オプションで起動するとヘルプが表示されます。 mysqlaccess は user,db and host テーブルだけしか検査しません。テーブルレベルの権限、フィールドレベルの権限は調べません。

Access control, stage 1: 接続の承認
==============================

MySQL サーバーに接続すると、あなたがパスワード認証して接続していようがいまいが、サーバーはあなたの身元により接続の許可拒否を行います。もし身元が一致しない場合接続を拒否し、接続許可した場合、サーバーは stage 2 へと進み、要求を待ちます。

身元は二つのものに基づいて確認されます：

  * あなたが接続しようとしているホスト

  * あなたの MySQL ユーザー名

身元の確認は user テーブルのスコープフィールド(Host, User, Password) を使用して行います。サーバーは user テーブルの登録に一致しているホスト名とユーザー名に限り接続を許可し、その後、パスワードを要求します。

user テーブルのスコープフィールドの登録は以下のようになります：

  * Host の値はホスト名か IP アドレスか 'localhost'(ローカルホスト) です。

  * Host にはワイルドカード文字 % と _ を使用できます。

  * Host に '%' を設定すると、全てのホストにマッチします。 Host を空にすると、'%' と同じになります。これらの値は、どんなホストもサーバーに接続できるということになります！

  * As of MySQL 3.23, for Host values specified as IP numbers, you can specify a netmask indicating how many address bits to use for the network number. For example:

          GRANT ALL PRIVILEGES on db.* to david192.58.197.0/255.255.255.0';

     This will allow everyone to connect from an IP where the following is true:

          user_ip & netmask = host_ip.

     In the above example all IP:s in the interval 192.58.197.0 - 192.58.197.255 can connect to the MySQL server.

  * ワイルドカード文字は User フィールドには設定できませんが、 User フィールドをブランク(空)にすることはできます。ブランクは全ての名前にマッチします。これはユーザー名がない状態で接続してきたものに適用され、クライアントがユーザー名を明記しない限り、匿名ユーザー(名前がブランク)として扱われます。全てのアクセスのチェックにブランクのユーザー名が使用される事を意味します。(that is, during stage 2)

  * Password フィールドは空にできます。その場合、パスワードなして接続できることになります。

非ブランクの Password 値はパスワードを暗号化したものです。 MySQL はだれもが見れるようにパスワードを平文では保存しません。接続を試みようとしているユーザーのパスワードも、(PASSWORD() 関数で) 暗号化され、user テーブルに保存されている暗号化パスワードと比較します。もし一致したなら、パスワードは正しいということです。

以下の表は、接続要求に対して与える、 user テーブルの Host と  User の設定例です：

Host value   User value   Connections matched by entry
'thomas.loc.gov'   'fred'   fred, thomas.loc.gov から接続
'thomas.loc.gov'   ''   thomas.loc.gov から接続してくる全てのユーザー
'%'   'fred'   fred, 全てのホストから接続
'%'    ''   全てのホストから接続してくる全ユーザー
'%.loc.gov'   'fred'   fred, loc.gov ドメイン内の全てのホストからの接続
'x.y.%'   'fred'   fred, x.y.net, x.y.com,x.y.edu, などからの接続. (あまり有効な使い方ではないです)
'144.155.166.177'   'fred'   fred, IP address が 144.155.166.177 のホストからの接続
'144.155.166.%'   'fred'   fred, 144.155.166 class C subnet 内の全てのホストからの接続
'144.155.166.0/24'   'fred'   Same as previous example

Host に IP のワイルドカード(例えば '144.155.166.%' はサブネットの全てのホストにマッチ) を使用することができます。が、この場合、 144.155.166.somewhere.com というホスト名でだれかが接続しようとしてくるかもしれません。このような攻撃に対し、MySQL は数字やドットで始まるホスト名を拒否しています。もし 1.2.foo.com のような名前のホストを持っている場合、許可テーブルの Host には絶対にマッチしません。 IPアドレスのみ、IP のワイルドカードにマッチする事になります。

サーバーに来る接続は、user テーブル内の登録に１つ以上マッチするかもしれません。例えば, thomas.loc.gov の fred からの接続は、上に示された登録のうちのいくつかにマッチするでしょう。サーバーは、複数の登録にマッチした場合、どのようにしてその中から使用する登録を選ぶのでしょう？サーバーは起動後に user テーブルをソートし、並び換えられた順に登録を検索することにより、この問題を解決します。最初にマッチした登録が使用されます。

user テーブルが以下のようにソートされていた場合：

     +-----------+----------+-
     | Host      | User     | ...
     +-----------+----------+-
     | %         | root     | ...
     | %         | jeffrey  | ...
     | localhost | root     | ...
     | localhost |          | ...
     +-----------+----------+-

サーバーがこのテーブルを読むと、Host に値が最も確実に特定できるホストを指定しているエントリを、最初に参照します。 (Host 項の '%' は ``すべてのホスト'' を意味し、ホスト名をはっきりと特定しているものではありません)

Host の値が同じエントリがあった場合、もっとも明確に User の値がユーザーを指定しているエントリを最初に参照します。(User の値が空の場合、``だれでも'' を意味します) この結果、user テーブルは以下のようにソートされます：

     +-----------+----------+-
     | Host      | User     | ...
     +-----------+----------+-
     | localhost | root     | ...
     | localhost |          | ...
     | %         | jeffrey  | ...
     | %         | root     | ...
     +-----------+----------+-

接続が試みられた場合、サーバーは並び換えられた登録を探し、最初に見つけたものを使用します。 'localhost' の jeffrey からの接続は、まず最初に Host に localhost を設定しているエントリにマッチします。ユーザー名が空のエントリは、ホスト名とユーザー名の両方を指定した接続にもマッチします。 ( '%'/'jeffrey' エントリもマッチします。が、これは最初にはマッチしません。)

もう一例。user が以下の設定と仮定します：

     +----------------+----------+-
     | Host           | User     | ...
     +----------------+----------+-
     | %              | jeffrey  | ...
     | thomas.loc.gov |          | ...
     +----------------+----------+-

これは次のようにソートされます：

     +----------------+----------+-
     | Host           | User     | ...
     +----------------+----------+-
     | thomas.loc.gov |          | ...
     | %              | jeffrey  | ...
     +----------------+----------+-

thomas.loc.gov の jeffrey からの接続は、最初のエントリにマッチし、 whitehouse.gov の jeffrey からの接続は、二つ目のエントリにマッチします。

最初にサーバが,接続のためのマッチを見つけるのを試みるとき,共通の誤解は与えられたユーザ名に明らかにそのユーザを命名するすべてのエントリが使用されると思うことです. これは単に本当ではありません. jeffreyによるthomas.loc.govからの接続が最初にエントリによってユーザ分野値として‘jeffrey'を含まないいずれのエントリによってる合わせられる場合,前の例はこれをユーザ名なしで例示します!

よくある考え違いは、ユーザー名を与えた場合、サーバーが接続にマッチするものを探す際に、そのユーザーが登録されている全てのルールが、最初に使用されるだろうと考えることです。これは正しくありません。前の例でこれを示しましたが、thomas.loc.gov の jeffrey からの接続が最初にマッチするのは、 User フィールドの値が 'jeffrey' になっているエントリではなく、ユーザー名なし(＝だれでも) のエントリの方が先にマッチします！

もしサーバーへの接続がうまく行かない場合、 user テーブルを表示し、マニュアルでソートしてみて、どのエントリに最初にマッチするか探してください。

Access control, stage 2: 要求の承認
==============================

一度接続か確立されると、サーバーはステージ２に移ります。このステージでは、サーバーはこの接続から来るそれぞれの要求が許可されているかどうかをチェックします。チェックは実行しようとしている操作のタイプにより行います。その操作が許可テーブルのどの権限フィールドに当てはまるかを見ます。これら権限は  user, db,host, tables_priv か columns_priv テーブルより導出されます。許可テーブルは GRANT コマンドで操作します。 See GRANT. (You may find it helpful to refer to the table shown earlier that lists the fields present in each of the grant tables; see Privileges.)

user テーブルは全てに対して基本となる権限をユーザーに割り当てます。たとえカレントのデータベースが許可を与えていなくても、user テーブルの設定が有効になります。例えば、user テーブルで delete を許可した場合、サーバーにあるどんなデータベースの行も削除できるのです！いうならば、user テーブルの権限はスーパーユーザーの権限と言ってもいいでしょう。この権限はスーパーユーザー(サーバーやデーターベース管理者)のみに与えておく事が賢明です。他のユーザーは、user テーブルの権限の設定を 'N' のままにしておくべきですし、また、db テーブルと host テーブルを利用して、データベースを指定した上でユーザーに権限を許可すべきです。

db テーブルと host テーブルは特定のデータベースに対する権限許可を行います。 Values in the scope fields may be specified as follows:

  * ワイルドカード文字 % と _ は Db テーブルと Host フィールドだけに使用できます。

  * '%' Host 値は ``あらゆるホスト'' を意味します。 db テーブルの Host に空を設定すると、``さらに host テーブルに許可情報を探しにいく'' となります。

  * '%' か 空値を Host テーブルに設定すると、それは ``あらゆるホスト'' となります。

  * '%' か 空値を host テーブルの Db フィールドに設定すると、それは ``あらゆるデータベース'' となります。

  * User を空値にすると、匿名ユーザーにマッチします。

サーバー起動時に、db テーブルと host テーブルはサーバーに読み込まれます。 (user テーブルもこの時に同時に読まれます) db テーブルは Host, Db, User のフィールドでソートされ、 host テーブルは Host, Db フィールドでソートされます。 user テーブルは、一番特定できるエントリを最初に、一番特定できないものを最後にソートします。サーバーはソートされたものの中から、最初にマッチしたものを使用します。

tables_priv と columns_priv テーブルは、特定のテーブルとフィールドに対する権限を許可します。スコープフィールドの値は、いかにそって記述されます：

  * ワイルドカード文字 % と _ はどちらかのテーブルの Host フィールドに使用できます。

  * どちらかのテーブルの Host 値を '%' かブランクにすると、 ``any host.'' を意味します。

  * Db, Table_name, Column_name フィールドはどのテーブルにもワイルドカードやブランクは使用できません。

tables_priv と columns_priv テーブルは Host, Db, User フィールドで並び換えられます。これは db テーブルのソートに似ていますが、 Host フィールドだけがワイルドカードを含むので、ソートはより単純なものになります。

この要求の承認は次のようにして行います。もしアクセス承認を決定する部分のソースコードを理解できるなら、ちょっと変わったアルゴリズムで承認の決定を行っている事に気づくでしょう。

管理者の要求(shutdown, reload, etc.)については、サーバーは user テーブルだけを参照します。(user テーブルだけが管理者権限のフィールドを持つ)。エントリに許可登録されている操作は受け入れられ、それ以外は拒否されます。例えば、mysqladmin shutdown を実行しようとしても、user テーブルの shutdown 権限が許されていなければ実行できません。この時、db と host テーブルはチェックされません。(これらのテーブルには Shutdown_priv フィールドが無いからです)

データベースへの要求 (insert, update, etc.) において、サーバーはまず最初に、ユーザーのグローバルな権限(スーパーユーザー)を user の中から探しだします。もし許可が与えられていれば、アクセスは成功します。

user テーブルのグローバルな権限の設定が不十分であるなら、サーバーはユーザーのデータベースに対する権限を db テーブルと host テーブルから決定します：

 1. サーバーは db テーブルの Host,Db,Userフィールドを参照します。 Host と User フィールドはユーザーの接続時のホスト名と MySQL ユーザー名にマッチします。 Db フィールドはユーザーがアクセスしたいデータベース名にマッチします。 Host と User にマッチするものが無かった場合、アクセスは拒否されます。

 2. db テーブル内の Host フィールドが空でないエントリにマッチした場合、ユーザーの指定されているデータベースに対する権限が定義されます。

 3. Host フィールドが空値の db テーブルのエントリにマッチした場合、どのホストがそのデータベースへアクセスできるかを host テーブルから探し出します。この場合、host テーブル の Host, Db フィールドとマッチするものを探し出します。 host テーブルにエントリがなかった場合、アクセスは拒否されます。もしマッチすると、ユーザーの特定データベースに対する権限は、 host テーブルと db テーブル両方にまたがった権限から割り出されます。いうならば両方とも 'Y' である権限。 (この方法を使用すると、まず db テーブルのエントリに大まかな権限を設定しておき、それから host テーブルのエントリを使用して、ホスト情報もとに権限を限定していくという事ができます)

特定データベースに対する権限が db テーブルと host テーブルのエントリから決定された後、サーバーはその割り出された権限に対し、user テーブルて設定されている権限を加えます。この結果から得られた権限にマッチした要求は受け入れられます。そうでなければ、サーバーはユーザーのテーブル、フィールドに対する許可を、 tables_priv と columns_priv 内に探します。アクセスはこの結果により、許可、拒否されます。

先のユーザーの権限が計算される方法の記述は、boolean 表記で示すならば、以下のようになるでしょう：

     global privileges
     OR (database privileges AND host privileges)
     OR table privileges
     OR column privileges

これは少し分かりにくいかもしれません。もしグローバルの user エントリ権限許可が、リクエストされたオペレーションには不十分だと最初に分かった際、サーバーがこれらの権限を database-, table-, column-固有の権限の後に、なぜ、追加してしまうのか。その理由は、リクエストが1個以上の権限を要求するだろうということです。例えば、もしあなたが INSERT ...  SELECT 構文を実行するなら、あなたには insert と select 許可が必要です。あなたの権限が、 user テーブルエントリで一つの権限が許可され、 db テーブルで、そのほかの権限が許可されていたとします。この場合、あなたは、そのリクエストを実行するために、必要な権限を持っています。しかし、サーバーはどちらのテーブル、それ単体からでは、権限を得ることが出来ません。権限は、両方のエントリーを合わせなくてはならないのです。

host テーブルは ``安全な'' ホストのリストを維持するために使用できます。 TcX では、host テーブルにはローカルネット上の全てのホストが登録されています。これらのホストは全ての権限が許可されています。

逆に host table で安全ではないホストを指定することもできます。 public.your.domain というマシンが安全ではない、公開されている場所にあるとします。その場合以下のようにして、その公開マシン以外のネットワーク上のホストに対して、アクセスを許可することができます：

     +--------------------+----+-
     | Host               | Db | ...
     +--------------------+----+-
     | public.your.domain | %  | ... (all privileges set to 'N')
     | %.your.domain      | %  | ... (all privileges set to 'Y')
     +--------------------+----+-

権限のテーブル設定は、あなたの思い通りに許可が得られるのか、常に(mysqlaccess等を使用して)チェックすべきです。

いつ権限の変更が反映されるか
==============

mysqld の起動時、全ての許可テーブルはメモリーに読み込まれ、この時点で有効になります。

GRANT, REVOKE, SET PASSWORD を使用して許可テーブルを変更した場合、直にサーバに通知されます。

もし手動で許可テーブルを変更した場合(INSERT, UPDATE などで)、 FLUSH PRIVILEGES 構文か mysqladmin flush-privileges コマンドか mysqladmin reload コマンドを実行して、サーバーに許可テーブルの読み込みを指示しなければなりません。そうしなければ、サーバーを再起動させるまで、変更は反映されません。 If you change the grant tables manually but forget to reload the privileges, you will be wondering why your changes don't seem to make any difference!

サーバーが許可テーブルの変更を通知した場合、既に接続しているクライアントは、以下のような影響を受けます：

  * テーブルとフィールドの許可の変更は、次のクライアントの要求から反映されます。

  * データベースに対する許可の変更は次の USE db_name コマンド以降から有効になります。

グローバル権限とパスワードの変更は、次のクライアントの接続時から反映されます。

MySQL 権限許可の初期設定
===============

MySQL インストール後、scripts/mysql_install_db を実行して権限のアクセス許可を初期化します。 See Quick install. mysql_install_db スクリプトは mysqld サーバーを起動し、以下のように権限を初期化してテーブルに登録します：

  * MySQL root ユーザーはスーパーユーザーとして登録され、全ての操作ができます。 localhostからしか接続できません。

     注意: root のパスワードの初期値は空です。全ての人が パスワードなしで root になれ、全ての権限許可を得ることができます。

  * 'test' あるいは 'test_' で名前がはじまっているデータベースに対して、匿名ユーザーでもなんでもできるように許可が与えられます。これは ローカルホストからの全てのユーザーは パスワード無しで接続ができ、匿名ユーザーとして扱われるということです。

  * その他の要求は拒否されます。例えば、一般ユーザーは mysqladmin shutdown や mysqladmin processlist を実行できません。

注意: デフォルトの権限は Win32 では違います。 See Win32 running.

初期インストールの状態ではかなりアクセスが解放されているので、インストール後最初にすることは、MySQL root ユーザーにパスワードを設定することです。以下のようにします(パスワードは PASSWORD() 関数を使用することをお忘れなく)：

     shell> mysql -u root mysql
     mysql> UPDATE user SET Password=PASSWORD('new_password')
                WHERE user='root';
     mysql> FLUSH PRIVILEGES;

MySQL 3.22 以上では、SET PASSWORD 構文も使用できます:

     shell> mysql -u root mysql
     mysql> SET PASSWORD FOR root=PASSWORD('new_password');

password をセットする他の方法として、mysqladmin コマンドも使用できます：

     shell> mysqladmin -u root password new_password

もし最初の方法で user テーブルのパスワードを直接更新したなら、サーバーに許可テーブルの再読み込みを行わせなければなりません(FLUSH PRIVILEGES を使用して)。

一度 root のパスワードを設定したなら、root でサーバーに接続する場合は常にパスワードを与えなければなりません。

追加設定やテストをしているためパスワードを入れたくない場合、 root パスワードをブランクのままにしておこうと考えるかも知れませんが、実稼働させる前には必ず設定してください。

どのようにデフォルトの権限を設定しているか、scripts/mysql_install_db 見てみてください。これは他のユーザーを設定するときに使えるでしょう。

もし権限の初期状態を違うものにして初期化したいなら、 mysql_install_db を実行する前に編集してもよいでしょう。

もしテーブルを完全に作り直したいなら、mysql データベースのディレクトリに存在する全ての *.frm, *.MYI, *.MYD ファイルを削除します。 (このディレクトリーはデータベースディレクトリーの下に mysql という名前で存在します。 mysqld --help とすればデータベースのディレクトリーが表示されます。) そして好みの許可状態に mysql_install_db を編集してから実行します。

注意: MySQL 3.22.10 以前のバージョンでは, *.frm ファイルを消してはいけません.  もしうっかり消してしまった場合、 mysql_install_db を実行する前に、 MySQL 配布からコピーしなおさなくてはなりません。

新しいユーザ権限を MySQL へ追加
===================

ユーザーは２つの違った方法で追加できます： GRANT 構文を使用して行う方法と、 MySQL の許可テーブルを直接操作する方法とです。 GRANT 構文の使用をお勧めします。

以下の例では、いかにして mysql クライアントを使用して新規にユーザーを登録するかを示します。以下の例では、権限は前節で述べたデフォルト値になっているとします。よって変更を行うためには、あなたは mysqld が走っているマシン上にログインしていなくてはなりませんし、かつ、MySQL root ユーザーで接続していなければなりません。さらに MySQL root ユーザーには mysql データベースに対して insert 権限を持ち、 reload のアドミニストレーター権限を持っていなければなりません。もし root ユーザーのパスワードを変えていたならば、 mysql コマンドにパスワード指定を与えなくてはなりません。

     shell> mysql --user=root mysql
     mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost
                IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
     mysql> GRANT ALL PRIVILEGES ON *.* TO monty@"%"
                IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
     mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
     mysql> GRANT USAGE ON *.* TO dummy@localhost;

これら GRANT 構文では3つの新しいユーザを作ります:

monty
     どこからでもサーバーに接続できる完全なスーパーユーザ。しかし、MySQL を使用する時にはパスワード 'some_pass' を使用する必要があります。 monty@localhost と monty@"%" の両方に GRANT 構文を発行しなくてはならない事に注意してください。もし localhost からの許可をした登録がないと、localhost から接続した時、 mysql_install_db が自動で作成した localhost への匿名ユーザーが優先されます。なぜなら、 Host フィールドの値が(ブランクやワールドカード以外に)明記されており、許可登録が MySQL 内部でソートされる時に順番が上にソートされるからです。

admin
     localhost からパスワードなしで接続できますが、reload, process の使用だけが許されます。これは、mysqladmin reload, mysqladmin refresh, mysqladmin flush-* そして mysqladmin processlist コマンドの実行がこのユーザーに許可されます。データベースへのアクセスは許可されていません。しかしこれは後でテーブル GRANT 構文を発行すれば、個々のデータベースへのアクセス権限が設定できます。

dummy
     パスワードなしで localhost からのみ、接続できるユーザー。グローバルな権限は全て 'N' に設定されます。 USAGE 権限は権限無しユーザーの設定を許可する事になります。これは、特定データーベースに対しての許可を後から与える事を想定しています。

同じアクセス許可を INSERT 構文を使用して直接設定できます。サーバーに許可テーブルの再読み込みを指示します：

     shell> mysql --user=root mysql
     mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('some_pass'),
                     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
     mysql> INSERT INTO user VALUES('%','monty',PASSWORD('some_pass'),
                     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
     mysql> INSERT INTO user SET Host='localhost',User='admin',
                      Reload_priv='Y', Process_priv='Y';
     mysql> INSERT INTO user (Host,User,Password)
                             VALUES('localhost','dummy','');
     mysql> FLUSH PRIVILEGES;

MySQL のバージョンにより、上の 'Y' の数が違う事に注意してください。 (3.22.11 以前のバージョンでは項目数が少なくなります). admin ユーザーを登録で使用している INSERT の拡張は 3.22.11 以上で可能です。

スーパーユーザーを定義するためには、user テーブルの許可フィールドを 'Y' にするだけでかまいません。 db や host テーブルに登録は必要無いのです。

user テーブルの許可フィールドは最後の INSERT 文で(dummy ユーザーのために) は設定されていません。これらのフィールドはデフォルト値の 'N' になります。これは GRANT USAGE が行うのと同じものです。

以下は、localhost, server.domain, whitehouse.gov から接続が可能な custom ユーザーの追加例です。 custom ユーザーは bankaccount データーベースには localhost からの接続のみを許可され、 expenses データベースには whitehouse.gov からのみ接続が許可され、 customer データベースには全てのホストから接続できます。 custom ユーザーは、 stupid というパスワードを全てのホストで使用したいとします。

このユーザーの許可を GRANT 構文で定義するには、以下のようにします：

     shell> mysql --user=root mysql
     mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
                ON bankaccount.*
                TO custom@localhost
                IDENTIFIED BY 'stupid';
     mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
                ON expenses.*
                TO custom@whitehouse.gov
                IDENTIFIED BY 'stupid';
     mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
                ON customer.*
                TO custom@'%'
                IDENTIFIED BY 'stupid';

許可テーブルを直接変更してこのユーザーの権限を設定するにはいかのようにします (FLUSH PRIVILEGES を最後に実行している事に注意)：

     shell> mysql --user=root mysql
     mysql> INSERT INTO user (Host,User,Password)
            VALUES('localhost','custom',PASSWORD('stupid'));
     mysql> INSERT INTO user (Host,User,Password)
            VALUES('server.domain','custom',PASSWORD('stupid'));
     mysql> INSERT INTO user (Host,User,Password)
            VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
     mysql> INSERT INTO db
            (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
             Create_priv,Drop_priv)
            VALUES
            ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
     mysql> INSERT INTO db
            (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
             Create_priv,Drop_priv)
            VALUES
            ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
     mysql> INSERT INTO db
            (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
             Create_priv,Drop_priv)
            VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y');
     mysql> FLUSH PRIVILEGES;

最初の３つの INSERT 文は、 custom ユーザーがそれぞれのホストからパスワードつきで接続できるように user テーブルに追加しています。しかしここでは権限は１つも与えられていません(権限のデフォルト値は 'N' です)。次の三つの INSERT 文は、bankaccount, expenses, customer データベースに対する該当ホストからのアクセス許可を custom ユーザーに与えるように、 db テーブルに追加しています。許可テーブルが直接変更された場合、これらをサーバーに反映させるために、許可テーブルの再読み込みを(FLUSH PRIVILEGESで) サーバーにつげなければなりません。

もし、あるドメインの全てのマシンに接続を許可したい場合、以下のように GRANT 構文を発行します：

     mysql> GRANT ...
                ON *.*
                TO myusername@"%.mydomainname.com"
                IDENTIFIED BY 'mypassword';

許可テーブルを直接変更するには以下のようにします：

     mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername',
                PASSWORD('mypassword'),...);
     mysql> FLUSH PRIVILEGES;

もちろん、xmysqladmin, mysql_webadmin, そして xmysql を使っても、権限テーブルへの値の挿入/変更/更新ができます。これらのユーティリティは Contrib directory of the MySQL Website (http://www.mysql.com/Contrib/). に見つけることができます。

パスワードの設定法
=========

前節の例で述べた、とても重要な基本原則：

INSERT か UPDATE で空ではないパスワードを設定する場合、暗号化するために PASSWORD() 関数を使用しなくてはなりません。これは user テーブルはプレーンテキストでなく、暗号化されたパスワードであることを要求しているからです。この原則を忘れてしまった場合、以下のようにしてパスワードをセットしてしまうかもしれません：

     shell> mysql -u root mysql
     mysql> INSERT INTO user (Host,User,Password)
            VALUES('%','jeffrey','biscuit');
     mysql> FLUSH PRIVILEGES;

これは user テーブルにプレーンテキストの 'biscuit' をパスワードとして登録してしまいます。 jeffrey ユーザーでこのパスワードを使用してサーバーに接続しようとすると、 mysql クライアントは暗号化したパスワードをサーバーに送ります。サーバーは暗号化されたパスワード('biscuit' ではありません) と user テーブルに登録された値('biscuit') を比較します。その結果、比較は失敗し、サーバーは接続を拒否します：

     shell> mysql -u jeffrey -pbiscuit test
     Access denied

user テーブルに登録されるパスワードは暗号化されたものでなくてはなりません。 INSERT 構文は以下のようにして使用しなくてはなりません：

     mysql> INSERT INTO user (Host,User,Password)
            VALUES('%','jeffrey',PASSWORD('biscuit'));

SET PASSWORD 構文を使用する場合は、以下のようにしなくてはなりません：

     mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');

もし GRANT ... IDENTIFIED BY 構文や mysqladmin password コマンドでパスワードを設定した場合、PASSWORD() 関数は必要ありません。両方とも、パスワードを暗号化してくれますので、以下のように'biscuit'と与えます：

     mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';

     shell> mysqladmin -u jeffrey password biscuit

注意： PASSWORD() がパスワードを暗号化することに注意してください。この暗号化は UNIX のパスワードで使用されている暗号化と違うことにも留意してください。 UNIX パスワードファイルに記録されている暗号と PASSWORD() が暗号化した物が同じでも、同じパスワードであるとは思わないでください。 See User names.

何故 Access denied エラーになるのか
=========================

もし、MySQL サーバーに接続しようとして Access denied エラーに遭遇してしまったら、以下に記すことが問題の解決のための指標となるでしょう:

  * MySQL をインストールした後に、スクリプト mysql_install_db を実行して許可テーブルを初期化しましたか？していなければ実行してください。See Default privileges 権限許可のテーブルが初期化されているかを試すには以下のようにします：

          shell> mysql -u root test

     これは普通はエラーなしで接続できます。 MySQL データベースディレクトリ内に user.MYD ファイルがあるかどうかでもチェックします。 (普通は PATH/var/mysql/user.MYD です。ここで PATH は MySQL をインストールしたディレクトリーパスを示します。)

  * 初めてインストールした後は、以下のようにしてサーバーに接続してユーザーとアクセス権を設定しなくてはなりません：

          shell> mysql -u root mysql

     初期状態では、MySQL に root ユーザーをパスワードなしで登録しているので、問題なく接続できるはずです。しかしこれはセキュリティ上危険な状態なので、他の MySQL ユーザーを登録している時に、 root のパスワードを設定しておいてください。

     もし root で接続しようとして以下のエラーが出た場合：

          Access denied for user: '@unknown' to database mysql

     これは user テーブルに、 User フィールド = root かつ mysqld がリゾルブできなかったホスト名で、クライアントが登録されていないからです。この場合、 /etc/hosts ファイルあるいは \windows\hosts ファイルを編集してホスト名を追加し、--skip-grant-tables オプションでサーバーをリスタートします。

     もし 3.22.11 より前の MySQL から 3.22.11 以上にバージョンアップしたなら、 mysql_fix_privilege_tables スクリプトを実行しましたか？実行していないなら、このエラーになります。許可テーブルの構造が MySQL 3.22.11 から変更され、 GRANT 構文が機能しています。

  * もし許可テーブルを直接変えて(INSERT か UPDATE 構文で)、変更が無視されているようならば、サーバーにテーブルを再読み込みさせるために、 FLUSH PRIVILEGES 構文か mysqladmin flush-privileges コマンドを実行する事を思い出してください。これを実行しなかった場合、変更は次のサーバーのリスタートまで反映されません。 root ユーザーのパスワードを設定したあとでも、権限情報を再読み込みするまでは新しいパスワードは不要です。なぜなら、サーバーは新しいパスワードをまだ知らないからです！

     mysqladmin reload を行っても、権限が有効なのは、このコマンド発行後に新しく接続したクライアントに対してだけです。 (多くの権限情報がサーバーにキャッシュされているためです)

  * もしあなたの権限がセッションの途中で変更されたように思ったなら、それはスーパーユーザーが権限を変えたのかも知れません。許可テーブルの再読み込みは新しいクライアントの接続から反映されますが、すでに接続している場合でも Privilege changes. に示す条件下では影響を受けます。

  * テストのためには、mysqld デーモンを --skip-grant-tables オプションで開始すべきです。そうすれば MySQL 承認テーブルを変更でき、スクリプト mysqlaccess を、あなたの承認が働くかどうかのチェックのために使用できます。 mysqladmin flush-privileges は mysqld デーモンに新しい承認テーブルの使用を開始するように知らせます。これは --skip-grant-tables オプションを上書きします。ユーザーの許可テーブルを読み込ませるのに、サーバーを落して立ち上げ直す必要はありません。

  * Perl, PHP, Python または ODBC でアクセスの問題があった場合も、常に mysql -u user_name db_name または mysql -u user_name -pyour_pass db_name で、権限の問題をテストしてください。(-p と password の間には空白がないことに注意してください。--password=your_password 構文でもパスワードを与えられます) mysql クライアントで接続できるなら、アクセスの権限の設定の問題ではなく、プログラムの問題です。

  * もしあなたのパスワードが働かないのであれば、 INSERT, UPDATE, SET PASSWORD 構文でパスワードを設定するとき PASSWORD() 関数を使用しなければならないことを思い出してください。しかし PASSWORD() 関数は、GRANT ... INDENTIFIED BY 構文や mysqladmin password コマンドでは不要です。 See Passwords.

  * localhost はローカルのホスト名です。もしクライアントがホストを指定せずに接続してきた場合、localhost がデフォルトで使用されます。しかし、 MIT-pthreads を使用している場合、localhost への接続は失敗します。 (localhost への接続は、Unixソケットを使用しますが、 MIT-pthreads が ソケット接続をサポートしていないためです。) この問題が起きるシステムでは、サーバー名を指定するために --host オプションを使用すべきです。これは TCP/IP 接続を使用して mysqld サーバーに接続します。この場合、user テーブルに、サーバーの実ホスト名を登録しておかなくてはなりません。 (これはクライアントプログラムをサーバーと同じホスト上で動かしている場合真となります)

  * mysql -u user_name db_name を使用してデータベースに接続しているときに Access denied エラーが発生した場合、user テーブルの設定違いが考えられます。 mysql -u root mysql を実行し、以下の SQL 文を試してください：

          mysql> SELECT * FROM user;

     Host と User にあなたのコンピュータ名と MySQL ユーザー名にマッチする登録がなされていなければなりません。

  * Access denied エラーは、どのユーザーで接続してきたか、どのホストから接続しようとしているか、パスワードを使用しているのかをメッセージに出力します。通常、エラーになっているホスト名とユーザー名がマッチするエントリが user テーブルに一つはなければなりません。

  * 他のホストから MySQL サーバーに接続を試みた時に以下のエラーが出た場合、 user テーブルにあなたがアクセスしているホストにマッチする行がありません：

          Host ... is not allowed to connect to this MySQL server

     mysql コマンドをサーバーのホスト上で使用して、 user, db, host テーブルに、接続しようとしている ユーザー名／ホスト名 を加えれば解決できるでしょう。もしサーバーが MySQL 3.22 ではなく、接続しようとしているホストの IP もホスト名もわからない場合、 user テーブルの Host フィールドに '%' を設定し、 mysqld を --log オプションで再起動してください。そしてクライアントホストから接続すれば、MySQL のログファイルにそのホストの情報が記録されているはずです。それがわかれば、先に設定した user テーブルの Host フィールドの '%' をログに記録されたホスト名に置き換えます。(しかしこれはシステムを危険にさらします)

  * mysql -u root test は動いたものの mysql -h your_hostname -u root test が Access denied を返した場合、 user テーブルに正しいホスト名が使用されていないと思われます。 user テーブルの Host フィールドにホスト名を確定できる形で指定していないか、使用しているシステムのリゾルブが FQDN (or vice-versa) を返しているかだと思われます。例えば、user テーブルに 'tcx' ホストの定義があったとして、 DNS が MySQL に 'tcx.subnet.se' をホスト名として返した場合、これは動きません。 user テーブルの Host フィールドの値に、あなたのホストの IP 番号を加えてください。 (user テーブルの Host の値にワイルドカードを使用することができます。'tcx.%' のように。しかしホスト名の値を % 文字で終わらせる設定は、安全ではなく、推奨されません)

  * もし mysql -u user_name test が動作し mysql -u user_name other_db_name が動作しない場合は、db テーブルに other_db_name のエントリが登録されていません。

  * mysql -u user_name db_name はザーバー上では動作するが、 mysql -u host_name -u user_name db_name がクライアントホスト上で動作しない場合、 user テーブルか db テーブルにクライアントホストの名前が登録されていません。

  * Access denied の原因がもし上記に当てはまらない場合は、 user テーブルから Host にワイルドカードを使用しているエントリを全て消去してみてください。(% や _ を含む値です) よくある間違いは、localhost に対して localhost と同じマシン上からの接続を許可すると考えて Host='%' と User='some user' を登録することです。これは動きません。なぜなら、デフォルトの権限に Host='localhost' と User='' が含まれているからです。 Host の値が 'localhost' の場合、これは '%' よりも具体的に指定されているので、localhost からの接続にはこちらの方が使用されるのです！ 正しい指定の仕方は、二番目の登録として Host='localhost' と User='some_user' を追加するか、あるいは、Host='localhost' と User='' を削除することです。

  * もし以下のエラーが出た場合 db か host テーブルに問題があるのかもしれません。：

          Access to database denied

     もし db テーブルに Host フィールドが空の登録がある場合には、 host テーブル中に、db テーブルに登録されているホストを明記した物が一つ以上あるかどうかを確認してください。

     もし SELECT ... INTO OUTFILE や LOAD DATA INFILE SQL 文を使用している時にこのエラーが出る場合、 user テーブルのあなたの登録に file 権限が許可されていないと思われます。

  * クライアントプログラムは接続に際して、設定ファイルで設定された値か環境変数の値を使用することに注意してください。もしクライアントプログラムが誤った値を接続に使用しているようなら、環境変数とホームディレクトリにある .my.cnf ファイルを確認してください。もちろんシステムワイドの MySQL 設定ファイルも、パラメターが記述されていないか、チェックしてみてください。See Option files. もしクライアントをオプションなしで起動していて Access denied がでるなら、オプションファイルに古いパスワードが書かれているか確認してください。 See Option files.

  * もし全て失敗するなら、mysqld デーモンをデバッグオプションで起動してください。例えば、--debug=d,general,query。これはコネクションに試みたホストやユーザーの情報、また実行したコマンドを表示します。 See Debugging server.

  * もし MySQL の権限許可についてその他の問題が起こり、メーリング・リストに問題をポストしなくてはいけないと感じれば、いつも MySQL 許可テーブルのダンプを提供して下さい。 mysqldump mysql コマンドでダンプできます。いつものように、 mysqlbug スクリプトでポストしてください。See Bug reports. ときにはは、 mysqldump を実行するために、 mysqld を --skip-grant-tables オプションで実行しないといけないかもしれません。

MySQL 言語リファレンス
**************

リテラル:文字列と数値をどのように書くか？
=====================

文字列
---

文字列は文字の並びです。引用符(')または二重引用符(")で括られます(後者は ANSI モードで実行していない場合のみ)。 例：

     'a string'
     "another string"

文字列中では、いくつかのシーケンスは特別な意味を持ちます。これらのシーケンスのそれぞれはエスケープ文字として知られるバックスラッシュ (\)で始まります。MySQL は次のエスケープシーケンスを認識します。

\0
     ASCII 0 (NUL) 文字。

\n
     改行文字。

\t
     タブ文字。

\r
     リターン文字。

\b
     バックスペース文字。

\'
     引用符(')。

\"
     二重引用符(")。

\\
     バックスラッシュ(\)文字。

\%
     % 文字。これは % がワイルドカード文字として解釈される文脈で、% そのものを検索するために使用されます。 See String comparison functions.

\_
     _ 文字。これは _ がワイルドカード文字として解釈される文脈で、_ そのものを検索するために使用されます。 See String comparison functions.

いくつかの文字列文脈で \% または \_ を使用すると、これらは文字列 % と _ ではなく、\% と \_ を返します。

文字列中に引用符を含める方法はいくつかあります:

  * ' で括られる文字列中の ' は '' として書くことができます。

  * " で括られる文字列中の " は "" として書くことができます。

  * 引用符の前にエスケープ文字 (\) を置くことができます。

  * " で括られた文字列中の ' は特別扱いの必要はなく、二重にしたり、エスケープする必要はありません。同じように、' で括られた文字列中の " は特別扱いの必要はありません。

次の SELECT ステートメントは、クォートとエスケープがどのように働くかを示します:

     mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
     +-------+---------+-----------+--------+--------+
     | hello | "hello" | ""hello"" | hel'lo | 'hello |
     +-------+---------+-----------+--------+--------+

     mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
     +-------+---------+-----------+--------+--------+
     | hello | 'hello' | ''hello'' | hel"lo | "hello |
     +-------+---------+-----------+--------+--------+

     mysql> SELECT "This\nIs\nFour\nlines";
     +--------------------+
     | This
     Is
     Four
     lines |
     +--------------------+

バイナリデータを BLOB フィールドに挿入したい場合、次の文字をエスケープシーケンスで表す必要があります:

NUL
     ASCII 0。\0 (バックスラッシュと ASCII 0 文字) に置き換えるべきです。

\
     ASCII 92, バックスラッシュ。\\ と表記してください。

'
     ASCII 39, 引用符。\' と表記してください。

"
     ASCII 34, 二重引用符。\" と表記してください。

C コードを書く場合、INSERT 節で文字をエスケープするために、C API 関数 mysql_escape_string() を使用できます。See C API function overview.  Perl では、DBI パッケージの quote メソッドを使用して、特殊文字を適当なエスケープシーケンスに変換できます。See Perl DBI Class.

上記の特殊文字のどれかを含む可能性のある全ての文字列について、エスケープ関数を使用すべきです！

数値
--

整数は数字の並びで表現されます。浮動小数点は . で小数を分割します。どちらの型も負数を表すために - を前につけます。

正当な数値の例:

     1221
     0
     -32

有効な浮動小数点の例：

     294.42
     -32032.6809e+10
     148.00

整数が浮動小数点の文脈で使用されるかもしれません； この場合、浮動小数点に変換されます。

16進法の値
------

MySQL は16進法の値をサポートします。数値の文脈では、これらは整数(64ビット精度)のように振る舞います。文字列の文脈では、hexの桁のそれぞれのペアが文字に変換されたバイナリー文字のように振る舞います。

     mysql> SELECT 0xa+0
            -> 10
     mysql> select 0x5061756c;
            -> Paul

16進数表記は、ODBC において BLOB の値を与えるためにしばしば使用されます。

NULL 値
------

NULL は ``no data'' を意味し、数値型の 0 や文字列型の空文字列とは異なることに注意してください。 See Problems with NULL.

テキストファイルの読み込みや書き出し時に、NULL は \N で表現されます。 (LOAD DATA INFILE, SELECT ... INTO OUTFILE). See LOAD DATA.

データベース名、テーブル名、インデックス名、フィールド名、エイリアス名
-----------------------------------

データベース名、テーブル名、インデックス名、フィールド名、エイリアス名は MySQL では全て同じ規則に基づきます:

注意: 規則は MySQL 3.23.6 で変更されました。それは識別子(データベース名、テーブル名、フィールド名)の ` でのクォートを導入した時です (ANSI モードで実行する場合は、" も識別子をクォートするために働きます)。

識別子   最大長   許される文字
データベース   64   ディレクトリ名として許されるすべての文字。/ を除く。
テーブル   64   ファイル名として許されるすべての文字。/ と . を除く。
フィールド   64   すべての文字
エイリアス   255   すべての文字

注意: 上記に加え、識別子内には ASCII(0) と ASCII(255) を持てません。

注意: 識別子が制限された単語であったり特殊文字を含む場合は、それを使用する時には常に ` でクォートする必要があります:

     SELECT * from `select` where `select`.id > 100;

MySQL の前のバージョンでは、名前の規則は次に従います:

  * 名前は、現在の文字セットのアルファベットと数字文字から成り、_ と $ も含みます。デフォルト文字セットは ISO-8859-1 Latin1 ですが、これは mysqld に --default-character-set オプションを与えることで変更できます. (3.23.14 以上の場合のみ。それ以前のバージョンでは MySQL 再コンパイルが必要) see Character sets.

  * 名前は、名前として正しい任意の文字で始めることができます。特に、名前は数字で始めることができます(これは他の多くのシステムと異なります！)。しかし、数字だけの名前にする事はできません。

  * 名前の中に . 文字を使用することはできません。フィールドを参照できるように形式を拡張するために使用されるためです(後述)。

1e のような名前は使用しないことを勧めます。1e+1 のような式があいまいだからです。これは、式 1e + 1 として、または数値 1e+1 として解釈されます。

MySQL では次の形式のいずれかを使用してフィールドを参照できます:

フィールドの参照方法   意味
col_name   クエリ中で使用されるテーブル内に存在している col_name という名前のフィールド
tbl_name.col_name   現在のデータベースのテーブル tbl_name 内のフィールド col_name
db_name.tbl_name.col_name   データベース db_name
のテーブル tbl_name 内のフィールド col_name。この形式は 3.22 以降
で有効です。

`column_name`   キーワードであったり特殊文字を含むフィールド。

参照が曖昧でないならば、ステートメント中のフィールド参照の前に tbl_name または db_name.tbl_name を記述する必要はありません。例えば、テーブル t1 と t2 がそれぞれフィールド c を含み、t1 と t2 の両方を使用する SELECT ステートメントで c を取り出すとします。この場合、c はステートメントで使用されるテーブル間で唯一でないので曖昧です。そのため、t1.c または t2.c と記述するこよによりどちらのテーブルを意味するかを示す必要があります。同様に、データベース db1 のテーブル t とデータベース db2 のテーブル t から取り出す場合、これらのテーブル中の項目は、db1.t.col_name と db2.t.col_name として参照する必要があります。

構文 .tbl_name は現在のデータベース内のテーブル tbl_name を意味します。この構文はいくつかの ODBC が . 文字をテーブル名の前に置くために許されています。

名前のケース依存性
.........

MySQL では、データベースとテーブルは、ディレクトリとそのディレクトリ中のファイルに対応します。そのため、下で動作するオペレーティングシステムのケース依存性は、データベースとテーブル名のケース依存性を決定します。データベース名とテーブル名は Unix ではケース依存で、Win32 ではケース非依存です。

注意: Win32 ではデータベース名とファイル名はケース非依存ですが、同じクエリ内で、データベースやテーブルを異なるケースを使用して参照すべきではありません。以下のクエリは動きません。なぜなら my_table と MY_TABLE の両方を参照しているからです：

     mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;

フィールド名は全ての場合でケース非依存です。

テーブルの別名はケース依存です。以下のクエリは動きません。なぜなら a と A のエイリアスを両方参照しているからです：

     mysql> SELECT col_name FROM tbl_name AS a
                WHERE a.col_name = 1 OR A.col_name = 2;

フィールドのエイリアス名はケース非依存です。

ユーザー変数
======

MySQL は、@variablename 構文でスレッド固有の変数をサポートします。変数名は現在の文字セットのアルファベットと数字、それに _、$、. 文字からなります。デフォルト文字セットは ISO-8859-1 Latin1 です。これは mysqld に --default-character-set オプションを与えることで変更できます. (3.23.14 以上の場合のみ。それ以前のバージョンでは MySQL 再コンパイルが必要) see Character sets。

変数は初期化する必要はありません。デフォルトでは NULL であり、整数値、実数値、文字列値を格納できます。すべてのスレッド変数は、スレッドが終了すると自動的に解放されます。

SET 構文で変数を設定できます:

     SET @variable= { integer expression | real expression | string expression }
     [,@variable= ...].

@variable:=expr 構文で、式中で変数を設定することも可能です:

     select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
     +----------------------+------+------+------+
     | @t1:=(@t2:=1)+@t3:=4 | @t1  | @t2  | @t3  |
     +----------------------+------+------+------+
     |                    5 |    5 |    1 |    4 |
     +----------------------+------+------+------+

(我々は := 構文を使用する必要がありました。= は比較のために予約されていたからです。)

ユーザー変数は式が許される場所で使用できます。注意: これは現在、 SELECT ステートメントの LIMIT 節、LOAD DATA ステートメントの IGNORE number LINES 節のように、数値が明示的に要求される文脈での使用を含みません。

注意: SELECT ステートメントでは、それぞれの式はクライアントに送られた時にだけ評価されます。これは、SELECT 部で設定された変数を必要とする式を参照する HAVING, GROUP BY, ORDER BY 節ができないことを意味します。例えば、次のステートメントは期待通りには動作しません:

     SELECT (@aa:=id) AS a, (@aa+3) AS b FROM table_name HAVING b=5;

この理由は、@aa が現在のレコードの値ではなく、前に受け取ったレコードの id の値になるからです。

フィールド型
======

MySQLは多くのフィールド型をサポートしており、それらは３つのカテゴリにグループ化されます: 数値型、日付及び時間型、そして文字列(文字)型。この章ではまず、利用できる型の概要から始まり、それから各カテゴリの各フィールド型の所要記憶容量の要約と、型の属性についてのより詳細な情報を提供します。概要は意図的に簡潔にまとめています。値として指定できる書式のようなフィールド型固有の付加情報は、詳細の説明部にて調べて下さい。

MySQLでサポートされるフィールド型は以下に示す通りです。後に続く文字の意味は説明のために使われます:

M
     最大表示サイズを意味します。最大の表示桁数は 255.

D
     浮動小数点数型に適用され、小数点以下の桁数を表します。最大の値は 30 ですが、これは M-2 より大きくなってはいけません。

中カッコ([及び])は型定義の一部であり、それがオプションであることを表します。

もしあるフィールドに ZEROFILL を指定した場合、 MySQL は自動で UNSIGNED 属性をそのフィールドに追加します。

TINYINT[(M)] [UNSIGNED] [ZEROFILL]

     とても小さい整数。符号つきの範囲は -128〜127。符号なしの範囲は 0〜255。

SMALLINT[(M)] [UNSIGNED] [ZEROFILL]

     小さい整数。符号つきの範囲は -32768〜32767。符号なしの範囲は 0〜65535。

MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]

     中間の整数。符号ありの範囲は -8388608〜8388607。符号なしの範囲は 0〜16777215

INT[(M)] [UNSIGNED] [ZEROFILL]

     通常の整数。符号ありの範囲は -2147483648〜2147483647。符号なしの範囲は 0〜4294967295

INTEGER[(M)] [UNSIGNED] [ZEROFILL]

     これは、INTの同義語です。

BIGINT[(M)] [UNSIGNED] [ZEROFILL]

     大きい整数。符号ありの範囲は -9223372036854775808〜9223372036854775807。符号なしの範囲は 0〜18446744073709551615。全ての演算は符合付き BIGINT または DOUBLE で行われるため、符合無しの 9223372036854775807 (63 bits) よりも大きな整数をビット関数以外で使用すべきではありません！ -、+及び*は、両方の引数がINTEGER値の時、BIGINT演算を使うことに注意して下さい！これは、２つの大きな整数のかけ算を行なう(又は整数を返す関数の結果が大きな整数である)時、結果が9223372036854775807よりも大きい場合に予期しない結果を受け取ることがあるということを意味しています。

FLOAT(precision) [ZEROFILL]

     浮動小数点数。符号なしにはできません。単精度浮動小数点数では precision が <=24 で、倍精度浮動小数点数では 25〜53 の間です。これらの型は次で述べるFLOATやDOUBLE型に似ています。 FLOAT(X)は、FLOAT及びDOUBLE型に一致する同じ範囲を持っていますが、表示サイズや小数点以下桁数が定義されません。

     MySQL 3.23 では、これは正しい浮動小数点です。前の MySQL バージョンでは, FLOAT(precision) は常に小数部は2桁でした。

     この構文は ODBC 互換です。

FLOAT[(M,D)] [ZEROFILL]

     小さい浮動小数点数。符号なしにはできません。範囲は -3.402823466E+38〜-1.175494351E-38、 0、 1.175494351E-38〜3.402823466E+38です。 M は表示幅で D は小数部桁数です。引数が無いか引数が24以下の FLOAT は単精度浮動小数点数を意味します。

DOUBLE[(M,D)] [ZEROFILL]

     通常の浮動小数点数。符号なしにはできません。範囲は -1.7976931348623157E+308〜-2.2250738585072014E-308、 0、2.2250738585072014E-308〜1.7976931348623157E+308です。 M は表示幅で D は小数部桁数です。引数が無いか DOUBLE か、25 <= X <= 53 である FLOAT(X) は倍精度浮動小数点数を意味します。

DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]

     これらはDOUBLEの同義語です。

DECIMAL[(M[,D])] [ZEROFILL]

     パック無し浮動小数点数。符号なしにはできません。CHARフィールドのように振舞います。`パック無し'は、数値が文字列として格納されることを意味し、数値のそれぞれの桁、小数点、及び負数での-符号に１文字使用します。 Dが0の時、値は小数点や小数部を持ちません。DECIMAL値の最大範囲はDOUBLEと同じですが、実際の範囲はDECIMALフィールドに与えられたM及びDの選択に強制されます。

     D を省略した場合は 0 に設定されいます。M を省略した場合は 10 に設定されます。

     MySQL 3.22 では、 M 引数は符号や小数点を含みます。

NUMERIC(M,D) [ZEROFILL]

     DECIMALと同じ。

DATE

     日付。サポートされる範囲は'1000-01-01'から'9999-12-31'まで。 MySQLは'YYYY-MM-DD'の書式でDATE値を表示しますが、DATEフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。

DATETIME

     日付と時刻の組み合わせ。サポートされる範囲は'1000-01-01 00:00:00'〜'9999-12-31 23:59:59'です。MySQLはDATETIME値を'YYYY-MM-DD HH:MM:SS'という書式で表示しますが、DATETIMEフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。

TIMESTAMP[(M)]

     タイムスタンプ。範囲は'1970-01-01 00:00:00'〜2106年末までです。MySQLはTIMESTAMP値をYYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD又はYYMMDDという書式で表示し、それはMに14(もしくは誤ってそれ以上の値を指定した時)、12、8又は6のいずれが指定されたかに依存します。しかしながらTIMESTAMPフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。 TIMESTAMPフィールドは、最後に操作された時刻を自動的に設定するので、INSERTやUPDATE操作の時刻を記録するのに役立ちます。 NULL値を与えることによっても、現在時刻を設定できます。 See Date and time types。

TIME

     時間。範囲は'-838:59:59'〜'838:59:59'です。 MySQLはTIME値を'HH:MM:SS'という書式で表示しますが、TIMEフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。

YEAR[(2|4)]

     年。2桁または4桁形式(デフォルトは4桁)。許される値は、4桁形式では 1901〜2155, 0000 で、2桁形式(70〜69)では 1970〜2069 です。MySQL は YEAR 値を YYYY 形式で表示しますが、 YEAR フィールドへの値の割り当ては文字列と数字のどちらでも使用できます。(YEAR は MySQL 3.22 での新しい型です。)

[NATIONAL] CHAR(M) [BINARY]

     固定長文字列で、格納時には必ず指定された長さまで右側に空白を埋めます。 Mの範囲は 1 から 255 文字です。後続の空白は値の取り出し時に削除されます。BINARY キーワードが与えられない場合、CHAR 値のソートと比較は、デフォルト文字セットに従ってケース非依存の方法で行なわれます。

     NATIONAL CHAR (短い形式は NCHAR) は、ANSI SQL で、CHAR フィールドがデフォルト文字セットを使用することを定義する方法です。これは MySQL ではデフォルトです。

     CHAR は CHARACTER の略記です。

     MySQL は CHAR(0) 型のフィールドの生成を許します。これは主に、実際にはもう値が使われていないフィールドが存在することに依存しているようないくつかの古いアプリケーションに対応する必要がある時に便利です。２つの値だけを取ることができるフィールドを必要とする時にもとても良いことです: NOT NULL として定義されていない CHAR(0) は1ビットだけを占有し、２つの値だけを取ることができます: NULL または ""。

[NATIONAL] VARCHAR(M) [BINARY]

     可変長文字列。  注意: 後続の空白は格納時に削除されます(これは ANSI SQL 仕様と異なります)。 Mの範囲は 1 から 255 文字です。 BINARY キーワードが与えられない場合、ソートと比較はケースに依存しません。 See Silent column changes.

     VARCHAR は CHARACTER VARYING の略記です。

TINYBLOB
TINYTEXT

     最大長 255 (2^8 - 1) 文字の TEXT/BLOB。See Silent column changes.

BLOB
TEXT

     最大長 65535 (2^16 - 1) 文字の TEXT/BLOB。See Silent column changes.

MEDIUMBLOB
MEDIUMTEXT

     最大長 16777215 (2^24 - 1) 文字の TEXT/BLOB。See Silent column changes.

LONGBLOB
LONGTEXT

     最大長 4294967295 (2^32 - 1) 文字の TEXT/BLOB。See Silent column changes.

ENUM('value1','value2',...)

     列挙。対象となる文字列は、値を一つだけ持ち、値リスト'value1', 'value2',...(又はNULL)から選ばれます。ENUMは最大65535個の固有値を持つことができます。

SET('value1','value2',...)

     組。対象となる文字列は0以上の値を持ち、それぞれ値リスト'value1', 'value2',...から選ばれなければなりません。 SETは、最大 64個の要素を持つことができます。

フィールドタイプの所要容量
-------------

MySQLがサポートする各フィールドタイプ毎の所要容量を、カテゴリ別に以下に記述します。

数値タイプ
-----

フィールドタイプ   所要容量
TINYINT         1 byte
SMALLINT        2 bytes
MEDIUMINT       3 bytes
INT             4 bytes
INTEGER         4 bytes
BIGINT          8 bytes
FLOAT(X)        X <= 24 の場合 4、25 <= X <= 53 の場合 8
FLOAT           4 bytes
DOUBLE          8 bytes
DOUBLE PRECISION   8 bytes
REAL           8 bytes
DECIMAL(M,D)   M bytes (M < D の場合 D+2)
NUMERIC(M,D)   M bytes (M < D の場合 D+2)

日付と時間タイプ
--------

フィールドタイプ   所要容量
DATE            3 bytes
DATETIME        8 bytes
TIMESTAMP       4 bytes
TIME            3 bytes
YEAR            1 byte

文字列タイプ
------

フィールドタイプ   所要容量
CHAR(M)   M bytes, 1 <= M <= 255
VARCHAR(M)   L+1 bytes, where L <= M and
1 <= M <= 255
TINYBLOB, TINYTEXT   L+1 bytes,
where L < 2^8
BLOB, TEXT   L+2 bytes,
where L < 2^16
MEDIUMBLOB, MEDIUMTEXT   L+3 bytes,
where L < 2^24
LONGBLOB, LONGTEXT   L+4 bytes,
where L < 2^32
ENUM('value1','value2',...)   1 or 2 bytes, 列挙値の数に依存 (最大値は 65535 )
SET('value1','value2',...)   1, 2, 3, 4 or 8 bytes, 要素の数に依存 (最大要素 64 )

VARCHAR、BLOB、及びTEXT型は可変長型であり、所要容量は、フィールドのとり得る最大サイズというよりはむしろフィールド値の実際の長さに依存します(前の表でLと表しました)。例えば、VARCHAR(10)フィールドは、最大10文字分の長さの文字列を保持することが出来ます。実際の所要容量は、文字列の長さ(L)と、その長さを記録するための１バイトを加えます。文字列'abcd'においては、Lは４で、所要容量は５バイトです。

BLOBとTEXT型は、フィールド値の長さを記録するのに、１、２、３、又は４バイト必要とし、型のとり得る最大の長さに依存します。

テーブルが可変長フィールド型を含む場合、そのレコードフォーマットもまた可変長となるでしょう。テーブルが作成された時、MySQLは確かな条件の下、フィールドを可変長タイプから固定長タイプへ変更し、副作用を起こすことに注意して下さい。

ENUMオブジェクトのサイズは、異なる列挙値の数によって決められます。列挙する数が255以内では、１バイトが使用されます。列挙する数が65535以内では、２バイトが使用されます。

SETオブジェクトのサイズは、異なる要素の数によって決められます。組のサイズをNとすると、オブジェクトは(N+7)/8バイトを占有し、１、２、３、４又は８バイトに切上げられます。１つのSETは、最大６４要素を持つことができます。

数値型
---

MySQL は ANSI/ISO SQL92 数値型をすべてサポートします。これらの型は正確な数値データ型(NUMERIC, DECIMAL, INTEGER, SMALLINT)、近似数値型(FLOAT, REAL, DOUBLE PRECISION)を含みます。キーワード INT は INTEGER の同義語で、 DECは DECIMAL の同義語です。

MySQL では NUMERIC と DECIMAL 型は、SQL92 標準で許されているように同じ型として実装されています。これらは正確な精度を維持することが重要な値(例えば金銭データ)に使用されます。これらの型の一つのフィールドを宣言する時、精度と大きさが指定できます(通常はそうします); 例えば:

         salary DECIMAL(9,2)

この例では、9 (precisoin) は値を格納する重要な数値の桁数を表します。そして 2 (scale) は小数点に続いて格納される桁数を表します。従って、この場合 salary フィールドに格納することができる値の範囲は、-9999999.99 から 9999999.99 です。ANSI/ISO SQL92 では、構文 DECIMAL(p) は DECIMAL(p,0) と等しいです。同様に、構文 DECIMAL は DECIMAL(p,0) と等しいです。ここで p の値の決定は実装に許されてます。DECIMAL/NUMERIC データ型のこれらの異なる形式は、MySQL は現在サポートしていません。この型の主な利益は精度と大きさの両方を明示的に制御する機能から引き出されるので、これは通常深刻な問題ではありません。

DECIMAL と NUMERIC 値は、値の小数の精度を維持するため、バイナリ浮動小数点数としてではなく、文字列として格納されます。1文字は値のそれぞれの桁(scale > 0 の場合)と - 記号(負数の場合)に使用されます。scale が 0 の場合、DECIMAL と NUMERIC 値は小数点と小数部を含みません。

DECIMAL と NUMERIC 値の最大範囲は DOUBLE と同じです。しかし DECIMAL や NUMERIC フィールドに与えられる実際の範囲はフィールドに与えられた precision と scale によって強制されます。このフィールドに、指定された scale で許されるよりも多い桁の小数部を持つ数値が割り当てられた場合、値はその scale に丸められます。 DECIMAL や NUMERIC フィールドに、指定された(またはデフォルトの) precision と scale で示された範囲を超えた大きさの値を割り当てた時、MySQL はその範囲の対応する最大値を表す値を格納します。

ANSI/ISO SQL92 標準に対する拡張として、上の表にリストしたように、 MySQL は整数型 TINYINT, MEDIUMINT, BIGINT もサポートします。MySQL によってサポートされる他の拡張として、オプションで、型の基本キーワードに続けて括弧内に指定する整数値の表示幅(例えば INT(4))があります。このオプションの幅指定は、フィールドに指定された幅よりも少ない幅の値の表示の左側を埋めるために使用されます。しかしフィールドに格納することができる値の範囲や、フィールドに指定された幅を超える幅の値について表示される桁数は制約されません。オプションの拡張属性 ZEROFILL を指定して使用された場合、デフォルトの埋められる空白は 0 で置き換えられます。例えば、INT(5) ZEROFILL として宣言されたフィールドでは、値 4 は 0004 として取り出されます。注意: 整数フィールド内に表示幅よりも大きい値を格納する場合、MySQL が複雑な join のために一時テーブルを生成する時に、問題を体験するでしょう。この場合 MySQL はデータがオリジナルのフィールド幅に合っていることを信用するためです。

すべての整数型はオプションの(非標準)属性 UNSIGNED を持つことができます。符合無しの値はフィールド内に正の数だけを許可したくて、フィールドに対して少し大きい数値の範囲が必要な時に使用できます。

FLOAT 型は近似数データ型を表すために使用されます。ANSI/ISO SQL92 標準は、FLOAT キーワードに続く括弧中にオプションの精度(指数の範囲ではない)の指定を許しています。MySQL 実装はこのオプションの精度指定もサポートしています。キーワード FLOAT が精度の指定無しでフィールド型として使用された時は、MySQL は値を格納するために4バイトを使用します。FLOAT キーワードに続く括弧中に2つの数値を与える構文もサポートされます。このオプションでの、最初の数値は値に必要な容量をバイトで表します。 2番目の数値は、格納、表示される小数部の桁数を指定します(DECIMAL と NUMERIC と同様)。MySQL がフィールドに指定されたよりも大きい小数部の桁数を持つ数値をこのフィールドに格納する時、値の格納時に余計な桁を取り除くように値が丸められます。

REAL と DOUBLE PRECISION 型は精度指定を許しません。 ANSI/ISO SQL92 標準に対する拡張として、MySQL は DOUBLE を DOUBLE PRECISION 型の同義語として認識します。REAL の精度は DOUBLE PRECISION の指定よりも小さいことを要求する標準と異なり、 MySQL はどちらも8バイトの倍精度小数点の値として実装しています ("ANSI モード"で実行していない場合)。移植性を最大にするためには、近似数値データ値の格納を要求するコードは、精度や小数部桁数の指定無しの FLOAT か DOUBLE PRECISION を使用すべきです。

フィールドの型の値の許容範囲を超えた数値を代入しようとすると、MySQL はその値を許容範囲いっぱいに切り詰め、その結果を代わりに代入します。

例えば、 INT フィールドの範囲は -2147483648 から 2147483647 です。もし -9999999999 を INT フィールドに挿入しようとすると、値は範囲の最低値に修正され、 -2147483648 が代わりに代入されます。同様に、9999999999 の場合、 2147483647 が代わりに代入されます。

そして、INT フィールドが符号無しの場合、フィールドの範囲の大きさは同じですが、限界値は 0 と4294967296 になります。もし -9999999999 と 9999999999 を代入しようとすると、値は 0 と 4294967296 として代入されます。

ALTER TABLE, LOAD DATA INFILE, UPDATE または multi-row INSERT 時、これらの変換は `警告' として得られます。

日付と時間の型
-------

日付と時間の型は DATETIME, DATE, TIMESTAMP, TIME, YEAR です.  これらはそれぞれ値に適正な範囲があり、 ``zero'' はあなたが間違った値を指定した場合に用いられます。注意: MySQL は確実に '厳密でない' 正しい日付の値、例えば 1999-11-31 を格納することができます。この理由は、日付をチェックする処理の責任はアプリケーションにあり、SQL サーバにはないと考えているからです。日付を'速く'チェックするために、MySQL は月が 0〜12 の範囲であるかと日が 0〜31 の範囲であるかだけをチェックします。上述の範囲は、MySQL が DATE または DATETIME フィールドに、日または月日が 0 である日付を格納できるために定義されています。これは、正確な日付を知らない誕生日を登録する必要があるアプリケーションに非常に有用です。この場合、1999-00-00 や 1999-01-00 のような日付を単純に登録できます(もちろん、このような日付を DATE_SUB() や DATE_ADD のような関数で使用して、正しい値が返ることは期待できません)。

これは、日付と時間型で作業する場合に、一般的に考慮しなければならないことです:

  * MySQLは、標準形式で与えられた日付や時間から値を抽出しますが、与えられた多様な形式の値(例えば、指定された値を日付や時間型に割り当てたり、比較したり)を解釈しようと試みます。それでも、次節で述べる形式だけがサポートされます。それは、正当な値が与えられることを期待し、他の形式の値を使用されるような事態が起こると、どのような結果となるか予想できません。

  * MySQL はいくつかの形式に値を変えてくれますが、常に年の部分と日にちの部分は左から与えられていると期待しています。日付は 年-月-日 の順(例えば、'98-09-04')でなくてはなりません。月-日-年 や 日-月-年 の様などこでも使われているような形であってはなりません。 (例えば、'09-04-98'や'04-09-98').

  * MySQL は、もし数値の文脈で日付と時間の型が使用されると、自動的に日付と時間を数値に直します。逆も行います。

  * MySQL が範囲外の誤った値を日付と時間型として受け取った場合 (このセクションの最初をみてください)、その値は ``ゼロ'' に変換されます。 (例外は、範囲外のTIME値が適切なTIMEの範囲の限界値に切り詰められることです。) 以下に、それぞれの型の `ゼロ' の形式を示します：

     フィールドタイプ   `ゼロ'値
     DATETIME        '0000-00-00 00:00:00'
     DATE            '0000-00-00'
     TIMESTAMP       00000000000000 (length depends on display size)
     TIME            '00:00:00'
     YEAR            0000

  * `ゼロ'値は特別ですが、表に示された値を明示的に使用して、格納したり参照したりできます。この値は、 '0' 又は 0 を使用することにより、より簡潔に書くこともできます。

  * MyODBC 内で使用されている `ゼロ' の日付と時間は、 MyODBC 2.50.12 以上では自動的に NULL に変換されます。これは ODBC がこれらの値を扱えないからです。

西暦２０００年問題とデータ型
..............

MySQL 自体は2000年問題に対して安全です(see Year 2000 compliance)が、 MySQL に提示される入力値に関してはそうではありません。2桁の年の入力は何世紀なのかわからないので全て曖昧です。このような値は MySQL が内部で年に4桁を使っていることから4桁の形式に変換されてしまいます。

MySQL は曖昧な日付を DATETIME, DATE, TIMESTAMP および YEAR 型に関して、以下のルールに従って解釈します。

  * 00-69 の範囲の年は 2000-2069 に変換。

  * 70-99 の範囲の年は 1970-1999 に変換。

これらのルールはデータが何を意味しているかに対して妥当な推定を与えるに過ぎないことに注意してください。この MySQL 発見的手法が正しい値を生成しない場合は曖昧でない4桁の年を含む入力を与えるべきです。

ORDER BY は2桁の YEAR/DATE/DATETIME 型を正しくソートされます。

注意: MIN() と MAX() のようないくつかの関数は TIMESTAMP/DATE を数値に変換します。これは年が2桁のタイムスタンプはこれらの関数で正しく動作しないことを意味します。この場合の修復は、TIMESTAMP/DATE を4桁の年の形式に変換するか、MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS)) のような何かを使用することです。

DATETIME, DATE, TIMESTAMP 型
...........................

DATETIME, DATE, TIMESTAMP型はお互いに関連しています。このセクションではそれらの特徴と、それぞれがどう同じでどう違うかを示します。

DATETIME 型は日付と時刻の情報を含む値が必要な場合に使います。MySQL は DATETIME 値を 'YYYY-MM-DD HH:MM:SS' のフォーマットで取り出し、表示します。サポートされる範囲は '1000-01-01 00:00:00' から '9999-12-31 23:59:59' です。 (「サポートされる」とはさらに過去の値でも動くかも知れませんが保証の限りではないという意味です)

DATE 型は時刻の部分なしで日付の値のみが必要な場合に使います。MySQL は DATE 値を'YYYY-MM-DD' のフォーマットで取り出し、表示します。サポートされる範囲は '1000-01-01' から '9999-12-31' です。

TIMESTAMP タイプは INSERT や UPDATE 操作に自動的に現在の日付と時刻をマークする場合に提供される型です。もし複数の TIMESTAMP フィールドがある場合には最初の一つだけが自動的に更新されます。

最初の TIMESTAMP フィールドの自動更新は以下のいずれかの条件で起こります：

  * そのフィールドが明示的に INSERT または LOAD DATA INFILE 文で指定されていないとき。

  * そのフィールドが明示的に UPDATE 文で指定されず、かつ、他のフィールドの値が変わった場合。 (もともとフィールドに入っていた値と同じ値に更新しようとする UPDATE 文は TIMESTAMP フィールドを更新しないことに注意。なぜならあるフィールドを現在と同じ値に変えようとしても MySQL は効率のためにそれを無視するからです。)

  * 明示的に TIMESTAMP フィールドを NULL にした場合。

最初以外の TIMESTAMP フィールドも現在の日付と時刻にすることができます。それらのフィールドを NULL または NOW() にすることです。

どの TIMESTAMP フィールドも明示的に望む値をセットすることで現在の日時でない値にすることができます。それは最初の TIMESTAMP フィールドについても同じです。この特性は例えば TIMESTAMP フィールドをあるレコードが生成されたときの日時にし、その後その行が更新されても変化しないようにしたいというようなときに使えます。

  * MySQL にレコードが生成されたときにそのフィールドをセットさせる。これで現在日時に初期化される。

  * 以降の他のフィールドに対する更新時に TIMESTAMP フィールドをそれ自体が今持っている値に明示的に更新する。

一方、この手法は DATATIME フィールドを行生成時に NOW() で初期化し、以降の更新時にそれをほうっておくのと同じように簡単であるとわかるでしょう。

TIMESTAMP の値は 1970 年の最初から 2037 年のどこかの時点までの範囲で有効で、 1秒の時間分解能を持ちます。値は数値として表示されます。

MySQL が TIMESTAMP 値を取り出したり表示するのに使うフォーマットは以下の表に示すようにその表示サイズに依存します。「目一杯の」 TIMESTAMP フォーマットは14桁ですが、 TIMESTAMP フィールドはより短い表示サイズで生成することもできます：

フィールド型    表示フォーマット
TIMESTAMP(14)    YYYYMMDDHHMMSS
TIMESTAMP(12)    YYMMDDHHMMSS
TIMESTAMP(10)    YYMMDDHHMM
TIMESTAMP(8)     YYYYMMDD
TIMESTAMP(6)     YYMMDD
TIMESTAMP(4)     YYMM
TIMESTAMP(2)     YY

全ての TIMESTAMP フィールドは表示サイズに関係なく同じ格納サイズを持ちます。もっとも一般的な表示サイズは 6 , 8 , 12 および 14 です。表示サイズはテーブル生成時に任意の値に指定できますが、 0 および 14 以上の値は強制的に 14 になります。1 から 13 までの奇数のサイズは強制的に一つ大きい偶数になります。

DATETIME, DATE, TIMESTAMP 値は以下の共通フォーマットセットのいずれかを使って指定できます：

  * 文字列で 'YYYY-MM-DD HH:MM:SS' か 'YY-MM-DD HH:MM:SS' の形式。 "柔軟な"書き方を許しています -- 日付や時刻の区切り文字として、いかなる句読記号も使用できます。例えば、'98-12-31 11:30:45', '98.12.31 11+30+45', '98/12/31 11*30*45', '98@12@31 11^30^45' は等価です。

  * 文字列で 'YYYY-MM-DD' か 'YY-MM-DD' の形式。これも"柔軟な"書き方ができます。例えば, '98-12-31','98.12.31', '98/12/31', '98@12@31' は等価です。

  * 文字列 'YYYYMMDDHHMMSS' または 'YYMMDDHHMMSS' フォーマット。「緩やかな」文法が認められていて、句読記号は日付、時刻部分の区切りとして使えます。例えば '98-12-31 11:30:45',  '98.12.31 11+30+45', '98/12/31 11*:30*:45',  '98@12@31 11^30^45' は全て等価です。

  * 文字列 'YYYY-MM-DD' または 'YY-MM-DD' フォーマット。これも「緩やかな」文法が認められています。例えば '98-12-31',  '98.12.31',  '98/12/31', '98@12@31' は全て等価です。

  * 区切り文字なしの文字列 'YYYYMMDDHHMMSS' または 'YYMMDDHHMMSS' フォーマットで日時として意味のあるもの。例えば '19970523091528' および '970523091528' は '1997-05-23 09:15:28' と解釈されます。しかし '971122129015' は無効で (時と分の部分がおかしい)、 '0000-00-00 00:00:00' になります。

  * 区切り文字なしの文字列 'YYYYMMDD' または 'YYMMDD' フォーマットで、日付として意味のあるもの。例えば '19970523' および '970523' は '1997-05-23' と解釈されます。しかし '971332' は無効で(月と日の部分がおかしい)、 '0000-00-00' になります。

  * YYYYMMDDHHMMSS または YYMMDDHHMMSS のフォーマットの数値で、日時として意味のあるもの。例えば 19830905132800 および 830905132800 は '1983-09-05 13:28:00' と解釈されます。

  * YYYYMMDD または YYMDD のフォーマットの数値で日付として意味のあるもの。例えば 19830905 および 830905 は '1983-09-05' として解釈されます。

  * NOW() や CURRENT_DATE のように DATETIME , DATE , TIMESTAMP のコンテキストでアクセス可能な値を返す関数の結果。

無効な DATETIME , DATE , TIMESTAMP の値は適切な「ゼロ」値に変換されます( '0000-00-00 00:00:00' , '0000-00-00' または 00000000000000 )。

日時の部分に区切りを持つ文字列で指定される値で、月、日の値が10未満の場合は2桁で指定しなくてもかまいません。 '1979-6-9' は '1979-06-09' と等価です。同様に時刻の部分に区切りを持つ文字列で指定される値で、時、分、秒が 10 未満の場合は2桁で指定しなくてもかまいません。 '1979-10-30 1:2:3' は '1979-10-30 01:02:03' と等価です。

数値でしていされる値は 6, 8, 12 または 14 桁である必要があります。もしその数値が 8 または 14 桁の長さの時はそれぞれ YYYYMMDD および YYYYMMDDHHMMSS フォーマットで、最初の 4 桁で年が与えられるものと仮定されます。もしその数値が 6 または12桁の長さの時は YYMMDD および YYMMDDHHMMSS フォーマットで最初の2桁で年が与えられるものと仮定されます。これら以外の長さの数値はあとに 0 が追加されてこれらのうちのもっとも近い長さのものと解釈されます。

区切りなしの文字列で与えられる値はそれ自身の長さを使って解釈されます。もし文字列が8または14文字ならば年は最初の4文字で与えられると仮定されます。そうでなければ最初の2文字で与えられると仮定されます。文字列は左から右に年、月、日、時、分、秒と文字列中に表現されている分だけ順に解釈されます。つまり6文字以下の文字列は使ってはいけないということです。例えば1999年3月を指定するつもりで '9903' を指定した場合、 MySQL は「ゼロ」日付をテーブルに挿入します。これは年と月の部分は 99 と 03 ですが日の部分が欠けている(ゼロ)ために値が有効な日付でないために起こります。

TIMESTAMP フィールドは有効な値を、表示サイズに関係なく指定された値を最高精度の時間分解能で格納します。このことはいくつかの意味合いを持ちます。

年の値が二桁で指定された場合、世紀の部分がないので曖昧な値となります。 MySQL は二桁の年の値を以下に示す規則にそって変換します：

  * 列の型がTIMESTAMP(4)であってもTIMESTAMP(2)であっても常に年月日を指定すること。そうでなければ値は無効で0が格納されます。

  * もし短い形式の TIMESTAMP を ALTER TABLE を使って拡張しようとした場合、拡張前には「隠れていた」情報が現れます。

  * 同様に TIMESTAMP フィールドを縮めた場合も、値が表示された時により少ない情報しか現れないという点を除いて、情報は失われません。

  * TIMESTAMP 値は最高精度の時間分解能で格納されますが、内部的に格納された値を直接操作できる関数は UNIX_TIMESTAMP() のみです。他の関数はフォーマットされて取り出された値について操作します。つまり、 HOUR() や SECOND() などの関数は TIMESTAMP 値の対応する部分がフォーマットされた値で含まれないと使うことができません。例えば TIMESTAMP 列の HH の部分は表示サイズが少なくとも10以上ないと表示されないので、それより短い TIMESTAMP 値に HOUR() の操作を行っても無意味な値しか得られません。

ある日付型を他の日付型のオブジェクトに拡張して指定することができます。しかしそれは値の変化や情報の欠落を起こす可能性があります。

  * DATE の値を DATETIME か TIMESTAMP の物に与えた場合、時刻の部分は '00:00:00' になります。これは DATE 値が時刻の情報を持っていないからです。

  * DATETIME か TIMESTAMP の値を DATE の物に与えた場合、時刻の部分は削られます。これは DATE 値が時刻の情報を持っていないからです。

  * DATETIME, DATE, TIMESTAMP 値は同じフォーマットのセットを使って表現できますが、どの型も同じ値の範囲を持っているわけではないことを覚えておいてください。例えば TIMESTAMP 値は 1970 年より前や 2037 年より後の値にはできません。つまり '1968-01-01' という値は DATETIME や DATE の値としては有効ですが TIMESTAMP の値としては無効で、そのようなオブジェクトを指定した場合は 0 に変換されます。

日付の値を指定するときの落とし穴に注意してください:

  * 文字列として指定される値の柔軟なフォーマットに騙されないよう。例えば '10:11:12' は ':' を区切り文字とする時刻のように見えますが、日付のコンテキストで使われるとこれは '2010-11-12' と解釈されます。'10:45:15' は '45' が有効な月ではないので '0000-00-00' に変換されます。

  * 2桁で表される年は世紀の部分が不明なので曖昧です。 MySQL は以下のルールで2桁の年を解釈します。

       - 00-69 の範囲にある年の値は 2000-2069 年とする。

       - 70-99 の範囲にある年の値は 1970-1999 年とする。

TIME 型
......

MySQL は TIME の値を 'HH:MM:SS' (時の部分が大きい場合は 'HHH:MM:SS') というフォーマットで扱い、また表示します。 (時の部分が大きい場合は 'HHH:MM:SS')。 TIME 値の範囲は '-838:59:59' から '838:59:59' の範囲です。時の部分がこんなに大きいのは、TIME 型は一日すなわち24時間以内の時刻を表現するのに用いられるだけではなく経過時間や二つの事象の間隔 (どちらも２４時間を越えたり、負の数になる場合もあります)を表現することもあるからです。

TIME 値は様々なフォーマットで指定可能です：

  * 文字列で 'D HH:MM:SS.fraction' というフォーマット。 (MySQLはまだこの fraction を time フィールドに保存できません)。以下の ``柔軟な'' 文法が使用できます：

     HH:MM:SS.fraction, HH:MM:SS, HH:MM, D HH:MM:SS, D HH:MM, D HH or SS.  Here D is days between 0-33.

  * 文字列で 'HHMMSS' というように区切りのないフォーマットで時刻として有効なもの。例えば '101112' は '10:11:12' と解釈されますが '109712' は無効で(分の部分が無意味) '00:00:00' になります。

  * 数値で HHMMSS のフォーマットで時刻として有効なもの。例えば 101112 は '10:11:12' と解釈されます。次の別の形式も解釈できます: SS, MMSS,HHMMSS, HHMMSS.fraction。注意: MySQL はまだ fraction 部を保存できません。

  * 例えば CURRENT_TIME のように TIME のコンテキストで受け付けられる値を返す関数の結果。

文字列で時刻の各部の区切りを含む TIME の値については、時、分、秒が 10 以下の場合、２桁の数字を指定する必要はありません。'8:3:2' は '08:03:02' と同じです。

「短い」 TIME 値を TIME フィールドとして指定する場合は要注意です。 MySQL はその値をもっとも右端の桁は秒を表すと仮定して解釈します (MySQL は TIME の値を一日のうちの時刻としてより経過時間として解釈します)。例えば '11:12','1112', 1112 が '00:11:12' (11時12分)を表しているつもりでいても、 MySQL はこれらを '00:00:12' (11分12秒)として解釈します。同様に '12' および 12 は '00:00:12' と解釈します。

TIME の範囲外にある値で値以外は正しいものは範囲の端の値の適当な方にクリップされます。例えば '-850:00:00' および '850:00:00' はそれぞれ '-838:59:59' および '838:59:59' になります。

無効な TIME 値は '00:00:00' に変換されます。ここで '00:00:00' 自体は有効な TIME 値なので、テーブル内に保存された'00:00:00'という値からそれがもともと '00:00:00' と指定された値なのか無効なために変換された結果なのかを区別する方法はないことに注意してください。

YEAR 型
......

YEAR 型は年を表現するのに使われる1バイトの値です。

MySQL は YEAR の値を YYYY というフォーマットで扱い、また表示します。範囲は 1901 から 2155 です。

YEAR 型は様々なフォーマットで指定可能です：

  * '1901' から '2155' の範囲にある4桁の文字列

  * 1901 から 2155 の範囲にある4桁の数値。

  * '00' から '99' の範囲にある2桁の文字列。 '00' から '69' までおよび '70' から '99' までの範囲はそれぞれ 2000 から 2069 までおよび 1970 から 1999 までの範囲の YEAR型に変換されます。

  * 1 から 99 の範囲にある2桁の数値。1 から 69 までおよび 70 から 99 までの範囲はそれぞれ 2001 から 2069 までおよび 1970 から 1999 までの範囲の YEAR 型に変換されます。 2桁の数値の場合は2桁の文字列の場合と若干異なっている点に注意してください。なぜなら0を数値として指定し、それを2000年として解釈させることができないからです。その場合は文字列で '0' または '00' を指定しなければなりません。そうでなければ数値0は無効なYEAR値を示す 0000 に変換されます。

  * 例えば NOW() のように YEAR コンテキストで受け入れられる値を返す関数の結果。

無効な YEAR 値は 0000 に変換されます。

文字列型
----

文字列型は  CHAR, VARCHAR, BLOB, TEXT, ENUM および SET です。

CHAR 型と VARCHAR 型
.................

CHAR 型と VARCHAR 型はよく似ていますが格納、取り出しの手順に違いがあります。

CHAR フィールドの長さはテーブルを生成するときに宣言した長さに固定されます。長さは 1 から 255 までの値を取ります。CHAR が格納されるときには指定された長さになるように右側に空白が詰められます。CHAR の値が取り出された場合には右側 (後続)の空白は取り除かれます。

VARCHAR フィールドの値は可変長文字列です。 VARCHAR フィールドは CHAR フィールドと同じく 1 から 255 までの長さに宣言できます。 (MySQL 3.23 では, CHAR の長さは 0 から 255 まで許されています.) しかし CHAR 型と異なり VARCHAR 型の値は必要な文字数の分に長さを記録する1 バイトを足した領域に格納されます。値には桁合わせのための空白はつけられません。後続の空白は値の格納時に取り除かれます。(この空白の除去は ANSI SQL仕様とは違っています。)

もし CHAR または VARCHAR フィールドに、フィールドの最大長を越える長さの値を与えた場合は、適合するように切り詰められます。

以下の表はこれらの二つのフィールド型の違いを、CHAR(4) および VARCHAR(4) に様々な文字列値を格納した結果を示すことで表しています。

値    CHAR(4)       必要な格納域   VARCHAR(4)   必要な格納域
''         '    '   4 バイト   ''   1 バイト
'ab'       'ab  '     4 バイト   'ab'   3 バイト
'abcd'     'abcd'       4 バイト   'abcd'   5 バイト
'abcdefgh'   'abcd'       4 バイト   'abcd'   5 バイト

CHAR(4) フィールドの後続の空白は取り出し時にとりのぞかれるので、CHAR(4)および VARCHAR(4) から取り出される値はどの場合でも同じです。

CHAR および VARCHAR フィールドの値はテーブルの生成時に BINARY 属性がつけられない限り、大文字と小文字を区別しないでソート・比較されます。BINARY 属性はその列の値が大文字、小文字を区別して、MySQLサーバを実行しているマシンの ASCII順にソート・比較されることを意味します。

BINARY 属性は「固定的」です。つまり、もし BINARY であると指定されたフィールドが式の中にあると式全体が BINARY の値として比較されるのです。

MySQL はテーブル生成時に何も断らずにCHAR または VARCHAR 型のフィールドを変更する事があります。 See Silent column changes.

BLOB と TEXT 型
.............

BLOB は大きなバイナリ型のオブジェクトで、可変長のデータを保持できます。 4 つの BLOB 型、すなわち TINYBLOB, BLOB, MEDIUMBLOB と LONGBLOB は保持できるデータの最大長が違うだけです。 See Storage requirements.

4 つの TEXT 型、すなわち TINYTEXT, TEXT, MEDIUMTEXT と LONGTEXT は 4 つの BLOB 型に対応し、同じ最大長と格納条件を持っています。 TEXT と BLOB の違いは、 TEXT はケースに依存しないでソートと比較され、 BLOB はケースに依存して(文字コードで)比較されることだけです。いうならば、TEXT は、ケースに依存しない BLOB です。

もし BLOB や TEXT フィールドにそれらの最大長以上の値が与えられた場合、その値はきっちり収まるように切り落とされます。

ほとんどの点で、TEXT フィールドを VARCHAR の大きい物と見なすことが出来ます。同様に、BLOB フィールドは VARCHAR BINARY フィールドの大きくなった物です。違いは、

  * MySQL 3.23.2 以上では、BLOB と TEXT 項にインデックスを持つことが出来ます。それ以前のバージョンではインデックスをもつことが出来ません。

  * VARCHAR フィールドで行っているようには、BLOB と TEXT フィールドの値の後ろについている連続した空白文字は切り落とされません。

  * BLOB と TEXT 項は DEFAULT 値を持つことが出来ません。

MyODBC は BLOB を LONGVARBINARY として、 TEXT を LONGVARCHAR として定義します。

BLOB と TEXT フィールドは極端に長いので、それらを使用する際には、いくつかの困った事にでくわすかもしれません：

  * もし GROUP BY か ORDER BY を BLOB フィールドや TEXT フィールドで使用したいなら、フィールドの値を固定長のものに変換しなくてはなりません。標準的な方法は、 SUBSTRING 関数を使用することです。たとえば：

          mysql> select comment from tbl_name,substring(comment,20) as substr
                 ORDER BY substr;

     もしこれをしない場合、フィールドの最初の max_sort_length バイトがソート時に使用されます。 max_sort_length のデフォルト値は 1024; この値は mysqld サーバー起動時に -O オプションを使用することで変更できます。フィールドの位置を指定することによってか、エイリアスを使用することによって、 BLOB や TEXT の値で group 化できます。

          mysql> select id,substring(blob_col,1,100) from tbl_name
                     GROUP BY 2;
          mysql> select id,substring(blob_col,1,100) as b from tbl_name
                     GROUP BY b;

  * BLOB または TEXT オブジェクトの最大長はその型により決定されますが、あなたがクライアントとサーバの間で実際に送ることができるは最大長は、利用可能なメモリ量とコミュニケーションバッファのサイズによって決定されます。メッセージバッファサイズを変えることができますが、その場合、サーバーとクライアント、両方共に変更しなければなりません。See Server parameters.

それぞれの BLOB, TEXT フィールドは、一意のアロケートされたオブジェクトによって、内部では表されることに注意してください.。これはテーブルが開かれるときに一度だけアロケートされる他のフィールドとは対照的です。

ENUM 型
......

ENUM はストリングオブジェクトで、その値は、通常、テーブル作成時のフィールド定義で列挙された値の中から選ばれます。

値はある状況下では 空文字 ("") か NULL を取ることがあります：

  * もし ENUM に無効な値 (列挙されている値の中に含まれない文字) を代入した場合、 そのエラーになる文字の代わりに空文字が挿入されます。

  * もし ENUM が NULL と定義された場合, NULL はそのフィールドで許可される値となり、デフォルト値が NULL になります。もし ENUM が NOT NULL と定義されたならば、 デフォルト値は、列挙リストの最初の値になります。

列挙されたそれぞれの値はインデックスを持ちます：

  * 列挙リストの要素は 1 から付番されます。

  * 空文字エラーのインデックス値は 0 。これは不正な ENUM 値が与えられているレコードを見つけるために以下のような SELECT 構文が使用できることを意味します：

          mysql> SELECT * FROM tbl_name WHERE enum_col=0;

  * NULL のインデックス値は NULL.

たとえば、フィールドが ENUM("one", "two", "three") と定義されたなら、以下に示す値をとります。 それぞれのインデックス値も示します。

値   インデックス
NULL      NULL
""        0
"one"     1
"two"     2
"three"   3

列挙は最大 65535 個の要素まで可能です。

ENUM フィールドに値を与える場合は大文字小文字は無関係です。しかし、後でフィールドから検索される値は、大文字小文字をもちます。これはテーブル作成時に与えられたリストの値です。

もし ENUM を数値の文脈で検索した場合、そのメンバーを前から数えた時の順番が数値で返ってきます。もし ENUM に数値を代入しようとした場合、その数値の位置にあるメンバーが代入されます。 (しかし、これは LOAD DATA では働きません。これはすべての入力を文字列として扱います。)

ENUM 値は列挙メンバがフィールド指定にリストされた順に従ってソートされます。 (つまり、ENUM 値はインデックス値に従ってソートされます。) 例えば、ENUM("a", "b") ならば "a" が "b" の前にソートされ、 ENUM("b", "a") ならば "b" が "a" の前にソートされます。空文字列は空ではない文字の前にソートされ、 NULL は他の列挙の前に並びます。

ENUM フィールドで指定可能な値のリストを全て取りたいならば、次のようにします： SHOW COLUMNS FROM table_name LIKE enum_column_name そして二番目のフィールドの ENUM 定義を分析します。

SET 型
.....

SET は文字型オブジェクトでゼロかそれ以上を値持ちます。テーブル作成時には、それぞれの値はリストから選ばれるべきです。 SET 型のフィールドの値は、コンマ(,) 区切りで並べられた複数のメンバーで構成されています。これは、 SET メンバーの値中にコンマを含むことが出来ない、ということです。

例えば、 SET("one", "two") NOT NULL と指定されたフィールドは以下の値をとります：

     ""
     "one"
     "two"
     "one,two"

SET は最大 64 個の異なったメンバーがもてます。

MySQL は SET の値を数値として代入します。代入された値の最下位のビットが最初のメンバーに対応します。もし SET 値を数値の文脈で検索した場合、検索される値はフィールドの値に対応します。もしメンバーが SET フィールドに代入された場合、二進数で表される数値が、メンバーの数値として決定されます。 SET("a","b","c","d") とフィールドが定義されたとします。メンバーは以下の２進数の値を持ちます：

SET member   10進数   ２進数値
a   1   0001
b   2   0010
c   4   0100
d   8   1000

もしこのフィールドに 9 を与えた場合、これは２進数で 1001 ですから、 1 番目と 4 番目の SET メンバーである "a" と "d" が選択され、結果、 "a,d" となります。

1つ以上の SET 要素を含む値においては,あなたが値を挿入するとき,要素がどんな順序で記載されているのかは重要ではありません. また,何回要素が与えられたのかは重要ではありません. 後で値が検索されるとき, 値の中のそれぞれの要素はただ一回だけ表れます。そのとき、テーブル作成時に与えられた順に要素は並びます。例えば、フィールドが SET("a","b","c","d") と設定されていたなら、 "a,d", "d,a", "d,a,a,d,d" は検索されると "a,d" となります。

SET 値は数値として代入されます。 NULL 値は非 NULL SET 値の前にソートされます。

通常、LIKE か FIND_IN_SET() を使用して SET フィールドの SELECT を行います：

     mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
     mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;

しかし、以下も動作します：

     mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
     mysql> SELECT * FROM tbl_name WHERE set_col & 1;

最初の文は完全一致するものを探します。二つ目は第一番目のメンバーを含む値を探します。

もし SET フィールドで設定可能なすべてのメンバーを知りたい場合： SHOW COLUMNS FROM table_name LIKE set_column_name とし、２番目にあらわされる SET 定義を分析します。

正しいフィールド型の選択
------------

もっとも効率よく格納するには、全てにおいて一番正確な型を使用することです。例えば、1-99999 の整数には、MEDIUMINT UNSIGNED が最良の型です。

良くある問題は、貨幣の値の正確な表現です。MySQL では DECIMAL 型を使用すべきです。これは文字列として格納し、正確さのロスは発生しません。正確さが重要でない場合は DOUBLE 型でも十分良いです。

高精度のため、常に BITINT に格納される固定小数点型に変換できます。これは、全ての計算を整数で行なうようにし、結果だけを浮動小数点に変換して戻します。

フィールドインデックス
-----------

MySQL の全てのフィールドはインデックスを持つことができます。適切なフィールドでのインデックスの使用は、SELECT の性能を向上する最良の方法です。

一つのテーブルには最大16個のインデックスが許されます。インデックスの最大長は256バイトで、これは MySQL コンパイル時に変更できます。

CHAR と VARCHAR フィールドには接頭部にインデックスを持つことができます。フィールド全体をインデックス化するより、これははるかに早く、少ないディスク容量でできます。

CREATE TABLE 構文でフィールドにインデックスを作るには、以下のようにします：

     KEY index_name (col_name(length))

以下の例は name フィールドの最初の10文字にインデックスを創り出します:

     mysql> CREATE TABLE test (
               name CHAR(200) NOT NULL,
               KEY index_name (name(10)));

BLOB と TEXT フィールドでは、そのフィールドの頭の部分にインデックスを張らなくてはなりません。 フィールドの全体にインデックスは張れません。

複数フィールドインデックス
-------------

MySQL は異なるフィールドのセットに一つのインデックスを持つことができます。インデックスは最大15個のコラムまで許されます。 (CHAR と VARCHAR フィールドの接頭部をインデックスとして使用できます)

複数フィールドインデックスは、ソートされた配列(インデックス化されたフィールドの値が結合されている配列) 　を扱うことができます。

インデックス化されたコラムに対して、既知の値を WHERE 節で指定した時、たとえ他のフィールドの値を指定しなくとも、 MySQL は複数フィールドインデックスを使用します。

以下のテーブルがあると仮定してください：

     mysql> CREATE TABLE test (
                id INT NOT NULL,
                last_name CHAR(30) NOT NULL,
                first_name CHAR(30) NOT NULL,
                PRIMARY KEY (id),
                INDEX name (last_name,first_name));

name インデックスは、last_name と first_name にまたがるインデックスです。このインデックスは、last_name に対するクエリや、 name インデックスは以下のクエリで使われます：

     mysql> SELECT * FROM test WHERE last_name="Widenius";

     mysql> SELECT * FROM test WHERE last_name="Widenius"
                               AND first_name="Michael";

     mysql> SELECT * FROM test WHERE last_name="Widenius"
                               AND (first_name="Michael" OR first_name="Monty");

     mysql> SELECT * FROM test WHERE last_name="Widenius"
                               AND first_name >="M" AND first_name < "N";

しかし name インデックスは以下のクエリでは使用されません:

     mysql> SELECT * FROM test WHERE first_name="Michael";

     mysql> SELECT * FROM test WHERE last_name="Widenius"
     　　　　　　　　　　　　OR first_name="Michael";

MySQL がクエリの性能を上げるためにどうインデックスを使用しているか、より詳しい情報はこちら： MySQL indexes.

他のデータベースエンジンのフィールド型の使用
----------------------

ほかのベンダーからSQLを簡単に書けれるように、 MySQL は以下の表にしめすフィールド型をサポートします。これらは、テーブルの定義を、他のデータベースエンジンから MySQL に簡単に移行させてくれます：

Other vendor type          MySQL type
BINARY(NUM)		  CHAR(NUM) BINARY
CHAR VARYING(NUM)		  VARCHAR(NUM)
FLOAT4			  FLOAT
FLOAT8			  DOUBLE
INT1			  TINYINT
INT2			  SMALLINT
INT3			  MEDIUMINT
INT4			  INT
INT8			  BIGINT
LONG VARBINARY		  MEDIUMBLOB
LONG VARCHAR		  MEDIUMTEXT
MIDDLEINT			  MEDIUMINT
VARBINARY(NUM)		  VARCHAR(NUM) BINARY

もし他のベンダーの型を使用してテーブルを作ろうとすると、テーブル作成時のフィールドの型のマッピングが発生し、 DESCRIBE tbl_name 構文を発行します。そして MySQL は、使用された型と等価な MySQL の型を用いてテーブルを構成したことを告げます。

SELECT と WHERE 節で使用する関数
=======================

SQL ステートメント中の select_expression または where_definition は後述の関数を使用した任意の式からなります。

演算と関数を式の中で呼ぶ時、本ドキュメントに示しているもの以外の、 NULL を含む式は常に NULL 値を生成します

注意: 関数名とそれに続く語句の間には、空白はありません。これは関数の呼び出しと、関数と同名のテーブル(かフィールド)の参照を、 MySQL パーサが区別するのを助けます。

次の例では、mysql プログラムの出力は短くなっています。つまり:

     mysql> select MOD(29,9);
     1 rows in set (0.00 sec)

     +-----------+
     | mod(29,9) |
     +-----------+
     |         2 |
     +-----------+

これは次に変換されています:

     mysql> select MOD(29,9);
             -> 2

グループ化関数
-------

( ... )
     丸かっこ。 式の評価の優先度を強制するために使用します。

          mysql> select 1+2*3;
                  -> 7
          mysql> select (1+2)*3;
                  -> 9

通常の算術演算
-------

普通の算術演算が有効です。 -, +, * は、二つの引数が正数ならば BIGINT (64bit精度) で計算されることに注意してください！

+
     足し算

          mysql> select 3+5;
                  -> 8

-
     引き算

          mysql> select 3-5;
                  -> -2

*
     掛け算

          mysql> select 3*5;
                  -> 15
          mysql> select 18014398509481984*18014398509481984.0;
                  -> 324518553658426726783156020576256.0
          mysql> select 18014398509481984*18014398509481984;
                  -> 0

     最後の式の結果は不当です。なぜなら結果は 64 ビットを超えた整数だからです。

/
     割り算。

          mysql> select 3/5;
                  -> 0.60

     0 で割った場合、NULL になります。

          mysql> select 102/(1-1);
                  -> NULL

     演算結果が整数になる場合にだけ、 BIGINT を用いて割り算は計算されます。

ビット関数
-----

これらは最大 64 ビットの範囲を持ちます。MySQL は BIGINT (64-bit) 演算を使用するためです。

|
     ビット演算 OR

          mysql> select 29 | 15;
                  -> 31

&
     ビット演算 AND

          mysql> select 29 & 15;
                  -> 13

<<
     左に longlong (BIGINT) number 分、ビットをシフトします

          mysql> select 1 << 2
                  -> 4

>>
     右に longlong (BIGINT) number 分、ビットをシフトします

          mysql> select 4 >> 2
                  -> 1

~
     Invert all bits.

          mysql> select 5 & ~1
                  -> 4

BIT_COUNT(N)
     引数 N がいくつビットを持っているか(２進数表記したときの１の数)

          mysql> select BIT_COUNT(29);
                  -> 4

論理演算
----

全ての論理関数は 1 (TRUE) or 0 (FALSE) を返します。

NOT
!
     論理否定。引数が 0 なら 1 を返し、そうでなければ 0 を返します。例外: NOT NULL は NULL を返します.

          mysql> select NOT 1;
                  -> 0
          mysql> select NOT NULL;
                  -> NULL
          mysql> select ! (1+1);
                  -> 0
          mysql> select ! 1+1;
                  -> 1

     最後の例は 1 を返します。なぜなら、式の評価が (!1)+1 と同じだからです。

OR
||
     論理和。引数のどれかが 0 または NULL でなければ 1 を返します。

          mysql> select 1 || 0;
                  -> 1
          mysql> select 0 || 0;
                  -> 0
          mysql> select 1 || NULL;
                  -> 1

AND
&&
     論理積。全ての引数が 0 または NULL でなければ 1 を返します。

          mysql> select 1 && NULL;
                  -> 0
          mysql> select 1 && 0;
                  -> 0

比較演算子
-----

1 (TRUE), 0 (FALSE) または NULL を返します。これらの関数は数値と文字列の両方で働きます。必要ならば、文字は自動的に数字に変換され、数字は文字に変換されます。 (Perlがおこなっているみたいに)

MySQL は以下の規則で比較を行います：

  * どちらかまたは両方の引数が NULL の場合は、比較結果は NULL です。<=> 演算子を除きます。

  * 比較操作の両方の引数が文字列の場合、文字列として比較されます。

  * 両方の引数が整数の場合、整数として比較されます。

  * 16進数の値は、もし数値と比較されないのであれば、文字列として扱われます。

  * 引数の一方が TIMESTAMP または DATETIME フィールドで、他の引数が定数の場合は、定数は比較前に timestamp に変換されます。これはより ODBC フレンドリにするためです。

  * 他の場合は全て浮動小数点(real)として比較されます。

文字列の比較は、ケースに依存せず、標準のキャラクターセットに従って行われます。(ISO-8859-1 Latin1 がデフォルトです。これは English です)

以下は、比較のために文字が数値へ変換されている例です：

     mysql> SELECT 1 > '6x';
              -> 0
     mysql> SELECT 7 > '6x';
              -> 1
     mysql> SELECT 0 > 'x6';
              -> 0
     mysql> SELECT 0 = 'x6';
              -> 1

=
     等しい

          mysql> select 1 = 0;
                  -> 0
          mysql> select '0' = 0;
                  -> 1
          mysql> select '0.0' = 0;
                  -> 1
          mysql> select '0.01' = 0;
                  -> 0
          mysql> select '.01' = 0.01;
                  -> 1

<>
!=
     等しくない

          mysql> select '.01' <> '0.01';
                  -> 1
          mysql> select .01 <> '0.01';
                  -> 0
          mysql> select 'zapp' <> 'zappp';
                  -> 1

<=
     より小さいか等しい

          mysql> select 0.1 <= 2;
                  -> 1

<
     より小さい

          mysql> select 2 <= 2;
                  -> 1

>=
     より大きいか等しい

          mysql> select 2 >= 2;
                  -> 1

>
     より大きい

          mysql> select 2 > 2;
                  -> 0

<=>
     等しい(NULL 安全)

          mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
                  -> 1 1 0

IS NULL
IS NOT NULL
     値が NULL とであるかどうかのテスト

          mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL:
                  -> 0 0 1
          mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
                  -> 1 1 0

expr BETWEEN min AND max
     もし expr が min 以上、 max 以下なら 1を返します。そうでないなら 0 を返します。これは 全ての引数が同じ型ならば、(min <= expr AND expr <= max) と同じです。最初の引数 (expr) はいかのように比較方法を決定します。

       * もし exor が TIMESTAMP, DATE, DATETIME フィールドなら、最小と最大はそれらが定数の場合と同じフォーマットになります。

       * もし expr が文字式なら、ケース非依存で比較が行われます。

       * もし expr がバイナリ文字なら、ケース依存で比較が行われます。

       * もし expr が整数なら、整数で比較が行われます。

       * その他は浮動小数点(実数)で比較されます。

          mysql> select 1 BETWEEN 2 AND 3;
                  -> 0
          mysql> select 'b' BETWEEN 'a' AND 'c';
                  -> 1
          mysql> select 2 BETWEEN 2 AND '3';
                  -> 1
          mysql> select 2 BETWEEN 2 AND 'x-3';
                  -> 0

expr IN (value,...)
     もし expr が IN リストにある値のどれかならば、1 を返します。そうでなければ 0 を返します。もし全ての値が定数なら、すべての値が expr の型に従って評価され、ソートされます。この検索にはバイナリサーチが使用されます。これは IN リストに定数を与えた場合、IN が速くなることを意味します。もし expr がケース依存の文字式なら、ケース依存のやり方で比較されます。

          mysql> select 2 IN (0,3,5,'wefwf');
                  -> 0
          mysql> select 'wefwf' IN (0,3,5,'wefwf');
                  -> 1

expr NOT IN (value,...)
     NOT (expr IN (value,...)) と同じ。

ISNULL(expr)
     expr が NULL なら 1 を、そうでなければ 0 を返します。

          mysql> select ISNULL(1+1);
                  -> 0
          mysql> select ISNULL(1/0);
                  -> 1

     NULL の値を = を使用して比較した場合は常に偽(false) となることに注意してください！

COALESCE(list)
     list 中の、最初に現れた 非-NULL 要素を返します。

          mysql> select COALESCE(NULL,1);
                  -> 1
          mysql> select COALESCE(NULL,NULL,NULL);
                  -> NULL

INTERVAL(N,N1,N2,N3,...)
     もし N < N1 なら 0 を返します。もし N < N2 なら 1 を返します。全ての引数は整数として扱われます。これは N1 < N2 < N3 < ... < Nnを正しく動作させるために必要なことです。これはバイナリ検索が使用されます(速いです)

          mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
                  -> 3
          mysql> select INTERVAL(10, 1, 10, 100, 1000);
                  -> 2
          mysql> select INTERVAL(22, 23, 30, 44, 200);
                  -> 0

文字列比較関数
-------

通常、比較される表現がケース依存でない場合、比較はケース非依存で行われます。

expr LIKE pat [ESCAPE 'escape-char']
     SQL の簡単な正規表現比較です。1 (TRUE) または 0 (FALSE) を返します。 LIKE には2つのワイルドカードがあります:

     %   任意の数の文字(0文字も含む)に適合します。
     _   厳密に1つの文字に適合します。

          mysql> select 'David!' LIKE 'David_';
                  -> 1
          mysql> select 'David!' LIKE '%D%v%';
                  -> 1

     ワイルドカード文字のテストをするためには、エスケープ文字より先行しておこなってください。 ESCAPE を指定しない場合は、文字 '\' が使われます:

     \%   1つの % に適合します。
     \_   1つの _ に適合します。

          mysql> select 'David!' LIKE 'David\_';
                  -> 0
          mysql> select 'David_' LIKE 'David\_';
                  -> 1

     違うエスケープ文字を指定するには、 ESCAPE 節を使用します:

          mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
                  -> 1

     LIKE は数値表現でも許されます！ (これは MySQL の、ANSI SQL LIKE に対する拡張です)

     注意： MySQL は文字列中に C のエスケープ文字を使用しているので(e.g., \n),  LIKE の指定文字列として使用するには \ を二倍しなくてはなりません。 例えば、 \n を探すには、\\n と記述します。 \ を探すには、  \\\\ (バックスラッシュは、一つはパーサーに取り除かれ、パターンマッチが行われる際にもうひとつ取り除かれ、一致を探すために残った一つのバックスラッシュが使用されます)

expr NOT LIKE pat [ESCAPE 'escape-char']
     NOT (expr LIKE pat [ESCAPE 'escape-char']) と同じ

          mysql> select 10 LIKE '1%';
                  -> 1

expr REGEXP pat
expr RLIKE pat
     パターン pat に対し、文字式 expr のパターンマッチを行います。パターン pat は正規表現の拡張が使用できます。See Regexp. もし expr が pat にマッチするなら 1 を返し、でなければ 0 を返します。 RLIKE は REGEXP と同義で、mSQL 互換を提供します。注意: MySQL は C エスケープ構文を文字中に使用しており(\n)、 REGEXP 中で使用される '\' 文字はすべて、二重に書かなければなりません。 MySQL 3.23.4 REGEXP は、普通の文字 (not binary) はケース非依存です。

          mysql> select 'Monty!' REGEXP 'm%y%%';
                  -> 0
          mysql> select 'Monty!' REGEXP '.*';
                  -> 1
          mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
                  -> 1
          mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
                  -> 1  0

     REGEXP and RLIKE は、文字の型を決定する場合、カレントのキャラクターセットを使用します。 (ISO-8859-1 Latin1 がデフォルト)

expr NOT REGEXP pat
expr NOT RLIKE pat
     NOT (expr REGEXP pat) と同じ.

STRCMP(expr1,expr2)
     文字列が同じなら 0 を返します。そうでなければ、最初の引数がソート順で小さければ -1 を返します。そうでなければ 1 を返します。

          mysql> select STRCMP('text', 'text2');
                  -> -1
          mysql> select STRCMP('text2', 'text');
                  -> 1
          mysql> select STRCMP('text', 'text');
                  -> 0

Cast operators
--------------

BINARY
     BINARY 演算子は、これ以降に続く文字をバイナリにキャストします。これはたとえフィールドが BINARY や BLOB 定義でなくても、ケース依存でフィールドを比較することが出来る簡単な方法です。

          mysql> select "a" = "A";
                  -> 1
          mysql> select BINARY "a" = "A";
                  -> 0

     BINARY は MySQL 3.23.0 で登場しました。

フロー制御関数
-------

IFNULL(expr1,expr2)
     expr1 が NULL でない場合は expr1 を、そうでなければ expr2 を返します。 IFNULL() はどの文脈で使用されたかにより数値か文字を返します。

          mysql> select IFNULL(1,0);
                  -> 1
          mysql> select IFNULL(0,10);
                  -> 0
          mysql> select IFNULL(1/0,10);
                  -> 10
          mysql> select IFNULL(1/0,'yes');
                  -> 'yes'

NULLIF(expr1,expr2)
     expr1 = expr2 が真なら、expr1 を返し、そうでなければ NULL を返します。

          mysql> select NULLIF(1,1);
                  -> 1
          mysql> select NULLIF(1,2);
                  -> NULL

     注意: 引数が等しい場合、expr1 は MySQL では2回評価されます。

IF(expr1,expr2,expr3)
     expr1 が真 (expr1 <> 0 and expr1 <> NULL) の場合 expr2 を返し、そうでなければ expr3 を返します。 IF() はどの文脈で使用されたかにより数値か文字を返します。

          mysql> select IF(1>2,2,3);
                  -> 3
          mysql> select IF(1<2,'yes','no');
                  -> 'yes'
          mysql> select IF(strcmp('test','test1'),'no','yes');
                  -> 'no'

     expr1 は INTEGER として評価されます。これは浮動小数点を使用する場合、比較演算も使用すべきであることを意味します。

          mysql> select IF(0.1,1,0);
                  -> 0
          mysql> select IF(0.1<>0,1,0);
                  -> 1

     上の最初の例では、 IF(0.1) は 0 を返します。なぜなら 0.1 は整数値として変換され IF(0) になり、それをもとにしたテスト結果が返るからです。 これはあなたの期待に添わないかもしれません。二番目の場合、 比較は、元の浮動小数点値が非ゼロかどうかテストします。比較結果は整数として使用されます。

     IF() のデフォルトの戻り値型(一時テーブルに格納される時に問題となります)は MySQL 3.23 では次のように計算されます:

     expr2 または expr3 が文字列を返す   文字列
     expr2 または expr3 が浮動小数点値を返す   浮動小数点
     expr2 または expr3 が整数を返す   整数

CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END

CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END

     最初の式は value=compare-value ならば result を返します。二つ目の式では、最初の条件[condition] が真ならば、 result を返します。もしマッチする result の値がなければ、 ELSE 以下の result が返ります。もし ELSE 部分がなければ、 NULL が返ります。

          mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END;
                 -> "one"
          mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
                 -> "true"
          mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
                 -> NULL

数学関数
----

すべての数学関数はエラーの場合 NULL を返します。

-
     符号。引数の符号を変更します。

          mysql> select - 2;
                  -> -2

     このオペレーターが BIGINT とともに使用された場合、返り値は BIGINT であることに注意してください!  これは -2^63 の値を持つかもしれない整数を、 - で使用してはならないことを意味します！

ABS(X)
     Returns the absolute value of X.

          mysql> select ABS(2);
                  -> 2
          mysql> select ABS(-32);
                  -> 32

     この関数は BIGINT 値とともに使用されると安全です。

SIGN(X)
     X が負数、ゼロ、整数によって、 -1, 0 or 1 を返します。

          mysql> select SIGN(-32);
                  -> -1
          mysql> select SIGN(0);
                  -> 0
          mysql> select SIGN(234);
                  -> 1

MOD(N,M)
%
     剰余 ( C の % 演算子のような ). N を M で割ったときの余りが返ります。

          mysql> select MOD(234, 10);
                  -> 4
          mysql> select 253 % 7;
                  -> 1
          mysql> select MOD(29,9);
                  -> 2

     この関数は BIGINT 値でも安全に使用できます。

FLOOR(X)
     X より大きくならない整数のうち、最大の整数値を返します.

          mysql> select FLOOR(1.23);
                  -> 1
          mysql> select FLOOR(-1.23);
                  -> -2

     返り値は BIGINT に変換されていることに注意!

CEILING(X)
     X より小さくならない整数のうち、最小の整数値を返します.

          mysql> select CEILING(1.23);
                  -> 2
          mysql> select CEILING(-1.23);
                  -> -1

     返り値は BIGINT に変換されていることに注意!

ROUND(X)
     X を整数に丸めた値(四捨五入)を返します。

          mysql> select ROUND(-1.23);
                  -> -1
          mysql> select ROUND(-1.58);
                  -> -2
          mysql> select ROUND(1.58);
                  -> 2

     返り値は BIGINT に変換されていることに注意!

ROUND(X,D)
     X を D で指定した少数桁に丸めた値(四捨五入)を返します。もし D が 0 なら, 結果は小数点無しになるか少数部分になるでしょう。

          mysql> select ROUND(1.298, 0);
                  -> 1

EXP(X)
     指数関数 : e (自然対数の底) の X 乗。

          mysql> select EXP(2);
                  -> 7.389056
          mysql> select EXP(-2);
                  -> 0.135335

LOG(X)
     自然対数 X

          mysql> select LOG(2);
                  -> 0.693147
          mysql> select LOG(-2);
                  -> NULL

     If you want the log of a number X to some arbitary base B, use the formula LOG(X)/LOG(B).

LOG10(X)
     常用対数(10を底とした対数) X

          mysql> select LOG10(2);
                  -> 0.301030
          mysql> select LOG10(100);
                  -> 2.000000
          mysql> select LOG10(-100);
                  -> NULL

POW(X,Y)
POWER(X,Y)
     X の Y 乗。

          mysql> select POW(2,2);
                  -> 4.000000
          mysql> select POW(2,-2);
                  -> 0.250000

SQRT(X)
     X の非負の平方根を返します。

          mysql> select SQRT(4);
                  -> 2.000000
          mysql> select SQRT(20);
                  -> 4.472136

PI()
     π

          mysql> select PI();
                  -> 3.141593

COS(X)
     コサイン X。X はラジアン。

          mysql> select COS(PI());
                  -> -1.000000

SIN(X)
     サイン X。X はラジアン。

          mysql> select SIN(PI());
                  -> 0.000000

TAN(X)
     タンジェント X。X はラジアン。

          mysql> select TAN(PI()+1);
                  -> 1.557408

ACOS(X)
     X のアークコサインを返します。これはコサインが X である値です。X が -1 から 1 の範囲にない場合は NULL を返します。

          mysql> select ACOS(1);
                  -> 0.000000
          mysql> select ACOS(1.0001);
                  -> NULL
          mysql> select ACOS(0);
                  -> 1.570796

ASIN(X)
     X のアークサインを返します。これはサインが X である値です。 X が -1 から 1 の範囲にない場合は NULL を返します。

          mysql> select ASIN(0.2);
                  -> 0.201358
          mysql> select ASIN('foo');
                  -> 0.000000

ATAN(X)
     X のアークタンジェントを返します。これはタンジェントが X である値です。

          mysql> select ATAN(2);
                  -> 1.107149
          mysql> select ATAN(-2);
                  -> -1.107149

ATAN2(X,Y)
     ２つの変数 X と Y のアークタンジェントを返します。両方の引数の符号が結果の象限を決定するために使用されることを除いて、Y / X のアークタンジェントの計算と同様です。

          mysql> select ATAN(-2,2);
                  -> -0.785398
          mysql> select ATAN(PI(),0);
                  -> 1.570796

COT(X)
     X のコタンジェントを返します。

          mysql> select COT(12);
                  -> -1.57267341
          mysql> select COT(0);
                  -> NULL

RAND()
RAND(N)
     0 から 1.0 間のランダムな浮動小数点数値を返します。もし N に整数を与えた場合、シードとしてこの値が使用されます。

          mysql> select RAND();
                  -> 0.5925
          mysql> select RAND(20);
                  -> 0.1811
          mysql> select RAND(20);
                  -> 0.1811
          mysql> select RAND();
                  -> 0.2079
          mysql> select RAND();
                  -> 0.7888

     RAND() 値を持つフィールドは ORDER BY 節で使用できません。 ORDER BY はフィールドを複数回評価するためです。

     しかし MySQL 3.23 では, 次が可能です: SELECT * FROM table_name ORDER BY RAND()

     これは SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000 のセットからランダムなサンプルを得るのに便利です。

     注意: WHERE 節の RAND() は WHERE が実行する度に再評価されます。

LEAST(X,Y,...)
     二つ以上の引数を取り、引数中、最小の値を返します。引数は以下の規則に従って比較されます：

       * 値が INTEGER を使用しているなら、あるいは、全ての引数が整数値ならば、整数として比較します。

       * 値が REAL として使用されているか、全ての引数が実数ならば、実数として比較します。

       * いかなる引数もケース依存の文字ならば、引数はケース依存文字として比較されます。

       * そのほかの場合、引数はケース非依存文字として比較されます。

          mysql> select LEAST(2,0);
                  -> 0
          mysql> select LEAST(34.0,3.0,5.0,767.0);
                  -> 3.0
          mysql> select LEAST("B","A","C");
                  -> "A"

     3.22.5 以前の MySQL では、MIN() を LEAST の代わりに使用できます。

GREATEST(X,Y,...)
     二つ以上の引数を取り、引数中、最大の値を返します。引数は LEAST の時と同じように比較されます。

          mysql> select GREATEST(2,0);
                  -> 2
          mysql> select GREATEST(34.0,3.0,5.0,767.0);
                  -> 767.0
          mysql> select GREATEST("B","A","C");
                  -> "C"

     3.22.5 以前の MySQL では、MAX() を GREATEST の代わりに使用できます。

DEGREES(X)
     引数 X をラジアンから度に変換して返します。

          mysql> select DEGREES(PI());
                  -> 180.000000

RADIANS(X)
     引数 X を度からラジアンに変換して返します。

          mysql> select RADIANS(90);
                  -> 1.570796

TRUNCATE(X,D)
     少数点以下 D 桁で X を切り捨てた値を返します。 D が 0 の場合、結果は小数部や微小部を持ちません。

          mysql> select TRUNCATE(1.223,1);
                  -> 1.2
          mysql> select TRUNCATE(1.999,1);
                  -> 1.9
          mysql> select TRUNCATE(1.999,0);
                  -> 1

文字列関数
-----

サーバー側のパラメター max_allowed_packet よりも結果の長さが大きい場合、文字列関数は NULL を返します。 See Server parameters.

文字の位置を扱う関数においては、一番最初の位置は数字の 1 です。

ASCII(str)
     str の左端の文字の ASCII コード値を返します。 str が空文字の場合は 0 を返します。 str が NULL の場合は NULL を返します。

          mysql> select ASCII('2');
                  -> 50
          mysql> select ASCII(2);
                  -> 50
          mysql> select ASCII('dx');
                  -> 100

     See also the ORD() function.

ORD(str)
     文字列 str の左端の文字がマルチバイト文字の場合、文字のASCII コード値を次の形式で返すことにより、マルチバイト文字のコードを返します: ((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]. 左端の文字がマルチバイト文字でない場合は、ASCII() 関数と同じ値を返します。

          mysql> select ORD('2');
                  -> 50

CONV(N,from_base, to_base)
     数字を、進数の違う数字に変換します。数 N を from_base 進数から to_base 進数に変換した場合の、文字表現を返します。もし引数が NULL なら NULL を返します。引数 N は整数として解釈されますが、整数か文字列で指定します。最小の進数は 2 で、最大は 36 です。 to_base が負数なら、N は符号付きの数になります。 CONV は 64-bit 精度で動作します。

          mysql> select CONV("a",16,2);
                  -> '1010'
          mysql> select CONV("6E",18,8);
                  -> '172'
          mysql> select CONV(-17,10,-18);
                  -> '-H'
          mysql> select CONV(10+"10"+'10'+0xa,10,10);
                  -> '40'

BIN(N)
     N を二進数にした値を返します。N は longlong 数値です。これは CONV(N,10,2) と同じです。 N が NULL なら NULL を返します.

          mysql> select BIN(12);
                  -> '1100'

OCT(N)
     N の8進数値を表す文字列を返します。N は longlong 数値です。これは CONV(N,10,8) と同じです。N が NULL の場合は NULL を返します。

          mysql> select OCT(12);
                  -> '14'

HEX(N)
     N の16進数値を表す文字列を返します。N は longlong(BIGINT) 数値です。これは CONV(N,10,16) と同じです。 N が NULL の場合は NULL を返します。

          mysql> select HEX(255);
                  -> 'FF'

CHAR(N,...)
     引数の ASCII コード値によって与えられた文字からなる文字列を返します。 NULL は飛ばされます。

          mysql> select CHAR(77,121,83,81,'76');
                  -> 'MySQL'
          mysql> select CHAR(77,77.3,'77.3');
                  -> 'MMM'

CONCAT(str1,str2,...)
     引数を結合した結果を返します。引数が NULL なら NULL を返します. 2個以上の引数を必要とします。数値の引数は等価の文字列形式に変換されます。

          mysql> select CONCAT('My', 'S', 'QL');
                  -> 'MySQL'
          mysql> select CONCAT('My', NULL, 'QL');
                  -> NULL
          mysql> select CONCAT(14.3);
                  -> '14.3'

CONCAT_WS(separator, str1, str2,...)

     CONCAT_WS() は区切り文字つき CONCAT (CONCAT With Separator) を意味し、CONCAT() の特殊な形式です。最初の引数は、残りの引数の区切り文字です。区切り文字は残りの引数と同じような文字列です。区切り文字が NULL の場合、結果は NULL になります。関数は区切り文字より後の NULL と空文字列を飛ばします。区切り文字は結合される文字列の間に追加されます。

          mysql> select CONCAT_WS(",","First name","Second name","Last Name");
                 -> 'First name,Second name,Last Name'
          mysql> select CONCAT_WS(",","First name",NULL,"Last Name");
                 -> 'First name,Last Name'

LENGTH(str)
OCTET_LENGTH(str)
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)
     文字列 str の長さ。

          mysql> select LENGTH('text');
                  -> 4
          mysql> select OCTET_LENGTH('text');
                  -> 4

     注意: CHAR_LENGTH() については、マルチバイト文字は一度だけしかカウントされません。

LOCATE(substr,str)
POSITION(substr IN str)
     str 内にある substr 文字列の位置を返します。最初の位置は 1 です。 str 内に substr がない時は 0 を返します。

          mysql> select LOCATE('bar', 'foobarbar');
                  -> 4
          mysql> select LOCATE('xbar', 'foobar');
                  -> 0

     この関数はマルチバイトでも安全です。

LOCATE(substr,str,pos)
     文字列 str 中に最初に顕れた substr 文字の位置を返します。 pos は検索を開始する位置です。 str に substr がなければ 0 を返します。

          mysql> select LOCATE('bar', 'foobarbar',5);
                  -> 7

     この関数はマルチバイトでも安全です。

INSTR(str,substr)
     文字列 str 内の最初の文字列 substr の位置を返します。これは引数が入れ替わっていることをのぞいて、 2つの引数を与えた LOCATE と同じです。

          mysql> select INSTR('foobarbar', 'bar');
                  -> 4
          mysql> select INSTR('xbar', 'foobar');
                  -> 0

     この関数はマルチバイトでも安全です。

LPAD(str,len,padstr)
     str の長さが len になるまで文字列 str の始めに padstr を埋めます。

          mysql> select LPAD('hi',4,'??');
                  -> '??hi'

RPAD(str,len,padstr)
     str の長さが len になるまで文字列 str の終わりに padstr を埋めます。

          mysql> select RPAD('hi',5,'?');
                  -> 'hi???'

LEFT(str,len)
     文字列 str の最初から len 個の文字を得ます。

          mysql> select LEFT('foobarbar', 5);
                  -> 'fooba'

     この関数はマルチバイトでも安全です。

RIGHT(str,len)
     文字列 str の最後から len 個の文字を得ます。

          mysql> select RIGHT('foobarbar', 4);
                  -> 'rbar'

     この関数はマルチバイトでも安全です。

SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
MID(str,pos,len)
     str の pos 位置から len 文字数分の文字列を返します。 FROM の違いは ANSI SQL 92 構文です。

          mysql> select SUBSTRING('Quadratically',5,6);
                  -> 'ratica'

     この関数はマルチバイトでも安全です。

SUBSTRING(str,pos)

SUBSTRING(str FROM pos)
     文字列 str の 位置 pos 以降の文字を返します。

          mysql> select SUBSTRING('Quadratically',5);
                  -> 'ratically'
          mysql> select SUBSTRING('foobarbar' FROM 4);
                  -> 'rbar'

     この関数はマルチバイトでも安全です。

SUBSTRING_INDEX(str,delim,count)
     str から、区切り文字 delim が count 個現れた位置から前の文字列を返します。count が正の場合は文字列は左から検索され、 count が負の場合は文字列は右から検索されます。

          mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
                  -> 'www.mysql'
          mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
                  -> 'mysql.com'

     この関数はマルチバイトでも安全です。

LTRIM(str)
     文字列 str の最初から空白文字を削除します。

          mysql> select LTRIM('  barbar');
                  -> 'barbar'

RTRIM(str)
     文字列 str の最後から空白文字を削除します。

          mysql> select RTRIM('barbar   ');
                  -> 'barbar'

TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
     全ての remstr プレフィックスまたはサフィックスを  str から削除した文字列を返します。BOTH, LEADING そして TRAILING が使用されない場合、BOTH が適用されます。remstr が与えられないと、空白が削除されます。

          mysql> select TRIM('  bar   ');
                  -> 'bar'
          mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
                  -> 'barxxx'
          mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
                  -> 'bar'
          mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
                  -> 'barx'

     この関数はマルチバイトでも安全です。

SOUNDEX(str)
     str からの soundex 文字列を返します。発音が``大体同じ''２つの文字列は同じ soundex 文字列を持ちます。``標準の'' soundex 文字列は4文字長ですが、 SOUNDEX() 関数は任意の長さの文字列を返します。SUBSTRING() を結果に使用して、``標準の'' soundex 文字列を得ることができます。与えられた文字列中の非アルファベット文字は無視されます。A-Z の半以外のすべての国際的なアルファベット文字は母音とみなされます。

          mysql> select SOUNDEX('Hello');
                  -> 'H400'
          mysql> select SOUNDEX('Quadratically');
                  -> 'Q36324'

SPACE(N)
     N 個の空白文字を返します。

          mysql> select SPACE(6);
                  -> '      '

REPLACE(str,from_str,to_str)
     文字列 str 内の全ての文字列 from_str を to_str に置き換えます。

          mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
                  -> 'WwWwWw.mysql.com'

     この関数はマルチバイトでも安全です。

REPEAT(str,count)
     str を count 回繰り返します。count <= 0 の場合は空の文字列を返します。str または count が NULL または、LENGTH(str)*count > max_allowed_packet の場合は NULL を返します。

          mysql> select REPEAT('MySQL', 3);
                  -> 'MySQLMySQLMySQL'

REVERSE(str)
     文字列 str を反転します。

          mysql> select REVERSE('abc');
                  -> 'cba'

     この関数はマルチバイトでも安全です。

INSERT(str,pos,len,newstr)
     str 中の pos 位置から len 長の文字列を newstr で置き換えます。str 内の最初の位置は1です。

          mysql> select INSERT('Quadratic', 3, 4, 'What');
                  -> 'QuWhattic'

     この関数はマルチバイトでも安全です。

ELT(N,str1,str2,str3...)
     N = 1 なら str1 を、N = 2 なら str2 を返します。 N が 1 より小さい場合、または引数の数より大きい場合は NULL が返されます。 ELT() は FIELD() の逆です。

          mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
                  -> 'ej'
          mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
                  -> 'foo'

FIELD(str,str1,str2,str3,...)
     str1, str2, str3, ... リスト内の str のインデックスを返します。str が見つからなければ 0 を返します。 FIELD() は ELT() の逆です。

          mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
                  -> 2
          mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
                  -> 0

FIND_IN_SET(str,strlist)
     str が strlist 中にあれば、値 1 から N を返します。 strlist は、それぞれの異なる値が ',' で分割された文字列です。最初の引数が定数文字列で２番目が SET 型のフィールドの場合FIND_IN_SET はビット演算を使用して最適化されます！ strlist が空文字なら 0 を返します。どちらかの引数が NULL なら NULL を返します. この関数は最初の引数が  ',' を含んだ場合、うまく動かないでしょう。

          mysql> SELECT FIND_IN_SET('b','a,b,c,d');
                  -> 2

MAKE_SET(bits,str1,str2,...)
     bits に指定されたビットに対応する文字列のセットを返します。 (文字列が複数の場合、 , で区切られます) str1 が ビット 0 に対応し、str2 が ビット 1 に対応し、 str3 が ビット 2 に対応し... となります。 str1, str2, ... 中に含まれている NULL 文字は結果には追加されません。

          mysql> SELECT MAKE_SET(1,'a','b','c');
                  -> 'a'
          mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
                  -> 'hello,world'
          mysql> SELECT MAKE_SET(0,'a','b','c');
                  -> ''

EXPORT_SET(bits,on,off,[separator,[number_of_bits]])
     'bits' に与えられた数値に対し、全てのセットされているビットを 'on' で指定された文字で表し、リセットされているビットを 'off' で指定された文字で表した文字列を返します。それぞれの文字は 'separator' (デフォルト',') で示された文字で区切られ、 'number_of_bits' (default 64) に与えられた桁数だけのビットを表示します。

          mysql> SELECT EXPORT_SET(5,'Y','N',',',4);
                  -> Y,N,Y,N

LCASE(str)
LOWER(str)
     str を現在のキャラクターセットマッピング (デフォルト ISO-8859-1 Latin1) にしたがって小文字に変換します。

     この関数はマルチバイトでも安全です。

          mysql> select LCASE('QUADRATICALLY');
                  -> 'quadratically'

UCASE(str)
UPPER(str)
     str を現在のキャラクターセットマッピング (デフォルト ISO-8859-1 Latin1) にしたがって大文字に変換します。

          mysql> select UCASE('Hej');
                  -> 'HEJ'

     この関数はマルチバイトでも安全です。

LOAD_FILE(file_name)
     ファイルを読み込み、ファイルの中身を文字として返します。 ファイルはサーバー上になくてはならず、ファイルをフルパスで指定しなければなりません。そして、 file 権限がなければなりません。 ファイルは全員に読み込み可能でなければならず、そして、 max_allowed_packet より小さいサイズでなければなりません。

     このうちどれかの理由で、もしファイルが存在しないか読み込めない場合、この関数は NULL を返します。

          mysql> UPDATE table_name
                     SET blob_column=LOAD_FILE("/tmp/picture")
                     WHERE id=1;

MySQL は必要とあらば数値を文字列に変換します。逆も同様に行います：

     mysql> SELECT 1+"1";
            -> 2
     mysql> SELECT concat(2,' test');
            -> '2 test'

明示的に数値を文字列に変換したければ、CONCAT() に引数として渡して下さい。

文字列関数は引数としてバイナリ文字列が与えられると、結果の文字列もバイナリ文字列になります。文字列に変換された数値はバイナリ文字列とみなされます。これは比較にだけ影響します。

日付と時刻関数
-------

それぞれの型がもつ値の範囲と日と時間の値が記述される有効な形式については Date and time types.

日付関数を使用する例: date_col が最新の30日である全てのレコードを選択します:

     mysql> SELECT something FROM table
                WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;

DAYOFWEEK(date)
     date の曜日を得ます (1 = 日曜日, 2 = 月曜日, ... 7 = 土曜日) これは ODBC 標準に従います。

          mysql> select DAYOFWEEK('1998-02-03');
                  -> 3

WEEKDAY(date)
     date の曜日を得ます (0 = 日曜日, 1 = 月曜日, ... 6 = 土曜日)

          mysql> select WEEKDAY('1997-10-04 22:23:00');
                  -> 5
          mysql> select WEEKDAY('1997-11-05');
                  -> 2

DAYOFMONTH(date)
     月の日を返します (1 - 31)

          mysql> select DAYOFMONTH('1998-02-03');
                  -> 3

DAYOFYEAR(date)
     年の日を返します (1-366)

          mysql> select DAYOFYEAR('1998-02-03');
                  -> 34

MONTH(date)
     月を返します (1 - 12)

          mysql> select MONTH('1998-02-03');
                  -> 2

DAYNAME(date)
     曜日の名前を返します。

          mysql> select DAYNAME("1998-02-05");
                  -> 'Thursday'

MONTHNAME(date)
     月の名前を返します。

          mysql> select MONTHNAME("1998-02-05");
                  -> 'February'

QUARTER(date)
     date についての年の四半期を返します。範囲は 1 から 4 です。

          mysql> select QUARTER('98-04-01');
                  -> 2

WEEK(date)
WEEK(date,first)
     引数が一つの場合、date についての週を返します。範囲は 0 から 53 (そう、53週の最初というのもありえます)で、日曜日が週の最初の日です。引数が二つの形式の WEEK() は、週の開始を日曜日か月曜日か指定できます。第2引数が 0 の場合、週の開始は日曜日です。第2引数が 1 の場合、週の開始は月曜日です。

          mysql> select WEEK('1998-02-20');
                  -> 7
          mysql> select WEEK('1998-02-20',0);
                  -> 7
          mysql> select WEEK('1998-02-20',1);
                  -> 8
          mysql> select WEEK('1998-12-31',1);
                  -> 53

YEAR(date)
     年を返します (1000 - 9999).

          mysql> select YEAR('98-02-03');
                  -> 1998

YEARWEEK(date)
YEARWEEK(date,first)
     データの年と週を返します。第2引数は WEEK() の第2引数とまったく同じように働きます。注意: 年の最初と最後の週では、年が date 引数内の年とは異なることがあります！

          mysql> select YEARWEEK('1987-01-01');
                  -> 198653

HOUR(time)
     時を返します (0 - 23)

          mysql> select HOUR('10:05:03');
                  -> 10

MINUTE(time)
     分を返します (0-59)

          mysql> select MINUTE('98-02-03 10:05:03');
                  -> 5

SECOND(time)
     秒を返します (0 to 59)

          mysql> select SECOND('10:05:03');
                  -> 3

PERIOD_ADD(P,N)
     N 月を期間 P (型 YYMM または YYYYMM) に追加します。YYYYMM を返します。

     注意: 期間引数 P は日付値ではありません。

          mysql> select PERIOD_ADD(9801,2);
                  -> 199803

PERIOD_DIFF(P1,P2)
     期間 P1 と P2 の差の月を返します。P1 と P2 は形式 YYMM または YYYYMM です。

     注意: 期間引数 P1 と P2 は日付値ではありません。

          mysql> select PERIOD_DIFF(9802,199703);
                  -> 11

DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)

     これら関数は日付の演算に使用します。 これらは MySQL 3.22 の新しい機能です。 ADDDATE() と SUBDATE() は DATE_ADD() , DATE_SUB() と同義です。

     MySQL 3.23 では, + と - を DATE_ADD() , DATE_SUB() の代わりに使用できます. (See example)

     date には、DATETIME か DATE 型の値を指定します。この値から演算が開始されます。 expr には、date から増減させる値を指定します。 expr が - から始まっていれば、負数を示します。 type はどれぐらいの期間かを示すキーワードです。

     EXTRACT(type FROM date) 関数は、date から 'type' の部分を返します。

     以下の表に、type と expr の関連を示します：

     type 値   意味   expr のフォーマット
     SECOND          秒               SECONDS
     MINUTE          分               MINUTES
     HOUR            時間             HOURS
     DAY             日               DAYS
     MONTH           月               MONTHS
     YEAR            年               YEARS
     MINUTE_SECOND   分と秒           "MINUTES:SECONDS"
     HOUR_MINUTE     時間と分         "HOURS:MINUTES"
     DAY_HOUR        日 と時間        "DAYS HOURS"
     YEAR_MONTH      年 と月          "YEARS-MONTHS"
     HOUR_SECOND     時間と分         "HOURS:MINUTES:SECONDS"
     DAY_MINUTE      日、時、分       "DAYS HOURS:MINUTES"
     DAY_SECOND      日、時、分、秒   "DAYS HOURS:MINUTES:SECONDS"

     MySQL は、 expr フォーマット内のいかなる句読点区切りをも許します。上の表中の区切り文字は提案する区切り文字です。 もし date 引数が DATE 値で、YEAR, MONTH, DAY の部分のみを含む計算をするなら、結果は DATE 値が返ります。 それ以外なら DATETIME 値が返ります。

          mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
                  -> 1998-01-01 00:00:00
          mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
                  -> 1998-01-01
          mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
                 -> 1997-12-31 23:59:59
          mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                                 INTERVAL 1 SECOND);
                  -> 1998-01-01 00:00:00
          mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                                 INTERVAL 1 DAY);
                  -> 1998-01-01 23:59:59
          mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                                 INTERVAL "1:1" MINUTE_SECOND);
                  -> 1998-01-01 00:01:00
          mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
                                 INTERVAL "1 1:1:1" DAY_SECOND);
                  -> 1997-12-30 22:58:59
          mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
                                 INTERVAL "-1 10" DAY_HOUR);
                  -> 1997-12-30 14:00:00
          mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
                  -> 1997-12-02
          mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
                 -> 1999
          mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
                 -> 199907
          mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
                 -> 20102

     もしあなたの指定する interval 値が短すぎるなら( type キーワードから類推される値を含んでいない場合)、 MySQL は interval 値の一番左の部分を指定し忘れたものだと仮定します。例えば、もし type を DAY_SECOND に指定した場合、 expr の値は 日、時、分、秒 からなる物と期待されます。ここであなたが "1:10" のような値を指定していたなら、 MySQL は、日、時 の部分が忘れ去られて、分、秒 が与えられたと推定します。つまり、 "1:10" DAY_SECOND は "1:10" MINUTE_SECOND であると理解されるのです。これは、MySQL が TIME 値を時刻ではなく経過時間の表現と解釈する方法に類似しています。

     もし、不正な値が使用されたなら、結果は NULL です. もし MONTH や YEAR_MONTH や YEAR を足し算して、結果となる日付が新しい月の最大日よりも大きい日になるようなら、その日は、新しい月の最大日に修正されます。

          mysql> select DATE_ADD('1998-01-30',Interval 1 month);
                  -> 1998-02-28

     例のように、INTERVAL と type キーワードはケース依存ではありません。

TO_DAYS(date)
     日付 date を与えると、0年からの日数を返します。

          mysql> select TO_DAYS(950501);
                  -> 728779
          mysql> select TO_DAYS('1997-10-07');
                  -> 729669

     TO_DAYS() はグレゴリオ歴の開始(1582)より前の値での使用を意図されていません。歴が変更された時に失われた日を考慮に入れてないからです。

FROM_DAYS(N)
     Given a daynumber N, returns a DATE value.

          mysql> select FROM_DAYS(729669);
                  -> '1997-10-07'

     FROM_DAYS() はグレゴリオ歴の開始(1582)より前の値での使用を意図されていません。歴が変更された時に失われた日を考慮に入れてないからです。

DATE_FORMAT(date,format)
     date 値を format 文字列に従って整形します。次の指定が format 文字列で使用できます:

     %M   月名 (January..December)
     %W   曜日 (Sunday..Saturday)
     %D   英語サフィックス付き月の日 (1st, 2nd, 3rd, etc.)
     %Y   4桁の年
     %y   2桁の年
     %X   週の年。週の最初の日は日曜日。4桁の数値。'%V' と共に使用されます
     %x   週の年。週の最初の日は月曜日。4桁の数値。'%v' と共に使用されます
     %a   省略された曜日名 (Sun..Sat)
     %d   月の日, 数値 (00..31)
     %e   月の日, 数値 (0..31)
     %m   月, 数値 (01..12)
     %c   月, 数値 (1..12)
     %b   省略された月名 (Jan..Dec)
     %j   年の日 (001..366)
     %H   時 (00..23)
     %k   時 (0..23)
     %h   時 (01..12)
     %I   時 (01..12)
     %l   時 (1..12)
     %i   分, 数値 (00..59)
     %r   時刻, 12時間 (hh:mm:ss [AP]M)
     %T   時刻, 24時間 (hh:mm:ss)
     %S   秒 (00..59)
     %s   秒 (00..59)
     %p   AM or PM
     %w   週の日 (0=Sunday..6=Saturday)
     %U   週 (0..53), 週のはじまりを 日曜とした場合
     %u   週 (0..53), 週のはじまりを 月曜とした場合
     %V   週 (1..53), 週のはじまりは日曜日。'%X' と共に使用されます
     %v   週 (1..53), 週のはじまりは月曜日。'%x' と共に使用されます
     %%   リテラル %。

     他の全ての文字は解釈されずに結果にコピーされます。

          mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
                  -> 'Saturday October 1997'
          mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
                  -> '22:23:00'
          mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                                    '%D %y %a %d %m %b %j');
                  -> '4th 97 Sat 04 10 Oct 277'
          mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                                    '%H %k %I %r %T %S %w');
                  -> '22 22 10 10:23:00 PM 22:23:00 00 6'
          mysql> select DATE_FORMAT('1999-01-01', '%X %V');
                  -> '1998 52'

     MySQL 3.23 では、 % 文字はフォーマット文字の前に必ず必要とされます。それより前のバージョンでは、 % 文字はオプションでした。

TIME_FORMAT(time,format)
     これは上記の DATE_FORMAT() のように使用されますが、 format オプションでは、時,分,秒だけを操作できます。他のオプションは NULL or 0 を与えます。

CURDATE()
CURRENT_DATE
     今日の日付を返します。日付の形式は、CURDATE() が数値または文字列のどちらの文脈で使用されたかに依存して YYYYMMDD または 'YYYY-MM-DD' で返されます。

          mysql> select CURDATE();
                  -> '1997-12-15'
          mysql> select CURDATE() + 0;
                  -> 19971215

CURTIME()
CURRENT_TIME
     現在の時刻を HHMMSS または 'HH:MM:SS' の形式で返します。これは CURTIME() が数値または文字列のどちらの文脈で使用されたかに依存します。

          mysql> select CURTIME();
                  -> '23:50:26'
          mysql> select CURTIME() + 0;
                  -> 235026

NOW()
SYSDATE()
CURRENT_TIMESTAMP
     現在の時刻を返します。数値または文字列のどちらの文脈で使用されたかに依存して YYYYMMDDHHMMSS または 'YYYY-MM-DD HH:MM:SS' 形式で返されます。

          mysql> select NOW();
                  -> '1997-12-15 23:50:26'
          mysql> select NOW() + 0;
                  -> 19971215235026

UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
     引数なしで呼び出された場合は、UNIX timestamp (GMT '1970-01-01 00:00:00' からの秒数) です。通常は、TIMESTAMP フィールドを引数として呼び出し、フィールドの値を秒数で返します。date はローカル時刻での DATE 文字列、DATETIME 文字列、または YYMMDD または YYYYMMDD 形式の数値です。

          mysql> select UNIX_TIMESTAMP();
                  -> 882226357
          mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
                  -> 875996580

     UNIX_TIMESTAMP が TIMESTAMP フィールドに使用された場合、この関数は、暗黙の ``文字から UNIX タイムスタンプ'' 変換をすることなく、値を得ます。

FROM_UNIXTIME(Unix_timestamp)
     文脈(数値/文字列)に依存して、'YYYY-MM-DD HH:MM:SS' または YYYYMMDDHHMMSS 形式の timestamp 文字列を返します。

          mysql> select FROM_UNIXTIME(875996580);
                  -> '1997-10-04 22:23:00'
          mysql> select FROM_UNIXTIME(875996580) + 0;
                  -> 19971004222300

FROM_UNIXTIME(unix_timestamp,format)
     format に従って整形された Unix timestamp 文字列を返します。 format は DATE_FORMAT() 関数のエントリに一覧されたのと同じ指定子を含むことができます。

          mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
                                      '%Y %D %M %h:%i:%s %x');
                  -> '1997 23rd December 03:43:30 x'

SEC_TO_TIME(seconds)
     seconds 引数を時分秒に変換して返します。関数が文字列文脈または数値文脈のどちらで使用されたかに依存して、'HH:MM:SS' または HHMMSS 形式で値を返します。

          mysql> select SEC_TO_TIME(2378);
                  -> '00:39:38'
          mysql> select SEC_TO_TIME(2378) + 0;
                  -> 3938

TIME_TO_SEC(time)
     time を秒に変換します。

          mysql> select TIME_TO_SEC('22:23:00');
                  -> 80580
          mysql> select TIME_TO_SEC('00:39:38');
                  -> 2378

その他の関数
------

DATABASE()
     現在のデータベース名を返します。

          mysql> select DATABASE();
                  -> 'test'

     もしデータベースが選択されていないなら、DATABASE() は空文字を返します。

USER()
SYSTEM_USER()
SESSION_USER()
     現在の MySQL ユーザ名を返します。

          mysql> select USER();
                  -> 'davida@localhost'

     MySQL 3.22.11 以降では、この関数はユーザー名とクライアントのホスト名を含みます。ユーザー名の部分だけ取り出すには次のようにします。（これはホスト名が含まれていなくとも動くでしょう）：

          ysql> select substring_index(USER(),"@",1);
                  -> 'davida'

PASSWORD(str)
     プレーンテキストのパスワード str からパスワード文字列を計算します。これは user 許可テーブルの Password フィールドに、暗号化された MySQL パスワードを保存する際に使用されます。

          mysql> select PASSWORD('badpwd');
                  -> '7f84554057dd964b'

     PASSWORD() 暗号は不可逆です。

     PASSWORD() は UNIX のパスワードが暗号化するのと同じ方法で暗号化を行うわけではありません。 UNIX のパスワードと MySQL のパスワードが同じと思ってはいけません。 UNIX のパスワードファイルに保存される値が PASSWORD() が返すと考えてはいけません。 ENCRYPT() 参照。

ENCRYPT(str[,salt])
     UNIX の crypt() システムコールで str を暗号化します。 salt は2文字の文字列です。 (MySQL 3.22.16 で, salt は2文字以上許されるようになりました。)

          mysql> select ENCRYPT("hello");
                  -> 'VxuFAJXVARROc'

     システムで crypt() が利用できない場合は ENCRYPT() は常に NULL を返します。

     少なくともいくつかのシステムでは、 ENCRYPT() は str 文字中の最初の 8 文字以外は全て無視します。これは crypt() システムコールの振る舞いによって決定づけられます。

ENCODE(str,pass_str)
     パスワードとして pass_str を用いて str を暗号化します。結果を復号化するには、DECODE()を使用します。

     結果はバイナリ文字列です。フィールドにそれを保存したい場合は BLOB フィールド型を使用してください。

DECODE(crypt_str,pass_str)
     暗号化された文字列 crypt_str をパスワードとして pass_str を用いて復号化します。crypt_str は ENCODE() から返された文字列であるべきです。

MD5(string)
     文字列を MD5 チェックサムした結果を返します。 値は 32 桁の 16進表示です。例えばハッシュキーとして使用できるように。

          mysql> select MD5("testing")
                  -> 'ae2b1fca515949e5d54fb22b8ed95575'

     これは "RSA Data Security, Inc. MD5 Message-Digest Algorithm".

LAST_INSERT_ID([expr])
     最後に AUTO_INCREMENT フィールドに挿入されて自動的に生成された値を返します。 See mysql_insert_id().

          mysql> select LAST_INSERT_ID();
                  -> 195

     最後の作成された ID はそれぞれのコネクション毎にサーバーに維持されます。これは他のクライアントからは変更できないでしょう。もし他の非マジック値をもつ AUTO_INCREMENT フィールド（値が NULL でも 0 でもないということ）を更新しても、これは 変更されません。

     もし UPDATE 節内の LAST_INSERT_ID() の引数に expr を指定すると、引数の値は LAST_INSERT_ID() の値として返ります。これは シーケンス番号のシミュレーションに使用できます：

     最初にテーブルを作成：

          mysql> create table sequence (id int not null);
          mysql> insert into sequence values (0);

     そして以下のようにしてシーケンス番号を生成：

          mysql> UPDATE sequence SET id=last_insert_id(id+1);

     LAST_INSERT_ID() の呼び出し無しでシーケンス番号を生成することが可能ですが、この方法でこの関数を使用するユーティリティは、ID 値が最後に自動的に生成された値としてサーバに管理されます。MySQL 内の通常の任意の AUTO_INCREMENT 値を読み込んで新しい ID を取り出すことができます。例えば、LAST_INSERT_ID() (引数無し) は新しい ID を返します。C API 関数 mysql_insert_id() もこの値を得るために使用できます。

FORMAT(X,D)
     '#,###,###.##' のような形式(小数部 X 桁)で数値 D を整形します。 もし D が 0 なら, 結果にはいかなる小数点も小数部も含まれません。

          mysql> select FORMAT(12332.123456, 4);
                  -> '12,332.1235'
          mysql> select FORMAT(12332.1,4);
                  -> '12,332.1000'
          mysql> select FORMAT(12332.2,0);
                  -> '12,332'

VERSION()
     MySQL サーバのバージョンを返します。

          mysql> select VERSION();
                  -> '3.23.13-log'

     注意: バージョンが -log で終わる場合はロギングが有効であることを意味します。

CONNECTION_ID()
     接続の接続 ID (thread_id) を返します。すべての接続は接続自身の一意な ID を持ちます。

          mysql> select CONNECTION_ID();
                  -> 1

GET_LOCK(str,timeout)
     timeout 秒のタイムアウトで、str と名付けられたロックの獲得を試みます。ロックを獲得した場合は 1, タイムアウトの場合は 0, エラーの場合(メモリ不足やスレッドが mysqladmin kill で殺された場合など)は NULL が返ります。RELEASE_LOCK の実行、新しい GET_LOCK の実行、スレッドの終了の場合に、ロックは解放されます。この関数はアプリケーションロックやレコードロックのシミュレートのために使用できます。これは、同じ名前のロックを行おうとする他のクライアントからのリクエストをブロックします； 与えられた名前のロックに応じているクライアントは、協調してロッキングを行うために、その文字列を使用できます。

          mysql> select GET_LOCK("lock1",10);
                  -> 1
          mysql> select GET_LOCK("lock2",10);
                  -> 1
          mysql> select RELEASE_LOCK("lock2");
                  -> 1
          mysql> select RELEASE_LOCK("lock1");
                  -> NULL

     ２つ目の RELEASE_LOCK() は NULL を返します。なぜなら、 "lock1" は、２つ目の GET_LOCK() の呼び出し時点で、自動的に解放されるからです。

RELEASE_LOCK(str)
     GET_LOCK で獲得したロック str を解放します。ロックが解放された場合は 1, このスレッドによってロックされていない場合は 0 (この場合、ロックは解放されません), strが存在しない場合は NULL が返ります。もし、 GET_LOCK() をコールして得られなかった場合、あるいは、既に解放されている場合は、ロックは存在しないでしょう。

BENCHMARK(count,expr)
     BENCHMARK() 関数は expr で与えられた文を count 回繰り返し実行します。 これは MySQL のその文の処理がどれぐらい速いのか知るのに使用されるでしょう。 結果は常に 0 です。想定している使用は、 mysql クライアントです。あるクエリの実行時間を知るための使用です。

          mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
          +----------------------------------------------+
          | BENCHMARK(1000000,encode("hello","goodbye")) |
          +----------------------------------------------+
          |                                            0 |
          +----------------------------------------------+
          1 row in set (4.74 sec)

     報告された時間は、クライアントでの経過時間です。 サーバー側の CPU 時間ではありません。BENCHMARK() を何回か実行して、サーバマシンの負荷の重さを考慮して結果を解釈することを勧めます。

INET_NTOA(expr)
     数値表現に対するネットワークアドレス(4 または 8 バイト) を返します。

          mysql> select INET_NTOA(3520061480);
                 ->  "209.207.224.40"

INET_NTOA(expr)
     ネットワークアドレスに対する数値を表す整数を返します。アドレスは 4 または 8 バイトアドレスです。

          mysql> select INET_ATON("209.207.224.40");
                 ->  3520061480

GROUP BY 節の関数
-------------

GROUP BY 節なしで グループ関数を使用するなら、これは全てのレコードをグループ化することになります。

COUNT(expr)
     SELECT 文によって得られるレコード 中、値が 非NULL であるレコードの数を返します。

          mysql> select student.student_name,COUNT(*)
                     from student,course
                     where student.student_id=course.student_id
                     GROUP BY student_name;

     検索されたレコードの数が、レコード中に NULL 値を含むかどうかで、 COUNT(*) で返る値ははいくぶん異なります。

     もし SELECT が一つのテーブルから検索し、かつ、他のフィールドが検索されることもなく、かつ WHERE 節が無いならば、 COUNT(*) は速く答えるために最適化されます。例えば：

          mysql> select COUNT(*) from student;

COUNT(DISTINCT expr,[expr...])
     異なる値の数のカウントを返します。

          mysql> select COUNT(DISTINCT results) from student;

     MySQL では、式のリストを与えることで、別個の式の組合せの数を得ることができます。ANSI SQL では、すべての式を CODE(DISTINCT ..)  内で結合する必要があります。

AVG(expr)
     exprの平均値。

          mysql> select student_name, AVG(test_score)
                     from student
                     GROUP BY student_name;

MIN(expr)
MAX(expr)
     expr.の最小/最大値。 min() と max() が文字列引数を取ると、最小/最大の文字列値を返します。

          mysql> select student_name, MIN(test_score), MAX(test_score)
                     from student
                     GROUP BY student_name;

SUM(expr)
     exprの合計. 注意: 結果セットが何もレコードを返さない場合は、これは NULL を返します！

STD(expr)
STDDEV(expr)
     expt の標準誘導(standard derivative)。これは ANSI SQL に対する拡張です。この関数の STDDEV() 形式は、Oracle 互換のために提供されました。

BIT_OR(expr)
     expr 内の全てのビットの論理 OR。64 ビット(BIGINT)の精度で計算されます。

BIT_AND(expr)
     expr 内の全てのビットの論理 AND。64 ビット(BIGINT)の精度で計算されます。

MySQL は GROUP BY を拡張しています。SELECT 表現内で GROUP BY 部に現れないフィールドまたは計算を使用できます。これは このグループのための全ての可能な値 を表しています。この使用により、必要ないフィールドでのソートとグループが避けられるので、高い性能が得られます。例えば、次のクエリでは customer.name でグループする必要はありません:

     mysql> select order.custid,customer.name,max(payments)
            from order,customer
            where order.custid = customer.custid
            GROUP BY order.custid;

ANSI SQL では、GROUP BY 節に customer.name を追加する必要があります。 MySQL では、ANSI モードで実行していない場合は、name は冗長です。

GROUP BY 部から省略したフィールドがグループ内で一意でない場合は、この機能を使用しないでください！

いくつかのケースでは、それが一意でない場合でも、MIN() と MAX() を特定のフィールド値を獲得するために使用することができます。次は、sort フィールド内の最小の値を含むレコードからの column の値を与えます:

     substr(MIN(concat(sort,space(6-length(sort)),column),7,length(column)))

注意: MySQL 3.22 (またはそれ以前) を使用している場合、または ANSI SQL に従おうとしている場合は、GROUP BY や ORDER BY 節で式を使用できません。式の別名を使用することでこの制限を回避できます:

     mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name
                GROUP BY id,val ORDER BY val;

MySQL 3.23 では次を行なうことができます:

     mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();

CREATE DATABASE構文
=================

     CREATE DATABASE [IF NOT EXISTS] db_name

CREATE DATABASE は与えられた名前のデータベースを作ります。データベースの名前として許される命名規則は、Legal namesに依ります。もし、データベースがすでに存在しているにもかかわらず IF NOT EXISTS を指定していなかったら、エラーが発生します。

MySQLにおけるデータベースは、データベース内のテーブルに相当するファイルを含むディレクトリとして実装されます。初期作成後はデータベース内にテーブルは存在せず、CREATE DATABASEステートメントは、MySQLデータディレクトリ下にディレクトリを作成するだけです。

mysqladminでもデータベースを作成することができます。 See Programs.

DROP DATABASE構文
===============

     DROP DATABASE [IF EXISTS] db_name

DROP DATABASEは、データベース内の全てのテーブルと共にデータベースを破棄します。このコマンドの使用には万全の注意を払って下さい！

DROP DATABASEは、データベースディレクトリから削除されたファイルの数を返します。それぞれのテーブルは.MYDファイル／.MYIファイル／.frmファイルに相当することから、通常この値はテーブルの３倍の数となります。

MySQL 3.22以降では、データベースが存在しないことに起因するエラーを防ぐために、キーワード IF EXISTS を使用することができます。

mysqladminでもデータベースを破棄することができます。 See Programs.

CREATE TABLE構文
==============

     CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
     [table_options] [select_statement]

     create_definition:
       col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
                 [PRIMARY KEY] [reference_definition]
       or    PRIMARY KEY (index_col_name,...)
       or    KEY [index_name] (index_col_name,...)
       or    INDEX [index_name] (index_col_name,...)
       or    UNIQUE [INDEX] [index_name] (index_col_name,...)
       or    [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
                 [reference_definition]
       or    CHECK (expr)

     type:
             TINYINT[(length)] [UNSIGNED] [ZEROFILL]
       or    SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
       or    MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
       or    INT[(length)] [UNSIGNED] [ZEROFILL]
       or    INTEGER[(length)] [UNSIGNED] [ZEROFILL]
       or    BIGINT[(length)] [UNSIGNED] [ZEROFILL]
       or    REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
       or    DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
       or    FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
       or    DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
       or    NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
       or    CHAR(length) [BINARY]
       or    VARCHAR(length) [BINARY]
       or    DATE
       or    TIME
       or    TIMESTAMP
       or    DATETIME
       or    TINYBLOB
       or    BLOB
       or    MEDIUMBLOB
       or    LONGBLOB
       or    TINYTEXT
       or    TEXT
       or    MEDIUMTEXT
       or    LONGTEXT
       or    ENUM(value1,value2,value3,...)
       or    SET(value1,value2,value3,...)

     index_col_name:
             col_name [(length)]

     reference_definition:
             REFERENCES tbl_name [(index_col_name,...)]
                        [MATCH FULL | MATCH PARTIAL]
                        [ON DELETE reference_option]
                        [ON UPDATE reference_option]

     reference_option:
             RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

     table_options:
     	TYPE = {ISAM | MYISAM | HEAP}
     or	AUTO_INCREMENT = #
     or	AVG_ROW_LENGTH = #
     or	CHECKSUM = {0 | 1}
     or	COMMENT = "string"
     or	MAX_ROWS = #
     or	MIN_ROWS = #
     or	PACK_KEYS = {0 | 1}
     or	PASSWORD = "string"
     or	DELAY_KEY_WRITE = {0 | 1}
     or      ROW_FORMAT= { default | dynamic | static | compressed }
     or     RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=#  RAID_CHUNKSIZE=#;

     select_statement:
     	[IGNORE | REPLACE] SELECT ...  (Some legal select statement)

CREATE TABLEはカレントデータベースに、与えられた名前のテーブルを作成します。テーブルの名前として許される命名規則は、see Legal namesに依ります。カレントデータベースが無い場合や、テーブルが既に存在している場合はエラーが発生します。

MySQL 3.22 以降ではテーブル名は db_name.tbl_name という形で与える事もできます。これはカレントデータベースがあるかどうかにに関係なく動作します。

MySQL 3.23 では、テーブル作成時に TEMPORARY キーワードを使用することができます。 一時テーブルは、もし、コネクションが落ちた場合、自動で消去されます。一時テーブルの名前はそれぞれの接続ごとです。これは、二つの違う接続で、同じ名前の一時テーブルを衝突することなく、使用できるという事です。さらには、既に存在するテーブルと同名であっても、一時テーブルは使用できます。 (一時テーブルが削除されるまで、実在するテーブルは隠されます)

MySQL 3.23 以降では、 IF NOT EXISTS キーワードを使用できます。これは、もしテーブルが既に存在していた場合、エラーを発生させません。テーブルの構造が一意かどうかまでは検査しないことに注意。

それぞれのテーブルは、データベースディレクトリにおける以下の複数のファイルで表されます。これは MyISAM 型 のテーブル場合：

ファイル   目的
tbl_name.frm   テーブル定義(書式)ファイル
tbl_name.MYD   データファイル
tbl_name.MYI   インデックスファイル

フィールドに対する種々の型属性の詳細は、Column typesを参照のこと。

  * NULLもNOT NULLも指定されなかった場合、フィールドはNULLが指定されたものとして扱われます。

  * 整数型のフィールドには付加属性AUTO_INCREMENTも指定することができます。AUTO_INCREMENTのフィールドに値NULL又は0を挿入した場合、フィールドにはvalue+1の値がセットされます。valueは、そのテーブル内の当該フィールドにおける現在の最大値です。 AUTO_INCREMENT は 1 からはじまります. See mysql_insert_id().

     削除したレコードが、AUTO_INCREMENTフィールドの最大値を含んでいた場合、その値は次に再利用されます(ただし、これは ISAM テーブルの場合で、MyISAM テーブルでは起こりません)。また、テーブル内の全てのレコードを DELETE FROM TABLE (WHERE節無しで) を使用して削除した場合は、始めから採番し直します。

     注意: 1つのテーブルには1つしかAUTO_INCREMENTフィールドを指定できません。また、インデックスを指定する必要があります。 MySQL 3.23 は auto_increment フィールドが正の数を持っている場合にだけ、正しく動作します。負の数の挿入はとても大きな正の数の挿入とみなされます。これは、数値が正から負への 'wrap' over する時の精度の問題を回避するためと、アクシデント的に 0 を含む auto_increment フィールドを得ることがないことを確実にするために、行なわれます。

     MySQL をいくつかの ODBC アプリケーションと互換にするために、次のクエリで最後に挿入されたレコードを見つけることができます:

          SELECT * FROM tbl_name WHERE auto_col IS NULL

  * TIMESTAMPフィールドにおけるNULL値は、他のフィールド属性と違った扱われ方をします。定数NULLをTIMESTAMPフィールドに格納することはできません。NULL値の指定は現在時刻をセットすることを意味します。TIMESTAMPフィールドがこのように振舞うので、通常はNULL属性やNOT NULL属性は適用できません。それらを指定しても無視されます。

     一方、MySQLクライアントからは、より安易にTIMESTAMPフィールドを利用でき、サーバもTIMESTAMPフィールドへのNULLの適用を報告しますが、TIMESTAMPフィールドは実際にはNULL値を保存することはありません。DESCRIBE tbl_nameを使用して、テーブル定義文を取得することにより、この現象を確認することができます。

     TIMESTAMPフィールドに0を指定することは、NULLを指定することと等しくないことに注意してください。なぜなら、0はTIMESTAMPの値として不正であるからです。

  * フィールドに対して DEFAULT 値が指定されない場合は MySQL が自動的にそれを割り当てます。

     フィールドが NULL を値として取り得る場合は、デフォルト値は NULL です。

     フィールドが NOT NULL として宣言された場合は、デフォルト値はフィールド型に依存します:

       - AUTO_INCREMENT 定義された以外の数値型のフィールドに対しては、初期値は0となります。 AUTO_INCREMENTフィールドでは、デフォルト値は次のシーケンス番号になります。

       - TIMESTAMP 型以外の日付型と時刻型のフィールドに対しては、初期値はその型において適切な``ゼロ''値となります。例外: フィールドがそのテーブル内で最初のTIMESTAMPフィールドである場合、初期値は現在時刻になります。 See Date and time types.

       - ENUM 以外の文字列型のフィールドに対しては、初期値は空文字列となります。 ENUM では、デフォルト値は最初の列挙値です。

  * KEYは、INDEXの同義語です。

  * MySQLでは、UNIQUEキーは固有値しか持つことができません。既に存在するレコードとキーの値が重複するレコードを挿入しようとした場合、エラーが発生します。

  * PRIMARY KEY はユニーク KEY で、すべてのキーフィールドは NOT NULL として定義されなければならないという特別な制限を伴います。 MySQL ではキーは PRIMARY と名付けられます。テーブルは PRIMARY KEY を一つだけ持つことができます。PRIMARY KEY を持たない場合に、アプリケーションがテーブル内の PRIMARY KEY を尋ねると、 MySQL は PRIMARY KEY として、NULL フィールドを持たない最初の UNIQUE キーを返します。

  * PRIMARY KEYは複数フィールドインデックスとできます。しかしながら、1つのフィールド定義内ではPRIMARY KEY属性を用いて複合インデックスを定義することができませんので、フィールド定義内における指定は、プライマリ・キーが単独フィールドの場合のみとして下さい。複合フィールドの場合は、PRIMARY KEY(index_col_name,...)文を使用しなければなりません。

  * PRIMARY や UNIQUE キーが１つのフィールドだけからなり、その型が整数の場合、それを _rowid としても参照することができます(3.23.11 での新機能)。

  * インデックスに名前を割り当てない場合、一意な名前を付けるために、index_col_name内の最初のフィールド名に(_2, _3, ...)のようなサフィックスを付加したものが割り当てられます。テーブルが使用しているインデックス名は、SHOW INDEX FROM tbl_nameにより確認することができます。 See SHOW.

  * MyISAM テーブルのみが、NULL 値をもつフィールドに対してインデックスを持つことが出来ます。その他のテーブル型の場合、フィールドを NOT NULL で定義しなくてはなりません。

  * col_name(length)文を共に指定することで、CHARフィールド又はVARCHARフィールドの一部分だけをインデックスとして定義できます。これによりインデックスファイルを適度に小さくすることができます。 See Indexes.

  * MyISAM テーブル型のみが、 BLOB と TEXT フィールド上にインデックスを持つことが出来ます。 BLOB と TEXT フィールドにインデックスを張る場合、常に、インデックスの長さを指定しなくてはなりません：

          CREATE TABLE test (blob_col BLOB, index(blob_col(10)));

  * TEXTフィールドやBLOBフィールドで ORDER BY や GROUP BY を使用すると、最初のmax_sort_lengthバイトだけが使用されます。 See BLOB.

  * FOREIGN KEY、CHECK及びREFERENCES節は実際には何も行いません。これらの構文は、互換性のためだけに用意されており、他のSQLサーバからのコードの移植を容易にしたり、参照情報と共にテーブルを作成するようなアプリケーションを動作させることを目的としています。 See Missing functions.

  * 全てのNULLフィールドは、1ビット余計に消費し、直近のバイトに丸められます。

  * レコードの最大長は、以下のようにして求められます:

          レコードの長さ = 1
                     + (フィールドの長さの合計)
                     + (NULLフィールドの数 + 7)/8
                     + (可変長フィールドの数)

  * table_options と SELECT オプションは、 MySQL 3.23 以上でのみ実装されます。

     テーブル型は：

     ISAM   オリジナルのテーブル see ISAM.
     MyISAM   新しい、バイナリ互換のテーブル see MyISAM.
     HEAP   このテーブルのデータは、メモリー内にのみ蓄えられる see HEAP.
     BDB または Berkeley_db   トランザクション安全なテーブル see BDB.

     See Table types.

     その他のテーブルオプションを使って、テーブルの振る舞いを最適化します。たいていの場合は、オプションを明示する必要がありません。明示的に指定されなかった場合、オプションはすべてのテーブル型に作用します。

     AUTO_INCREMENT   あなたがこのテーブルにセットしたい、次の auto_increment 値
     AVG_ROW_LENGTH   テーブルに含まれるレコードの長さのおおよその平均値。 可変長のレコードを持つ場合にのみ、これをセットします。
     CHECKSUM   MySQL に全てのレコードをチェックさせたい場合、これを 1 にセットします。 (これは更新を遅くさせますが、不整合の生じたテーブルを見つけ出しやすくなります) (MyISAM)
     COMMENT   テーブルの、60文字コメント
     MAX_ROWS   あなたがテーブルに保存したいと考えている最大レコード数。
     MIN_ROWS   あなたがテーブルに保存したいと考えている最低レコード数
     PACK_KEYS   より小さいインデックスにしたいなら、これを 1 にします。 これは更新を遅くしますが、読み出しは速くなります (MyISAM, ISAM).
     PASSWORD   .frm ファイルをパスワード付きで暗号化。 このオプションは、標準の MySQL バージョンではなにも行いません。
     DELAY_KEY_WRITE   テーブルがクローズされるまでキーテーブルの更新を送らせたい場合、1に設定します(MyISAM)。
     ROW_FORMAT   レコードがどのように格納されるかを定義します(将来のため)。

     MyISAM テーブルを使用するならば、MySQL は max_rows * avg_row_length の値を、テーブルがどのくらい大きくなるかの推定に使用します。もし、上記のオプションをなにも指定しなかった場合、テーブルの最大サイズは 4G になります。(か、あなたの OS が 2G しかサポートしていなければ 2G まで)

     PACK_KEYS を使用しない場合、デフォルトは文字列だけをパックし、数値はパックしません。PACK_KEYS=1 を使用するとさらに数値もパックされます。

     バイナリ数値キーをパックする時、MySQL はプレフィックス圧縮を使用します。これは、同じ数値を多く持つ場合にだけこの大きな恩恵を得るということを意味します。プレフィックス圧縮は、前のキーの何バイトが次のキーと同じであるかを示すための余計な1バイトがすべてのキーに必要となることを意味します(注意: レコードへのポインタは、圧縮の向上のため high-byte-first-order でキーの直後に格納されます)。これは、2つのレコードが同じキー多く持つ場合、後のすべての'同じ'キーは通常2バイト(レコードへのポインタを含む)だけを必要とするということです。これを、通常のケースと比較してみてください。通常のケースは、後のキーは'キーの格納サイズ' + ポインタサイズ(通常4)を必要とします。一方、すべてのキーが全く異なっていると、キーが NULL 値を持つことができるキーではない場合では、キー毎に1バイトを消費します(この場合、パックされたキーの長さは、キーが NULL の時にマークのために使用されるのと同じバイト数で格納されます)。

  * もし CREATE STATEMENT の後に SELECT を指定するならば、 MySQL は、SELECT で返ってくる全ての項目を収めるために、新しいフィールドを作成します。例えば：

          mysql> CREATE TABLE test (a int not null auto_increment,
                     primary key (a), key(b))
                     TYPE=HEAP SELECT b,c from test2;

     これは 3つのフィールドを HEAP テーブルに作成します。もしデータをテーブルにコピーしている最中にエラーが起きたなら、このテーブルは自動的に消去されることに注意してください。

  * RAID_TYPE オプションは、大規模ファイルをサポートしていない OS 上の 2G/4Gの制限を破る手助けをします。また、RAID ディレクトリを別の物理ディスクに置くことにより、IO ボトルネックからさらに速度を得ることができます。RAID_TYPE は、MySQL を --with-raid でコンフィグすれば、どんな OS 上でも働きます。現在、RAID_TYPE は STRIPED だけが許されています(1 と RAID0 はこれの別名です)。

     RAID_TYPE=STRIPED を MyISAM テーブルに指定すると、 MyISAM はデータベースディレクトリ中に 00, 01, 02 という名前の RAID_CHUNKS サブディレクトリを生成します。これらのディレクトリのそれぞれに、MyISAM は table_name.MYD を生成します。データファイルにデータが書き込まれる時、RAID ハンドラは最初の RAID_CHUNKSIZE *1024 バイトを最初のファイルに、次の RAID_CHUNKSIZE *1024 バイトを次のファイルにマップします。

暗黙のフィールド定義変更
------------

いくつかのケースにおいてMySQLは、CREATE TABLEステートメントで与えられたフィールド定義を暗黙の内に変更します (これは ALTER TABLE で起きるかもしれません)

  * フィールド長が4未満のVARCHARフィールドはCHARに変更されます。

  * テーブル内にいくつかの可変長フィールドがある場合、結果的にレコード全体が可変長となります。その結果、テーブルがいくつかの可変長フィールド(VARCHAR、TEXT及びBLOB) を持つならば、3文字より大きいフィールド長の全てのCHARフィールドは、 VARCHARフィールドに変更されます。このことは、フィールドの使用方法には影響しません。 MySQLでは、VARCHARは文字列を格納するための1つの手段に過ぎません。 MySQLは、スペース埋めのコンバージョンを行いますし、テーブル操作もより速く行います。 See Table types.

  * TIMESTAMPフィールドの表示サイズは、2〜14の範囲の偶数でなければなりません。表示サイズを0や14より大きく指定した場合、サイズは14に強制されます。1から13の範囲の奇数の場合、大きい方の偶数値に強制されます。

  * TIMESTAMP フィールドには NULL を代入できません； NULL は現在の日時をセットします。 NULL and NOT NULL 属性は通常の方法では適用されず、それらを与えた場合は無視されます。 DESCRIBE tbl_name は常に TIMESTAMP フィールドに NULL 値が割り当てられた事を告げます。

  * MySQL は他の SQL データベースの使用している型を MySQL 型にマップします。 See Other-vendor column types.

もし MySQL がフィールドの型をあなたが指定したものと違うものにしたかどうかを知りたい場合、テーブルの作成、alter 後に、 DESCRIBE tbl_name 構文を発行します。

myisampackを使用してテーブルを圧縮した場合、別のフィールド定義変更がある程度起こることがあります。 See Compressed format.

ALTER TABLE構文
=============

     ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]

     alter_specification:
             ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
       or    ADD [COLUMN] (create_definition, create_definition,...)
       or    ADD INDEX [index_name] (index_col_name,...)
       or    ADD PRIMARY KEY (index_col_name,...)
       or    ADD UNIQUE [index_name] (index_col_name,...)
       or    ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
       or    CHANGE [COLUMN] old_col_name create_definition
       or    MODIFY [COLUMN] create_definition
       or    DROP [COLUMN] col_name
       or    DROP PRIMARY KEY
       or    DROP INDEX index_name
       or    RENAME [AS] new_tbl_name
       or    table_options

ALTER TABLEは、既存のテーブルの構造変更を可能にします。例えば、フィールドの追加や削除、インデックスの作成や破棄、既存のフィールド属性の変更、及びフィールドやテーブルそのものの名前の変更です。また、テーブルのコメントやテーブルの型式を変更することも可能です。 See CREATE TABLE.

もし ALTER TABLE でフィールド定義を変えても DESCRIBE tbl_name がフィールドを変更していないと示すなら、これは MySQL が Silent column changes. に述べている理由の一つで変更していない可能性があります。 例えば、 VARCHAR フィールドを CHAR にしようとすると, MySQL はそのテーブルに他の可変長のフィールドがあるかぎり、 VARCHAR のままにしようとします。

ALTER TABLEはオリジナルのテーブルの一時的なコピーを作成することにより動作します。コピーへの変更作業が完了すると、オリジナルのテーブルは削除され新しく作られた方の名前が変更されます。これは全ての変更が自動的に新しいテーブルに対して実施されることにより、誤った変更無しに完了します。ALTER TABLEが実行されている間、オリジナルのテーブルは他のクライアントから読みだしが可能です。このテーブルへの更新や書き込みは、新しいテーブルが準備完了となるまで遅らされます。

  * ALTER TABLEを使うには、そのテーブルにselect、insert、 delete、update、create、それからdrop 権限が必要です。

  * IGNOREはANSI SQL92に対するMySQLの拡張です。これは、新しいテーブルのユニークキーで重複があった場合の動作を制御します。 IGNOREが指定されない場合、コピーは異常終了し、ロールバックされます。 IGNOREが指定された場合、ユニークキーの重複があったレコードに対し、最初のレコードだけを使用し、他は削除されます。

  * 1つのALTER TABLEステートメントの中で、ADD、ALTER、 DROP、それからCHANGE節の複合的な発行が可能です。これは、ALTER TABLEステートメント毎に1つだけしかこれらの節を許さないANSI SQL92に対するMySQLの拡張です。

  * CHANGE col_name、DROP col_name及びDROP INDEXはANSI SQL92に対するMySQLの拡張です。

  * MODIFY は Oracle の ALTER TABLE 拡張です。

  * オプション語COLUMNは蛇足であり、記述を省くことが可能です。

  * 他のオプション無しでALTER TABLE tbl_name RENAME AS new_nameを使用すると、 MySQLはtbl_nameに一致するテーブルの名前を単純に変更します。テンポラリテーブルの作成は必要としません。

  * create_definitionは、CREATE TABLEにおけるADDやCHANGEと同じ構文を使用します。 See CREATE TABLE.

  * CHANGE old_col_name create_definition節を使用することによりフィールドの名前を変更することができます。このようなことを行うためには、フィールドの旧名称と新名称、それからそのフィールドの現在の型を指定する必要があります。例えば、あるINTEGERフィールドをaからbに変更する場合、以下のように実行することができます:

          mysql> ALTER TABLE t1 CHANGE a b INTEGER;

     もしフィールドの名前を変えることなく、型だけを変更したい場合であっても、この CHANGE 構文は、たとえ同じ名前であっても、２つの名前を指定するよう要求します。例:

          mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;

     しかし MySQL 3.22.16a からは,  MODIFY を使用して、名称変更をすることなくフィールドの型を変更することができます。

          mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;

  * CHANGE や MODIFY を使用して、フィールドの一部にインデックスが存在するようなフィールドを短くしようとしても(例えば VARCHAR フィールドの最初の10文字上ににインデックスがある場合)、インデックスされた文字数よりもフィールドを短くすることはできません。

  * CHANGE や MODIFY を用いてフィールドの型を変更する場合、 MySQLは可能な限り新しい型にデータをコンバートしようと試みます。

  * MySQL 3.22以降では、FIRST又はADD ... AFTER col_nameを使用して、テーブルのレコード内の指定した位置に、フィールドを追加することができます。デフォルトでは、フィールドは(そのレコードの)最後に追加されます。

  * ALTER COLUMNは、フィールドの新たな初期値を指定したり、フィールドの古い初期値を削除したりします。古い初期値が削除され、フィールドがNULLを許す場合、新たな初期値はNULLとなります。 NULLが許されない場合、MySQLはある初期値を割り当てます。割り当てる初期値は、 CREATE TABLE. で説明されています。

  * DROP INDEXは、インデックスを削除します。これはANSI SQL92に対するMySQLの拡張です。

  * フィールドがテーブルから削除されると、そのフィールドが含まれているインデックスからもそのフィールドが削除されます。インデックスを構成する全てのフィールドが削除されると、そのインデックスも削除されます。

  * DROP PRIMARY KEYは、プライマリ・インデックスを削除します。もしプライマリインデックスが存在しなければ、そのテーブルの最初のUNIQUEインデックスが削除されます。 (MySQLは、明示的にPRIMARY KEYが指定されなければ最初のUNIQUEキーをPRIMARY KEYとして扱います。)

  * C API関数mysql_info()により、どれだけのレコードがコピーされたか、(IGNOREが指定されている時は)どれだけのレコードがユニークキーの重複により削除されたかを調べることができます。

  * FOREIGN KEY、CHECK及びREFERENCES節は、実際には何もしません。これらの構文は、互換性のためだけに用意されており、他のSQLサーバからのコードの移植を容易にしたり、参照情報と共にテーブルを作成するようなアプリケーションを動作させることを目的としています。 See Missing functions.

以下は、ALTER TABLEの使用例を表す例です。次に示すように作成されたテーブルt1から始めます:

     mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));

テーブルt1の名前をt2に変更するには:

     mysql> ALTER TABLE t1 RENAME t2;

フィールド aを INTEGER から TINYINT NOT NULL に (名前は同じままで)変更し、 b を CHAR(10) から CHAR(20) に変更しつつ、名前を b から cに変更するには:

     mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);

TIMESTAMPを追加し、名前をdとするには:

     mysql> ALTER TABLE t2 ADD d TIMESTAMP;

フィールドdにインデックスを追加し、フィールドaをプライマリ・キーとするには:

     mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);

フィールドcを削除するには:

     mysql> ALTER TABLE t2 DROP COLUMN c;

c という名前の NULL を許可しない AUTO_INCREMENT 整数フィールドを追加し、作成するには:

     mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
                ADD INDEX (c);

ここで我々が c をインデックス指定したのは、 AUTO_INCREMENT フィールドはインデックスであるべきだからで、 c を NOT NULL 指定しているのはインデックスフィールドは NULL にできないからです。

AUTO_INCREMENT フィールドを追加した場合、フィールドの値は自動的にシーケンス番号で埋められます。

See also ALTER TABLE problems.

DROP TABLE構文
============

     DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...]

DROP TABLEは、1つ又は1つ以上のテーブルを破棄します。テーブルの全てのデータとテーブル定義は破棄されますので、このコマンドの使用は慎重に行ってください！

MySQL 3.22以降では、テーブルが存在しないことに起因するエラーを防ぐために、キーワード IF EXISTS を使用することができます。

OPTIMIZE TABLE構文
================

     OPTIMIZE TABLE tbl_name

OPTIMIZE TABLEは、テーブルの大部分を削除したり、可変長となっているテーブル(VARCHAR、BLOBもしくはTEXTフィールドを持つテーブル)に多くの変更を加えた場合に使用すべきです。削除されたレコードはリンクリストで維持され、次のINSERT操作は、古いレコード位置を再利用します。未使用領域を再生するためにOPTIMIZE TABLEを使用することができます。

OPTIMIZE TABLEは、オリジナルのテーブルの一時的なコピーを作成することにより動作します。古いテーブルは新しいテーブルに(未使用レコードを除いて)コピーされ、元のテーブルが削除されてから新しいテーブルの名前が変更されます。 OPTIMIZE TABLEが実行されている間、オリジナルのテーブルは他のクライアントから読みだしが可能です。このテーブルへの更新や書き込みは、新しいテーブルが準備完了となるまで遅らされます。これは全ての変更が自動的に新しいテーブルに対して実施されることにより、誤った変更無しに完了します。

CHECK TABLE 構文
==============

     CHECK TABLE tbl_name[,tbl_name...] [TYPE = QUICK]

テーブルのエラーをチェックします。このコマンドは次のフィールドを持つテーブルを返します:

Table   テーブル名
Op   常に 'check'
Msg_type   status, error, info, warning の一つ。
Msg_text   メッセージ。

注意: チェックされた各テーブルに対する情報の多くのレコードが得られます。最後の１レコードは Msg_type status になり、通常は OK であるべきです。OK が得られない場合は、テーブルの修復を通常通り実行すべきです。See Table maintenance。

TYPE=QUICK が与えられた場合は、MySQL は固定長レコードテーブルのレコードを走査しません。

CHECK TABLE は MyISAM テーブルだけで動作し、テーブルに対する myisamchk -m table_name の実行と同じことです。

REPAIR TABLE 構文
===============

     REPAIR TABLE tbl_name[,tbl_name...] [TYPE = QUICK]

REPAIR TABLE は MyISAM テーブルだけで動作します。テーブルに myisamchk -r table_name を実行することと同じです。

壊れたテーブルを修復します。コマンドは次のフィールドを含むテーブルを返します:

Table   テーブル名
Op   常に 'repair'
Msg_type   status, error, info, warning のどれか
Msg_text   メッセージ

注意: 修復された各テーブルの情報の多くのレコードを得ることがあります。最後の１レコードは Msg_type status になり、通常は OK であるべきです。OK が得られなければ、myisamchk -o でテーブルの修復を試みるべきです。REPAIR TABLE はまだ myisamchk のすべてのオプションを実装していないためです。近い将来、我々はこれをより柔軟にする予定です。

If TYPE=QUICK is given then MySQL will try to do a REPAIR of only the index tree.

DELETE構文
========

     DELETE [LOW_PRIORITY] FROM tbl_name
         [WHERE where_definition] [LIMIT rows]

DELETEは、tbl_nameより、where_definitionにて与えられた条件を満たすレコードを削除し、削除されたレコード数を返します。

WHERE節を指定することなしにDELETEを発行した場合、全てのレコードが削除されます。 MySQLは、これを空テーブルを再作成することで実現しており、これは、全てのレコードを実際に削除するよりもかなり早く動作します。この場合DELETEは、影響のあったレコード数として0を返します。 (再作成は、元のデータが格納されているファイルをオープンすることなく実施されますから、MySQLは実際に削除されたレコード数を返すことができません。たとえデータファイルやインデックスファイルが乱されたとしても、テーブル定義ファイルtbl_name.frmが有効である限り、このような方法でテーブルの再作成が可能となります。)

もし全てのレコードを削除している時に、いくつのレコードが消され、いくつのレコードがスピードを犠牲にしているのか、本当に知りたいならば、 DELETE 構文を以下のように使用します：

     mysql> DELETE FROM tbl_name WHERE 1>0;

これは DELETE FROM tbl_name を WHERE 節なしで行うよりも、とても遅いです。なぜなら一度で消そうとするからです。

キーワードLOW_PRIORITYを指定した場合、そのテーブルを読んでいるクライアントがいなくなるまでDELETEの実行は遅らせられます。

削除されたレコードはリンクリストで維持され、次のINSERT操作は、古いレコード位置を再利用します。ファイルをより小さくしたい場合は、OPTIMIZE TABLEステートメントかテーブルの再編成のためにmyisamchkユティリティを使用してください。 OPTIMIZE TABLEの方が簡単ですが、myisamchkの方が早く動作します。 See OPTIMIZE TABLE, と Optimization.

MySQL-特化  DELETE の LIMIT rows オプションはサーバーに消す最大のレコード数をつげます。これは DELETE コマンドがあまりに多くの時間を取らないために使用されます。 LIMIT 値よりも affected row の数が少なくなるまで、単純に DELETE コマンドを繰り返すだけです。

SELECT構文
========

     SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
            [HIGH_PRIORITY]
            [DISTINCT | DISTINCTROW | ALL]
         select_expression,...
         [INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
         [FROM table_references
             [WHERE where_definition]
             [GROUP BY {unsigned_integer | col_name | formula}]
             [HAVING where_definition]
             [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
             [LIMIT [offset,] rows]
             [PROCEDURE procedure_name] ]

SELECTは通常、1つまたは1つ以上のテーブルからレコードを検索して抽出するのに使用されます。 select_expression は取り出したいフィールドを示します。 SELECTはまた、テーブルの参照なしに計算によって求められたレコードを取り出すために使用されます。例:

     mysql> SELECT 1 + 1;
              -> 2

全てのキーワードの使用は、上記に示すような順序で正確に与えられる必要があります。例えば、HAVING節は必ずGROUP BY節の後、ORDER BY節の前でなければなりません。

  * SELECTの表現では、ASによる別名の指定が可能です。別名は、フィールド名の表現として使われ、ORDER BY及びHAVING節とともに使用することができます。例:

          mysql> select concat(last_name,', ',first_name) AS full_name
              from mytable ORDER BY full_name;

  * FROM table_references節は、(例えば、選択するレコードにより、1つ又はそれ以上の)結合するテーブルのリストを示します。このリストはまた、LEFT OUTER JOIN参照を含むことがあります。 See JOIN.

  * col_name、tbl_name.col_name、db_name.tbl_name.col_nameのようにしてフィールドを表すことができます。 SELECTステートメント内での列の参照が曖昧でなければ、tbl_nameやdb_name.tbl_nameのようなプリフィックスを詳細に記述する必要はありません。より明示的なフィールドの指定形式をを必要とする曖昧な参照の例は、Legal namesを参照のこと。

  * テーブル参照は、tbl_name AS alias_name又はtbl_name alias_nameを使って別名を使用することが可能です。

          mysql> select t1.name, t2.salary from employee AS t1, info AS t2
                     where t1.name = t2.name;
          mysql> select t1.name, t2.salary from employee t1, info t2
                     where t1.name = t2.name;

  * LIKEの表現において、ワイルドカード・キャラクタである%や_ は、これらの通常のワイルドカードとしての意味を抑制するために\の後に置かれることにより、定数%や_の検索に使われます。

  * 出力用に選択されたフィールドは、ORDER BY節やGROUP BY節において、フィールド名、フィールドのエイリアス名、又はフィールド番号にて指し示すことができます。フィールド番号は1から始まります。

          mysql> select college, region, seed from tournament
                     ORDER BY region, seed;
          mysql> select college, region AS r, seed AS s from tournament
                     ORDER BY r, s;
          mysql> select college, region, seed from tournament
                     ORDER BY 2, 3;

     逆順で並べたい場合には、 ORDER BY 節の中で、あなたが並べたいと思っているフィールドの名前の後ろに、 DESC (descending) キーワードを追加します。デフォルトは昇順です； これは ASC キーワードを指定したことになります。

  * HAVING節は、select_expressionにおいてどのフィールドの名前やエイリアス名でも指し示すことができます。これは最後に適用され、クライアントにアイテムが送られる直前に実行されるので、最適化されません。 WHERE節で書くべきものにHAVINGを用いてはいけません。例えば、次のように書いてはいけません:

          mysql> select col_name from tbl_name HAVING col_name > 0;

     その代わりに、次のように書いてください:

          mysql> select col_name from tbl_name WHERE col_name > 0;

     MySQL 3.22.5以降では、次のようにクエリを記述することができます:

          mysql> select user,max(salary) from users
                     group by user HAVING max(salary)>10;

     MySQLの古いバージョンでは、この代わりに次のように記述できます:

          mysql> select user,max(salary) AS sum from users
                     group by user HAVING sum>10;

  * SQL_SMALL_RESULT, SQL_BIG_RESULT, SQL_BUFFER_RESULT, STRAIGHT_JOIN, HIGH_PRIORITY は ANSI SQL92 に対する MySQL 拡張です。

  * HIGH_PRIORITY は、テーブルの更新よりも SELECT を優先させます。これは一度で完了する、とても速いクエリにのみ適用すべきです。もしリードロックされているテーブルがあったとし、たとえ update 文がこのテーブルの解除を待っていたとしても、 SELECT HIGH_PRIORITY クエリは実行されます。

  * SQL_BIG_RESULT は GROUP BY や DISTINCT と共に使用する事ができ、結果セットが多くのレコードを持つことをオプティマイザに知らせます。この場合、必要なら MySQL はディスクベースの一時テーブルを直接使用します。MySQL はこの場合、GROUP BY 要素上のキーで一時テーブルを行なう代わりにソートを行なうことを選択します。

  * SQL_SMALL_RESULT (MySQL 固有のオプション) は GROUP BY か DISTINCT と共に使用する事ができ、結果セットが小さくなることをオプティマイザに知らせます。この場合、 MySQL はソートする代わりに、速い一時テーブルを結果の保存のために使用します。 MySQL 3.23 では、これは通常必要ではありません。

  * STRAIGHT_JOINは、FROM節にて記述されたテーブルの順序に従って結合するよう、オプティマイザに強制します。オプティマイザが、テーブルを最適な順序で結合しない場合に、クエリのスピードアップのためにこれを使用することが可能です。 See EXPLAIN.

  * LIMIT 節は、 SELECT 構文で返されるレコード数を指定するのに使用されます。 LIMIT は一つか二つの数字の引数を取ります。

     引数が2つ与えられたならば、最初の引数は最初のレコードからのオフセットを示し、2つめの引数は返すレコードの最大数を示します。初めのレコードのオフセットは0です(1ではありません)。

          mysql> select * from table LIMIT 5,10;  # 6〜15行目を返す

     もし引数が一つなら、返すべきレコードの最大行数を指定したことになります。

          mysql> select * from table LIMIT 5;     # 最初の5行を取り出す

     いいかえれば、LIMIT n は LIMIT 0,n と同じです。

  * SELECTの書式、SELECT ... INTO OUTFILE 'file_name'は、選択されたレコードをファイルに書き込みます。ファイルはサーバ機に作成され、既に存在するファイルであってはなりません(/etc/passwdのようなファイルの破壊を防止します)。 SELECT ... INTO OUTFILEは、LOAD DATA INFILEの逆です。export_optionsの構文は、LOAD DATA INFILEステートメントの一部で使われるFIELDS節やLINES節と同じような構成です。 See LOAD DATA.

     INTO OUTFILEを使うとき、エスケープ・キャラクタ、ASCII 0 (nul)、そして全てのターミネータ・キャラクタは、デフォルトでエスケープされることに気をつけてください。 See LOAD DATA.

     結果として取り出されるテキストファイルでは、以下に示す文字が ESCAPED BY 指定の文字によってエスケープされます：

       * ESCAPED BY 文字自身

       * FIELDS TERMINATED BY の最初の文字

       * LINES TERMINATED BY の最初の文字

     さらに、 ASCII 0 は、ESCAPED BY 0 (ASCII 48) にコンバートされます。

     いかなる FIELDS TERMINATED BY, ESCAPED BY, LINES TERMINATED BY 指定されている文字も、エスケープしなければならない理由は、テキストファイルを読み返せれるようにするためなのです。 ASCII 0 はいくつかのページャーでも見れるようにするためにエスケープされるのです。

     結果のファイルは SQL の文を含んでいないので、何もエスケープする必要はありません。

INTO OUTFILE の代わりに INTO DUMPFILE を使用すると、 MySQL はファイルに１レコードだけを書きます。フィールドや行の終端とすべてのエスケープを含みません。これはファイル内に BLOB を格納したい場合に便利です。

JOIN 構文
=======

MySQLは、以下に示すSELECTステートメントにおけるJOIN構文をサポートします:

     table_reference, table_reference
     table_reference [CROSS] JOIN table_reference
     table_reference INNER JOIN table_reference join_condition
     table_reference STRAIGHT_JOIN table_reference
     table_reference LEFT [OUTER] JOIN table_reference join_condition
     table_reference LEFT [OUTER] JOIN table_reference
     table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
     { oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr }

Where table_reference is defined as

     table_name [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)]

and join_condition is defined as

     ON conditional_expr |
     USING (column_list)

Note that in version before 3.23.16 the INNER JOIN didn't take a join condition!

上に示す最後のLEFT OUTER JOIN構文は、ODBCとの互換性のためだけに存在します。

  * table referenceは、tbl_name AS alias_nameやtblname alias_nameによる別名を指定することができます。

          mysql> select t1.name, t2.salary from employee AS t1, info AS t2
                     where t1.name = t2.name;

  * INNER JOINと, (コンマ)は、同義語です。どちらも使用されるテーブル間の直積をとります。通常はWHERE条件にて、テーブルがどのようにリンクされるべきかを定義します。

  * ON条件節は、WHERE節で使用されるような条件文の書式です。

  * もし、LEFT JOIN の ON や USING において右側のテーブルにマッチするレコードが無かった場合、全てのフィールドがNULLである1つのレコードが、右側のテーブルとして使用されます。この事実は、あるテーブルについて、他のテーブルに対応するレコードが存在しないレコードを探すということに利用できます:

          mysql> select table1.* from table1
                     LEFT JOIN table2 ON table1.id=table2.id
                     where table2.id is NULL;

     この例は、table1の内、idの値がtable2に存在しない全てのレコードを検索します。(即ち、table2内のレコードと一致しないtable1の全てのレコード。) もちろん、この場合のtable2.idは、NOT NULLと定義されているものと仮定します。

  * USING (column_list)節のフィールド名リストは、両方のテーブルに存在しなければなりません。USING節が次のように:

          A LEFT JOIN B USING (C1,C2,C3,...)

     定義されることは、ON式がこのように定義されるのと同義です:

          A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...

  * 同じフィールド名を持つ2つのテーブルの NATURAL [LEFT] JOIN は、 USING 節を伴った INNER JOIN や LEFT JOIN と同じとして定義されます。

  * STRAIGHT_JOINは、右側のテーブルの前に、常に左側のテーブルを読むことを除けば、JOINと全く同じことです。これは、結合オプティマイザが、不当な順序でテーブルを出力するようなまれな事態に使用できます。

  * MySQL 3.23.12 から、テーブルから情報を取り出す時に、 MySQL がどのインデックスを使用すべきかというヒントを与えることができるようになりました。これは、MySQL が間違ったインデックスを使用していることを EXPLAIN が示す場合に有用です。USE INDEX (key_list) を指定することによって、テーブルからレコードを見つけるために、指定されたインデックスの一つだけを使用するように MySQL に伝えることができます。別の構文 IGNORE INDEX (key_list) は、MySQL に特定のインデックスを使用しないように伝えるために使用できます。

例:

     mysql> select * from table1,table2 where table1.id=table2.id;
     mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id;
     mysql> select * from table1 LEFT JOIN table2 USING (id);
     mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id
                LEFT JOIN table3 ON table2.id=table3.id;
     mysql> select * from table1 USE INDEX (key1,key2) WHERE key1=1 and key2=2 AND
            key3=3;
     mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND
            key3=3;

See LEFT JOIN optimization.

INSERT構文
========

         INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
             [INTO] tbl_name [(col_name,...)]
             VALUES (expression,...),(...),...
     or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
             [INTO] tbl_name [(col_name,...)]
             SELECT ...
     or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
             [INTO] tbl_name
             SET col_name=expression, col_name=expression, ...

INSERTは、既存のテーブルに新しいレコードを挿入します。 INSERT ... VALUES書式は、値の明示指定を基本としてレコードを挿入します。 INSERT ... SELECT書式は、他の表(複数可)から抽出したレコードを挿入します。複数の値リストを用いるINSERT ... VALUES書式は、MySQL 3.22.5以降でサポートされています。 col_name=expression構文は、MySQL 3.22.10以降でサポートされています。

tbl_nameは、レコードを挿入するテーブルです。フィールド名リストは、後続の値定義ステートメントのフィールドを指し示します。

  * もしいかなるフィールドも INSERT ... VALUES や INSERT ... SELECT などで明示しなければ、全てのフィールドの値が VALUES() の中に与えられなくてはなりません。テーブル内のフィールド順が不明な場合、これを調べるためにDESCRIBE tbl_nameを使用して下さい。

  * テーブル内の一部のフィールドしか指定しない場合、指定されなかったフィールドには、それぞれの初期値が指定されます。初期値の割当ては、CREATE TABLE. で述べられています。

  * NULLをTIMESTAMPフィールドに挿入した場合、フィールドには現在時刻がセットされます。他の値を挿入した場合、指定された値が単純にセットされます。

  * expressionは、値リスト内で先頭に近い方のフィールドを参照しなければなりません。例えば、次のように記述できます:

          mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);

     しかし、次のようには記述できません:

          mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);

  * キーワードLOW_PRIORITYを指定した場合、INSERTの実行はそのテーブルから値を読み込むクライアントがいなくなるまで遅らされます。この場合、クライアントは insert 文が完了するまで待たされます。テーブルが頻繁に使用される場合、長い時間かかります。これはクライアントを一度に継続させる INSERT DELAYED と対称的です。

  * もし IGNORE キーワードを INSERT に 値とともに 与えるなら、テーブル内の PRIMARY や UNIQUE キーにすでに存在する重複したものは無視され、挿入されません。多重行の値を含むレコードの INSERT にキーワード IGNORE を指定しない場合、テーブルの PRIMARY キーや UNIQUE キーに重複が起こる際に、挿入処理が異常終了します。 IGNORE を指定した場合、重複するキー値を持つレコードは挿入されません。 C API 関数 mysql_info() により、テーブルにいくつのレコードが挿入されたかチェックすることができます。

  * MySQLが、DONT_USE_DEFAULT_FIELDSオプションにより制限されていた場合、NULL値を許さない全てのフィールドに明示的に値をしないとINSERTステートメントは、エラーを生成します。 See configure options.

  * 以下の条件は、INSERT INTO ... SELECTステートメントのために用意されています:

       - クエリーは、ORDER BY節を含むことができません。

       - INSERTステートメントのターゲットとなるテーブルは、クエリー内SELECT部のFROM節に指定できません。なぜなら、挿入先のテーブルからのSELECTはANSI SQLで禁じられているからです。(問題は、SELECTが実行中に挿入したレコードを抽出することが可能であることです。副問い合わせ節を使用するときに、このような状況で混乱しやすくなります！)

       - AUTO_INCREMENTフィールドは、通常通り動作します。

多重の値リストを持つ INSERT ... SELECT ... 又は INSERT ... VALUES() ステートメントを使用する場合、クエリーに関する情報を得るために C API関数 mysql_info() を使用することができます。その情報の書式は以下に示す文字列のようになります:

     Records: 100 Duplicates: 0 Warnings: 0

Duplicatesは、既に存在するユニークインデックスの値と重複することにより、挿入できなかったレコード数を表します。 Warningsは、挿入されたフィールドが何らかの疑わしい値であったという数を表します。警告は、次のような条件の下で発生します:

  * NOT NULL定義されたフィールドへのNULLの挿入。フィールドには初期値が設定されます。

  * 数値フィールドの範囲を超える値のセット。値は範囲内の限界値に補正されます。

  * 数値フィールドへの `10.34 a' のような値のセット。引きずっているゴミは取り除かれ、残りの数値部分が挿入されます。値が数値として判断できなかった場合、フィールドには 0 がセットされます。

  * CHAR、VARCHAR、VARCHAR、TEXT又はBLOBフィールドへの最大長を超える文字列の挿入。値はフィールドの最大長に切り捨てられます。

  * 日付又は時刻フィールドへのフィールド属性に反した挿入。その属性に適した``ゼロ''値がセットされます。

INSERT 構文の DELAYED オプションは MySQL 独自のオプションで、これは INSERT が完全に終了することを待てないクライアントを持つ場合に、とても役立ちます。これは、ロギングのために MySQL を使用する時の一般的な問題で、完了に長い時間がかかる SELECT ステートメントも定期的に実行できます。 DELAYED は MySQL 3.22.15 で導入されました。  これは ANSI SQL92 に対する MySQL 拡張です。

INSERT DELAYED を使用する時、クライアントは一度 ok となり、テーブルが他のスレッドで使用中でない時にレコードが挿入されます。

INSERT DELAYED を使用して得られるほかの利益は、多くのクライアントからの insert が同時に束ねられ、一つのブロックで書かれることです。 これは多くの別々の insert を実行するよりとても速くなります。

現在、キューイングされたレコードは、それらがテーブルに代入されるまでメモリーに保持されているだけです。 これは、もし mysqld を強引な方法 (kill -9) でキルしたり、 mysqld が予期せず死んだ場合、キューイングされているレコードはディスクに書かれず失われます！

DELAYED オプションを INSERT や REPLACE で使用する場合、以下のことがおきます。ここで ``スレッド'' とは INSERT DELAYED コマンドを受けたスレッドをさし、 ``ハンドラー'' とは特定のテーブルのための全ての INSERT DELAYED 構文を操作するスレッドを指します。

  * スレッドがあるテーブルに対し DELAYED 構文を実行するとき、そのテーブルに対する全ての DELAYED 構文を処理するためにハンドラースレッドが作成されます。もしそのようなハンドラーが存在していない場合には。

  * そのスレッドは、そのハンドラーが DELAYED ロックを既に持っているかどうかをチェックします； もし持っていないなら、そうするようにハンドラーに告げます。たとえ他のスレッドが READ か WRITE ロックをそのテーブルに持っていたとしても、 DELAYED ロックを得ることができます。しかし、そのハンドラーは全ての ALTER TABLE ロックか FLUSH TABLES を待ちます。 そのテーブル構造が最新であるのを確実にするために。

  * スレッドは INSERT ステートメントを実行しますが、レコードをテーブルに書く代わりに、ハンドラスレッドによって管理されるキューに最後のレコードのコピーを置きます。文法エラーはスレッドによって通知され、クライアントプログラムに報告されます。

  * クライアントは結果行の重複数や AUTO_INCREMENT の値を報告できません； それはサーバーから得ることができません。 なぜなら、 INSERT はインサートオペレーションが完全に終了する前に返るからです。 もし C API を使用しているなら、 mysql_info() 関数は同様の理由によりなにも返しません。

  * 更新ログは、レコードがそのテーブルに insert されたとき、そのハンドラースレッドによって更新されます。 複数レコードの挿入の場合、 更新ログは最初の行が挿入されたときに更新されます。

  * それぞれの delayed_insert_limit レコードが書かれた後、そのハンドラーはいかなる SELECT 文もまだ延期されていないかを確認します。もしそうなら、続ける前にこれらに対して実行を可能にします。

  * ハンドラーのキュー内にレコードがなくなったとき、テーブルはアンロックされます。もし新しい INSERT DELAYED コマンドが delayed_insert_timeout 秒以内に受け付けられなければ、ハンドラーは終了します。

  * もし、特定のハンドラーのキュー内に delayed_queue_size 以上のレコードが既に延期されているならば、そのスレッドは、キューに余裕がある間待ちます。これは mysqld サーバーが delayed されたキューに全てのメモリーを確実に使用しないようにするのに役立ちます。

  * そのハンドラースレッドは  MySQL プロセスリストの Command 項内に、 delayed_insert と共に表示されます。これは FLUSH TABLES コマンドか KILL thread_id を実行することで、 kill できるでしょう。しかし、これらは、終了する前に、キュー内の全てのレコードをテーブルに保存しようとします。この間、このスレッドは、他のスレッドから来たいかなる新しい INSERT コマンドも受け付けません。もし、この後に INSERT DELAYED コマンドを実行するなら、新しいハンドラースレッドが作成されます。

  * 上記のことは、もし INSERT DELAYED コマンドが既に走っているなら、 INSERT DELAYED コマンドは、普通の INSERT コマンドよりも高い優先度を持つということです！他の update コマンドは INSERT DELAY キューが空になるまで、あるいは誰かが KILL thread_id や FLUSH TABLES を実行してハンドラーをキルするまで、待たされます。

  * 以下のステータス変数は INSERT DELAYED コマンドについての情報を与えます：

     Delayed_insert_threads   ハンドラースレッドの数
     Delayed_writes   INSERT DELAYED で書かれるレコード数
     Not_flushed_delayed_rows   書き込みを待つレコード数

     これらの変数は SHOW STATUS 構文を発行したり mysqladmin extended-status コマンドを実行することで見れます.

注意: INSERT DELAYED は、テーブルが使用中でない場合、通常の INSERT よりも遅くなります。INSERT DELAYED を使用する各テーブルについて別のスレッドを操作するサーバの、追加のオーバーヘッドもあります。これは、確実にそれを必要とする時にだけ INSERT DELAYED を使用すべきことを意味します！

REPLACE構文
=========

         REPLACE [LOW_PRIORITY | DELAYED]
             [INTO] tbl_name [(col_name,...)]
             VALUES (expression,...)
     or  REPLACE [LOW_PRIORITY | DELAYED]
             [INTO] tbl_name [(col_name,...)]
             SELECT ...
     or  REPLACE [LOW_PRIORITY | DELAYED]
             [INTO] tbl_name
               SET col_name=expression, col_name=expression,...

REPLACEは、テーブル中の古いレコードがユニークインデックス上の新しいレコードと同じ値を持つ場合に、新しいレコードを挿入する前に、古いレコードを削除するということを除けば、INSERTと全く同じように動作します。 See INSERT.

LOAD DATA INFILE構文
==================

     LOAD DATA [LOW_PRIORITY] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE]
         INTO TABLE tbl_name
         [FIELDS
             [TERMINATED BY '\t']
             [OPTIONALLY] ENCLOSED BY '']
             [ESCAPED BY '\\' ]]
         [LINES TERMINATED BY '\n']
         [IGNORE number LINES]
         [(col_name,...)]

LOAD DATA INFILEステートメントは、テキストファイルからテーブルへと、レコードを高速に読み込みます。 LOCAL キーワードが指定されれば、ファイルはクライアント・ホストから読み込まれます。 LOCALが指定されなければ、ファイルはサーバに位置する必要があります (LOCALは、MySQL 3.22.6以降で利用できます)。

セキュリティ上の理由から、サーバからテキストファイルを読み出す時は、ファイルがデータベースディレクトリに存在するか、全てに読み込み権限がある必要があります。また、サーバファイルで LOAD DATA INFILE を使用するには、データベースの file 権限も持たなければなりません。 See Privileges provided.

もし LOW_PRIORITY を指定した場合、LOAD DATA 構文はそのテーブルから他のクライアントが読み込みを行っている間、遅らされます。

LOCAL 使用をすると、クライアント・ホストからサーバ・ホストへファイルの内容が転送される分、多少遅くなるでしょう。いうならば、ローカルのファイルを読み込むのに、 file 権限は必要ないということです。

mysqlimportユティリティは、データファイルの読み込みに使用することができます。; これは、サーバにLOAD DATA INFILEコマンドを送信することによって処理を実現しています。 --localオプションは、mysqlimportに、クライアント・ホストからデータファイルを読み込ませます。クライアントとサーバが圧縮プロトコルをサポートしていれば、低速なネットワークでより良いパフォーマンスを得るために、--compressオプションを指定することができます。

サーバ・ホストにファイルを置く場合、サーバは、以下のルールを使用します:

  * 完全なパスでファイル名が与えられた場合、サーバはパス名をそのまま使用します。

  * １つ又は複数の構成要素から成る相対パスと共にファイル名が与えられた場合、サーバは、サーバのデータディレクトリ以下からファイルを探します。

  * ファイル名だけが単に与えられた場合、サーバは、カレントのデータベースディレクトリを探します。

これらのルールは、ファイルが myfile.txt のように与えられればデータベースディレクトリからファイルが読み出され、 ./myfile.txt のように与えられれば、現在選択しているデータベースのデータディレクトリからファイルが読み出されるという意味であることに注意して下さい。

例えば、以下の LOAD DATA 文は、data.txt ファイルを db1 データベースディレクトリから読みます。 なぜなら、db1 は現在選択されているデータベースだからです。 たとえ、db2 データベースのテーブルに、ファイルから読み込んだデータを挿入するとしても。：

以下に示すような構文では、ファイルは db1 データベースディレクトリから読まれます。db2 ではありません:

     mysql> USE db1;
     mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;

REPLACE と IGNORE キーワードは、すでに存在するユニークキーに重複しているレコードの入力に対する制御です。 REPLACE 指定の場合、同じユニークキーを持つ既存のレコードは新しいレコードで置き換えられます。 IGNORE 指定の場合、既存のレコードのユニークキーと重複するキーをもつ新しいレコードは飛ばされます。 もし、どちらも指定しなかった場合、重複したキーが見つかった場合エラーが発生し、テキストファイルは無視されます。

LOCAL キーワードを使用してデータをローカルからロードする場合、サーバーは操作の途中で転送をとめる方法を知りません。それでデフォルトの動作としては IGNORE が指定されたのと同じになります。

LOAD DATA INFILEは、SELECT ... INTO OUTFILEの逆です。 See SELECT. データベースからファイルへデータを書き込むには、SELECT ... INTO OUTFILEを使用します。ファイルからデータベースに読み戻すには、LOAD DATA INFILEを使用します。 FIELDSとLINES節の構文は両方のコマンドとも同じです。どちらの節もオプションですが、両方を指定する場合は、FIELDSは、LINESより先に指定しなければなりません。

FIELDS節を指定した場合、その段落(TERMINATED BY、[OPTIONALLY] ENCLOSED BY及びESCAPED BY)は、少なくとも１つを指定しなければならないことを除いて、それらもまたオプションとなります。

FIELDS節を指定しなかった場合、初期値は以下のように記述したのと等価となります:

     FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'

LINES節を指定しなかった場合、初期値は以下のように記述したのと等価となります:

     LINES TERMINATED BY '\n'

言い換えると、LOAD DATA INFILE の初期値は、出力へ書き込む際に以下のように振舞います:

  * 改行をレコードの境界とみなす

  * タブ文字によってフィールドを区切る

  * クォート文字でフィールドを囲んでいないものとする

  * タブ文字や改行文字及び\の前に\があることにより、それらをフィールド値の一部のリテラル文字であるとして処理する。

逆に、LOAD DATA INFILEの初期値は、入力を読み込む際に以下のように振舞います:

  * フィールド間にタブ文字を書く

  * いずれのクォート文字でもフィールドを囲まない

  * \の使用により、フィールド値の中で使用するタブ文字や改行文字、\をエスケープする

  * レコードの終りに改行文字を書く

FIELDS ESCAPED BY '\\'と書いた場合、単一のバックスラッシュとして読み出される値とするために、２つのバックスラッシュを指定しなければならないことに注意して下さい。

IGNORE number LINES オプションはファイルの先頭にあるレコードを無視するのに使用されます：

     mysql> LOAD DATA INFILE "/tmp/file_name" into table test IGNORE 1 LINES;

データベースからファイルへデータを書き、それから後でそのファイルからデータベースへデータを読み戻すために、SELECT ... INTO OUTFILEと対にLOAD DATA INFILEを使う場合、双方のフィールドとレコードの取扱いに関するオプションは、一致しなければなりません。さもなければ、LOAD DATA INFILEは適切にファイルを処理しないでしょう。フィールドをコンマで区切ってファイルへ書き出すために、SELECT ... INTO OUTFILEを使用するとすれば:

     mysql> SELECT * FROM table1 INTO OUTFILE 'data.txt'
                FIELDS TERMINATED BY ','
                FROM ...

コンマ区切りファイルから読み戻すため、正しいステートメントはこうなるでしょう:

     mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
                FIELDS TERMINATED BY ',';

その代わりとして次に示すようなステートメントでファイルを読み込もうとしても、正しく動作しないでしょう。なぜなら、これは、LOAD DATA INFILEに対してフィールドの間にタブを探すよう指示するからです:

     mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
                FIELDS TERMINATED BY '\t';

おそらく、それぞれの入力行は単一のフィールドとして処理されるでしょう。

LOAD DATA INFILEは外部ソースからもファイルを読み出すことができます。例えば、dBASEフォーマットのファイルは、フィールドをコンマで区切られ、ダブルクォーテーションで囲まれています。レコードが改行文字で区切られているとしたら、次に示すフィールド及びレコードの取扱オプションを指定したコマンドが、このようなファイルを読み込むのに使用できます。

     mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
                FIELDS TERMINATED BY ',' ENCLOSED BY '"'
                LINES TERMINATED BY '\n';

いくつかのフィールド及びレコードの取扱オプションに、空文字列('')を指定することがあります。空でないなら、FIELDS [OPTIONALLY] ENCLOSED BYとFIELDS ESCAPED BYの値は単一の文字でなければなりません。FIELDS TERMINATED BYとLINES TERMINATED BYは２つ以上の文字となるでしょう。例えば、リターン文字と改行文字のペアで区切られたレコードを書き込んだり、このようなレコードを含んだファイルを読み込んだりするには、LINES TERMINATED BY '\r\n'節を指定します。

FIELDS [OPTIONALLY] ENCLOSED BYは、フィールドの引用符を制御します。出力の際(SELECT ... INTO OUTFILE)、OPTIONALLY語を省いたなら、全てのフィールドはENCLOSED BY文字で囲まれます。このような出力(フィールド区切りにコンマを使用)の例を次に示します:

     "1","a string","100.20"
     "2","a string containing a , comma","102.20"
     "3","a string containing a \" quote","102.20"
     "4","a string containing a \", quote and comma","102.20"

OPTIONALLYを指定すれば、ENCLOSED BY文字は、 CHARフィールドとVARCHARフィールドのみ囲むのに使用されます:

     1,"a string",100.20
     2,"a string containing a , comma",102.20
     3,"a string containing a \" quote",102.20
     4,"a string containing a \", quote and comma",102.20

フィールド値の中におけるENCLOSED BY文字の出現は、ESCAPED BY文字をその前に置くことによりエスケープされることに注意して下さい。ESCAPED BY値に空を指定すると、LOAD DATA INFILEにより正しく読み込めない出力を生成するでしょう。例えば、このようにエスケープ文字を空にした場合、以下に示すような出力となります。４行目の２つ目のフィールドに、(誤って)フィールドを区切るかのようなクォートに続くコンマを含んでいることに注視して下さい:

     1,"a string",100.20
     2,"a string containing a , comma",102.20
     3,"a string containing a " quote",102.20
     4,"a string containing a ", quote and comma",102.20

入力において、ENCLOSED BY文字が指定されており、それがフィールド値の両端に現れた場合、その文字は取り去られます。(これは、OPTIONALLYが指定されたかどうかに拘らず、当てはまります;OPTIONALLYは入力解析には効果がありません。) ESCAPED BY文字を前置きされたENCLOSED BY文字の出現は、現在のフィールド値の一部として処理されます。具体的には、あるフィールドがそれ自身、たENCLOSED BY文字で始まっている場合、フィールドらの内部で発生する２重のENCLOSED BY文字は、単一のENCLOSED BY文字として処理されます。例えば、ENCLOSED BY '"'が指定されると、引用符は以下のように操作されます:

     "The ""BIG"" boss"  -> The "BIG" boss
     The "BIG" boss      -> The "BIG" boss
     The ""BIG"" boss    -> The ""BIG"" boss

FIELDS ESCAPED BYは、特殊文字をどのように書き込んだり読み込んだりするかを制御します。 FIELDS ESCAPED BY文字が空でない場合、出力において次のような文字(文字列)のプリフィックスに使用されます:

  * FIELDS ESCAPED BY文字

  * FIELDS [OPTIONALLY] ENCLOSED BY文字

  * FIELDS TERMINATED BY値とLINES TERMINATED BY値の最初の文字

  * ASCII 0 (エスケープ文字の後に続いて実際に書かれる文字はASCII '0'で、'ゼロ値'バイトではありません)

FIELDS ESCAPED BY文字が空であれば、どの文字もエスケープされません。特に、フィールド値が上に示した文字を含んでいるならば、エスケープ文字に空を指定するのはあまり良い考えとは言えないでしょう。

入力において、FIELDS ESCAPED BY文字が空でない場合、この文字の出現は取り去られ、後続の文字はフィールド値の一部としてそのまま受け取られます。例外は、エスケープされた0やNです(例えば、エスケープ文字が\である時の\0や\N)。これらのシーケンスは、ASCII 0('ゼロ値'バイト) 、NULLとして処理されます。NULL操作の規則は下を参照して下さい。

\-escape syntaxに関するこれ以外の情報は、Literals参照。

フィールドとレコード操作オプションが確実に相互作用する事例:

  * LINES TERMINATED BYが空文字列でFIELDS TERMINATED BYが空でない場合、各レコードもまたFIELDS TERMINATED BYで終らせられます。

  * FIELDS TERMINATED BYとFIELDS ENCLOSED BY値が両方とも空('')の時、(区切られない)固定長行フォーマットが使用されます。固定長行フォーマットでは、フィールド間に区切り文字列が使用されません。その代わり、フィールド値は、フィールドの``表示''幅を使って書き込まれたり、読み込まれます。例えば、あるフィールドがINT(7)で定義されている場合、フィールドの値は7文字の桁を使って書き込まれます。入力においてフィールドは、７文字の読み込みにより得られます。固定長行フォーマットはまた、NULL値の操作に好んで用いられます;下を参照のこと。注意: マルチバイト文字セットを使用している場合は固定長フォーマットは働きません。

FIELDSとLINESオプションによるNULL値の多様な取扱い:

  * FIELDSとLINESの初期値のために、出力時にNULLは\Nとして書き込まれ、入力時に\NはNULLとして読み込まれます(当然のことながら、ESCAPED BY文字は\とします)。

  * FIELDS ENCLOSED BYが空で無い時、定数NULLのフィールド値はNULL値として読み込まれます(これは、文字列'NULL'として読み込まれるFIELDS ENCLOSED BY文字列で囲まれたNULLとは異なります)。

  * FIELDS ESCAPED BYが空の時、NULLはNULLとして書き込まれます。

  * 固定長行フォーマット(FIELDS TERMINATED BYとFIELDS ENCLOSED BYがいずれも空の場合に起こります)において、NULLは、空白文字列として書き込まれます。これは、ファイル内では、NULL値と空白値の見分けがつかないということを示していることに注意して下さい。ファイルからデータを読み戻す時に両者を区別しなければならない場合、固定長行フォーマットは使用すべきではありません。

キーワードREPLACEとIGNOREは、ユニーク・キー値が重複するレコードが存在する入力レコードの取扱いを制御します。 REPLACEを指定した場合、同じユニーク・キー値を持つ新しいレコードは、既に存在する同じユニーク・キーであるレコードを置き換えます。 IGNOREを指定した場合、既に存在するレコードのユニーク・キー値と重複する入力レコードは、スキップされます。いずれのオプションも指定していない場合、重複キーが発見された時点でエラーが発生し、テキストファイルの残りは無視されます。

LOAD DATA INFILEでサポートされないケース:

  * 固定長行(FIELDS TERMINATED BYとFIELDS ENCLOSED BYの両方が空)とBLOBフィールド。

  * あるセパレータを他と同じかもしくは他のプリフィックスとした場合、LOAD DATA INFILEは、正しい入力処理ができないでしょう。例えば、以下のFIELDS節は問題の原因となります:

          FIELDS TERMINATED BY '"' ENCLOSED BY '"'

  * FIELDS ESCAPED BYが空で、フィールド値に、FIELDS ENCLOSED BY値やLINES TERMINATED BY値の後にFIELDS TERMINATED BY値がくるようなものを含む場合、フィールドや行の読み込みが早めに打ち切られてしまいます。これは、LOAD DATA INFILEが、フィールドやレコードの終了位置を正しく決められないことにより発生します。

次の例は、persondataテーブルの全てのフィールドを読み込みます:

     mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;

フィールドリストが指定されていませんから、LOAD DATA INFILEは、入力レコードがテーブルのそれぞれのフィールドを含むものと想定します。 FIELDSとLINESの初期値が使用されます。

テーブルの一部のフィールドのみ読み込みたい場合、フィールドリストを指定します:

     mysql> LOAD DATA INFILE 'persondata.txt'
                INTO TABLE persondata (col1,col2,...);

テーブル内のフィールド順と入力ファイルのフィールド順が異なる場合にも、MySQLにテーブルのフィールドと入力フィールドの対応を教えるために、フィールドリストを指定しなければなりません。

入力レコードのフィールド数の方が少ない場合、入力フィールド値が与えられないフィールドは、初期値が設定されます。初期値の割当てについては、CREATE TABLE. で述べられています。

空のフィールド値は変換されます：

  * 文字型の場合、 フィールドの値は空文字にセットされます。

  * 数値型の場合、フィールドの値は 0 にセットされます。

  * 日付と時刻の型の場合、 フィールドの値は ``zero'' の意味する値がセットされます。 See Date and time types.

TIMESTAMP フィールドは、フィールド値に NULL 値が指定されていた場合もしくは、フィールドリストが指定されている時に TIMESTAMP フィールドがそのリストから除外されていた場合 (最初のTIMESTAMPフィールドのみ)、現在時刻が設定されるだけです。

入力レコードのフィールド数の方が多い場合、余分なフィールドは無視され、警告の数が増やされます。

LOAD DATA INFILEは全ての入力を文字列と文字列とみなすことから、INSERTステートメントでできるようなENUMフィールドやSETフィールドへの数値の指定はできません。全てのENUM及びSET値は文字列として与えられなければいけません！

LOAD DATA INFILEクエリの終了時、クエリの情報を得るためにC API関数mysql_info()を使用することができます。情報の書式は以下に示すようなものです:

     Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

LOAD DATA INFILE が、入力レコードのフィールド数の過不足があった時にも警告を引き起こす事を除けば、INSERT ステートメント (see INSERT. ) により値が挿入される時に警告が発生するのと同じ状況下で、警告が発生します。警告はどこにも保存されません； 警告の数は全てうまくいった場合にだけ使用できます。 もし警告を知りたい、その警告の理由を知りたいのなら、一つ方法があります。 SELECT ... INTO OUTFILE を使用して他のファイルに落とし、オリジナルのファイルと比べます。

INSERTと比較したLOAD DATA INFILEの効率やLOAD DATA INFILEの高速化についてのより詳しい情報は、see Insert speedを参照のこと。

UPDATE 構文
=========

     UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1,col_name2=expr2,...
         [WHERE where_definition] [LIMIT #]

UPDATE はテーブルに存在するレコードのフィールドを、新しい値に更新します。 SET 節はどのフィールドをどういった値にすべきかを示します。 WHERE 節が与えられた場合、更新すべきレコードを特定することになります。それ以外は、全てのレコードを更新します。

LOW_PRIORITY キーワードを指定した場合、UPDATE の実行は、テーブルを読んでいるクライアントがなくなるまで、遅らされます。

IGNORE キーワードを指定した場合は、update 文は、 update 中に二重キーのエラーを得たとしても、異常終了しません。 Rows that would cause conflicts will not be updated.

表記中の tbl_name からのフィールドをアクセスすると、UPDATE は現在のフィールド値を使用します。例えば、次のステートメントは age フィールドにその現在値より１大きい値を設定します:

     mysql> UPDATE persondata SET age=age+1;

UPDATE は左から右に評価されます。例えば、以下の文は age フィールドを 2倍にし、そのあと1増やします：

     mysql> UPDATE persondata SET age=age*2, age=age+1;

もしフィールドに現在もっている値を指定した場合、MySQL はそれを通知し、値は更新しません。

UPDATE は変更されたレコード数を返します。 MySQL 3.22 以上では、C API 関数 mysql_info() がマッチし更新されたレコード数を返します。また UPDATE 中に起きたワーニングの数も返します。

MySQL 3.23 では、 LIMIT # で指定した数だけレコードを変更できます。

USE 構文
======

     USE db_name

USE db_name 構文は、 MySQL に db_name データベースをこの後のクエリのデフォルトのデータベースにするように指示します。指定されたデータベースは、セッションの最後まで、あるいは、他の USE 構文が発行されるまで残ります：

     mysql> USE db1;
     mysql> SELECT count(*) FROM mytable;      # selects from db1.mytable
     mysql> USE db2;
     mysql> SELECT count(*) FROM mytable;      # selects from db2.mytable

USE 構文で特定のデータベースをカレントにしても、他のデータベースのテーブルからアクセスすることを妨げません。以下は db1 データベースの author テーブルと、 db2 データベースの editor テーブルにアクセスする例です：

     mysql> USE db1;
     mysql> SELECT author_name,editor_name FROM author,db2.editor
                WHERE author.editor_id = db2.editor.editor_id;

USE 構文は Sybase の互換のために提供されています。

FLUSH 構文 (キャッシュのクリア)
====================

     FLUSH flush_option [,flush_option]

FLUSH コマンドで MySQL が使用している内部キャッシュのいくつかをきれいに消すことができます。 FLUSH を実行するには、 reload 権限がなければなりません。

flush_option には以下の内一つが指定できます：

HOSTS    ホストキャッシュテーブルを空にします。あなたのホストの
IP アドレスを変えたり、Host ... is blocked というエラーメッセージが
出る場合はホストテーブルキャッシュを一度空にしなくてはなりません。
（指定したホストに対して max_connect_errors 以上の接続エラーが出る場合、
MySQL は何か起きたと
推定し、そのホストからのいかなる接続要求も拒否します。ホストテーブルキャッシュの消去は、
再び接続を許すようにします。See Blocked host.）
mysqld を
-O max_connection_errors=999999999 開始し、このエラーメッセージを
回避できます

LOGS     標準のログファイルと更新ログファイルを
一度閉じて再び開きます。
もし更新ログファイルを拡張子無しで指定している場合、新しい更新ログファイルの
拡張子の番号は、一つ前のファイルより 1 増やした数になります。
ファイル名に拡張を使用した場合、MySQL は更新ログファイルを閉じて開きます。
See Update log.

PRIVILEGES   mysql データベースの許可テーブルから、
権限情報を再読込します。

TABLES   全ての開いているテーブルを閉じます。

TABLES WITH READ LOCK   Closes all open tables and locks all tables for read until one executes UNLOCK TABLES.

STATUS   ほとんどのステータス変数を 0 にします。

上に示したコマンドは、mysqladmin を使用しても実行できます。 mysqladmin の引数はそれぞれ、 flush-hosts, flush-logs, reload, flush-tables となります。

FLUSH コマンドを実行するには、reload 権限がなければなりません。

KILL 構文
=======

     KILL thread_id

thread_id には、mysqld に接続して走っているスレッドの ID を空白で区切って指定します。 SHOW PROCESSLIST コマンドで走っているスレッドを知ることができ、 KILL thread_id コマンドでスレッドを KILL できます。

もし process 権限があるなら、全てのスレッドを確認し、KILL 出来ます。そうでなければ、自分のスレッドだけを、確認し、KILL する事ができます。

mysqladmin processlist と mysqladmin kill をスレッドの検査と KILL に使用できます。

SHOW 構文 (テーブルやフィールドなどについての情報を得る)
================================

        SHOW DATABASES [LIKE wild]
     or SHOW TABLES [FROM db_name] [LIKE wild]
     or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
     or SHOW INDEX FROM tbl_name [FROM db_name]
     or SHOW STATUS [LIKE wild]
     or SHOW VARIABLES [LIKE wild]
     or SHOW [FULL] PROCESSLIST
     or SHOW TABLE STATUS [FROM db_name] [LIKE wild]
     or SHOW GRANTS FOR user

SHOW はデータベース、テーブル、フィールド、サーバーについての情報を与えます。 LIKE wild が使用された場合、wild 文字列は通常の SQL ワイルドカード (% と _) です。

tbl_name FROM db_name の代わりに、db_name.tbl_name が使用できます。これら二つは同じです：

     mysql> SHOW INDEX FROM mytable FROM mydb;
     mysql> SHOW INDEX FROM mydb.mytable;

SHOW DATABASES は MySQL サーバー上のデータベースを示します。 mysqlshow コマンドでも同じ情報が得られます。

SHOW TABLES は指定されたデータベースのテーブルを一覧表示します。 mysqlshow db_name コマンドでも同じ情報が得られます。

NOTE: もしユーザーにテーブルに対する権限が無い場合、テーブルは SHOW TABLES や mysqlshow db_name の要求で表示されません。

SHOW COLUMNS は与えられたテーブルのフィールドを表示します。もしそのフィールドの型が、あなたが CREATE TABLE 構文実行時に与えたものと違う場合は、 MySQL は、フィールドの型をときおり変更することがあることに注意してください。 See Silent column changes.

DESCRIBE 文は SHOW COLUMNS と似たような情報を提供します。 See DESCRIBE.

SHOW TABLE STATUS (バージョン 3.23 の新機能) は SHOW STATUS のようですが、それぞれのテーブルについてより多くの情報を提供します。 mysqlshow --status db_name コマンドを実行しても同じものが得られます。以下の項目が返ってきます：

項目   意味
Name   テーブル名
Type   テーブルの種類 (BDB, ISAM, MyISAM or HEAP)
Row_format   レコードの保存形式 (Fixed, Dynamic, or Compressed)
Rows   レコード数
Avg_row_length   レコードの平均長
Data_length   データファイルの大きさ
Max_data_length   データファイルの最大値
Index_length   インデックスファイルの大きさ
Data_free   割り当てられたが使用されていないバイト数
Auto_increment   次の autoincrement 値
Create_time   テーブル作成時刻
Update_time   一番最後に更新された時刻
Check_time   一番最後にチェックされた時刻
Create_options   CREATE TABLE で使用された拡張オプション
Comment   テーブル作成時につけられたコメント (あるいは、なぜこのテーブルにMySQL がアクセスできないかのいくつかの情報).

SHOW FIELDS は SHOW COLUMNS の別名として使用され、 SHOW KEYS は SHOW INDEX の別名として使用されます。テーブルのフィールドやインデックスは mysqlshow db_name tbl_name か mysqlshow -k db_name tbl_name でも見れます。

SHOW INDEX は ODBC でいう SQLStatistics に近い形式で、インデックスの情報を表示します。以下の項目が返ります：

項目   意味
Table   テーブル名
Non_unique   インデックスが重複を含まないなら 0
Key_name   インデックス名
Seq_in_index   インデックスの項目番号。1 から始まります。
Column_name   フィールド名。
Collation   いかにこのフィールドがインデックス中でソートされるか.  MySQL では, これは A (Ascending) か NULL (Not sorted) になります。
Cardinality   インデックス中のユニークな値の数。 これは isamchk -a の実行で更新されます。
Sub_part   もしこのフィールドがインデックスに一部分だけ使用している場合、そのインデックスに使用しているキャラクター数をしめす。 もしキー全体がインデックスされているなら NULL 。

SHOW STATUS は mysqladmin extended-status と同様に、サーバからのステータス情報を与えます。出力は次とは異なるかもしれません:

     +--------------------------+--------+
     | Variable_name            | Value  |
     +--------------------------+--------+
     | Aborted_clients          | 0      |
     | Aborted_connects         | 0      |
     | Connections              | 17     |
     | Created_tmp_tables       | 0      |
     | Delayed_insert_threads   | 0      |
     | Delayed_writes           | 0      |
     | Delayed_errors           | 0      |
     | Flush_commands           | 2      |
     | Handler_delete           | 2      |
     | Handler_read_first       | 0      |
     | Handler_read_key         | 1      |
     | Handler_read_next        | 0      |
     | Handler_read_rnd         | 35     |
     | Handler_update           | 0      |
     | Handler_write            | 2      |
     | Key_blocks_used          | 0      |
     | Key_read_requests        | 0      |
     | Key_reads                | 0      |
     | Key_write_requests       | 0      |
     | Key_writes               | 0      |
     | Max_used_connections     | 1      |
     | Not_flushed_key_blocks   | 0      |
     | Not_flushed_delayed_rows | 0      |
     | Open_tables              | 1      |
     | Open_files               | 2      |
     | Open_streams             | 0      |
     | Opened_tables            | 11     |
     | Questions                | 14     |
     | Slow_launch_threads      | 0      |
     | Slow_queries             | 0      |
     | Threads_connected        | 1      |
     | Threads_running          | 1      |
     | Uptime                   | 149111 |
     +--------------------------+--------+

上に示したステータス変数は以下に示すの意味を持ちます：

Aborted_clients   クライアントが接続を閉じる前に死んでしまったために中断されたコネクション数。
Aborted_connects   MySQL サーバーに接続を試みて失敗した数
Bytes_received   クライアントから受信したバイト数
Bytes_sent   クライアントに送信したバイト数
Connections   MySQL サーバーに接続を試みた数
Created_tmp_tables   ステートメント実行中に暗黙のうちに作成された一時テーブルの数
Delayed_insert_threads   使用中の delayed insert ハンドラースレッドの数
Delayed_writes   INSERT DELAYED で書かれたレコード数
Delayed_errors   INSERT DELAYED で書かれたレコードでなんらかのエラーのあったレコード数 (たぶん duplicate key).
Flush_commands   FLUSH コマンドの実行回数
Handler_delete   テーブルからレコードを削除するためのリクエスト数
Handler_read_first   テーブル中の最初のレコードを読むためのリクエスト数。
Handler_read_key   キーに基づいてレコードを読むためのリクエスト数。
Handler_read_next   キー順で次のレコードを読むためのリクエスト数。
Handler_read_rnd   固定位置に基づいてレコードを読むためのリクエスト数。
Handler_read_rnd_next   データファイルの次のレコードを読む要求の数。
多くのテーブルスキャンを行なう場合、これは高くなります - 通常、これはテー
ブルが正しくインデックスされていないか、存在するインデックスを有利に使うよ
うにクエリが書かれていないことを示唆します。
Handler_update   テーブルのレコードを更新するための要求数
Handler_write   テーブルにレコードを挿入するためのリクエスト数
Key_blocks_used   キーキャッシュ中で使用されたブロック数
Key_read_requests   キャッシュからキーブロックを読み込んだリクエスト数
Key_reads   Disk から物理的にキーブロックを読んだ回数
Key_write_requests   キャッシュにキーブロックを書き込んだリクエスト数
Key_writes   Diskに物理的にキーブロックを書き込んだ回数
Max_used_connections   最大同時接続数
Not_flushed_key_blocks   キーキャッシュ中にあるキーブロックで、変更されたもののいまだDiskに書き出されていないキーブロック数
Not_flushed_delayed_rows   INSERT DELAY クエリで書き出しを待っているレコード数
Open_tables   オープンされているテーブル数
Open_files    オープンされているファイル数
Open_streams   開いているストリーム数 (主にログに使用される)
Opened_tables   オープンされたテーブル数
Questions   サーバーに送られたクエリの数
Slow_launch_threads   接続に slow_launch_time 以上を要したスレッド数
Slow_queries   long_query_time 以上に時間のかかったクエリの数
Threads_cached   スレッドキャッシュ内のスレッド数
Threads_connected   現在開いている接続数
Threads_running   スリープしていないスレッドの数
Uptime   サーバーが走っている秒数

上についてのいくつかコメント：

  * もし Opened_tables が大きければ、 table_cache 変数が小さすぎるのでしょう。

  * もし key_reads が大きければ、 key_cache が少なすぎるでしょう。キャッシュヒットレートは key_reads/key_read_requests で計算できます。

  * もし Handler_read_rnd が大きければ、 MySQL にテーブルをスキャンさせるような多くのクエリや、 キーを使用しない JOIN がもてます。

SHOW VARIABLES は MySQL システム変数のいくつかの値を示します。 mysqlshow variables コマンドでも同じ情報が得られます。もし標準値が適さないなら、ほとんどの変数を mysqld 起動時にコマンドラインのオプションとして与えることにより、変更できます。出力は以下のようになりますが、フォーマットや数はいくぶん違うでしょう：

     +------------------------+--------------------------+
     | Variable_name          | Value                    |
     +------------------------+--------------------------+
     | back_log               | 5                        |
     | connect_timeout        | 5                        |
     | basedir                | /my/monty/               |
     | datadir                | /my/monty/data/          |
     | delayed_insert_limit   | 100                      |
     | delayed_insert_timeout | 300                      |
     | delayed_queue_size     | 1000                     |
     | join_buffer_size       | 131072                   |
     | flush_time             | 0                        |
     | interactive_timeout    | 28800                    |
     | key_buffer_size        | 1048540                  |
     | language               | /my/monty/share/english/ |
     | log                    | OFF                      |
     | log_update             | OFF                      |
     | long_query_time        | 10                       |
     | low_priority_updates   | OFF                      |
     | max_allowed_packet     | 1048576                  |
     | max_connections        | 100                      |
     | max_connect_errors     | 10                       |
     | max_heap_table_size    | 16777216                 |
     | max_delayed_threads    | 20                       |
     | max_join_size          | 4294967295               |
     | max_sort_length        | 1024                     |
     | max_tmp_tables         | 32                       |
     | net_buffer_length      | 16384                    |
     | port                   | 3306                     |
     | protocol-version       | 10                       |
     | record_buffer          | 131072                   |
     | skip_locking           | ON                       |
     | slow_launch_time       | 2                        |
     | socket                 | /tmp/mysql.sock          |
     | sort_buffer            | 2097116                  |
     | table_cache            | 64                       |
     | thread_stack           | 131072                   |
     | tmp_table_size         | 1048576                  |
     | tmpdir                 | /machine/tmp/            |
     | version                | 3.23.0-alpha-debug       |
     | wait_timeout           | 28800                    |
     +------------------------+--------------------------+

See Server parameters.

SHOW PROCESSLIST はどのスレッドが走っているかを表示します。 mysqlshow processlist コマンドでも同じ情報が得られます。もし process 権限があるなら、全てのスレッドがみれます。しかし権限がないなら、自分のスレッドしか見れません。 See KILL. FULL オプションを使用しない場合、各クエリの最初の100文字だけが表示されます。

SHOW GRANTS FOR user はユーザの許可を複製するために発行する必要がある grant コマンドをリストします。

     mysql> SHOW GRANTS FOR root@localhost;
     +---------------------------------------------------------------------+
     | Grants for root@localhost                                           |
     +---------------------------------------------------------------------+
     | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
     +---------------------------------------------------------------------+

EXPLAIN 構文 (SELECTについての情報を得る)
=============================

         EXPLAIN tbl_name
     or  EXPLAIN SELECT select_options

EXPLAIN tbl_name は、 DESCRIBE tbl_name や SHOW COLUMNS FROM tbl_name と同義です。

もし EXPLAIN をともなって SELECT 構文を実行した場合、 MySQL はこの SELECT がいかに動作するかを説明し、いかにテーブルが結合されるかの情報を与えます。

EXPLAIN の情報を元に、インデックスを使用した速い SELECT を得るためにテーブルにインデックスを加えなくてはならないという事がわかります。テーブル結合の最適化もオプションによって見ることができます。 SELECT 構文での結合を強制的に最適化するには STRAIGHT_JOIN 節を加えます。

単純ではない join のために、EXPLAIN は SELECT 文で使用されているそれぞれのテーブルの情報を返します。テーブルは読まれる順に表示されます。MySQL は one-sweep multi-join method を用いた全ての join を解決します。これは MySQL は最初のテーブルから一レコード読み込み、二つ目のテーブルからマッチしたレコードを探し、そして三番目を探すということです。全てのテーブルが処理される時、選択されたフィールドを出力し、テーブルの一覧はよりマッチするレコードをもつテーブルを見つけるまで back-track されます。次のレコードはこのテーブルから読まれ、次のテーブルから処理を続けます。

EXPLAIN の出力は以下のフィールドを含みます：

table
     出力レコードが参照されるテーブル

type
     　join タイプ.  様々なタイプの説明は後述します

possible_keys
     possible_keys 項目は、MySQL がテーブルからレコードを見つけるためにどのインデックスを使用する事ができたかを示します。注意: このフィールドはテーブルの順にまったく依存しません。これは、 possible_keys 内のいくつかのキーは、生成されたテーブル順での実行に使用できないことを意味します。

     この項目が空なら、関連したインデックスは無いということです。この場合、あなたは WHERE 節を調べることによって、クエリの性能を向上させることができるかもしれません。もしそれがインデックスに適合したフィールドを参照しているならば。仮にそうだとすると、適切なインデックスを作成し、 EXPLAIN でクエリをもう一度チェックしてみてください。

     テーブルがどんなインデックスを持っているかみるには、SHOW INDEX FROM tbl_name とします。

key
     key 項目は、 MySQL が使用すると実際に決めたキーを示します。どのインデックスも選ばれなかったならば、キーは NULL です。 MySQL が間違ったインデックスを選択する場合、たいていは MySQL に他のインデックスを使用するように強制することができます。 myisamchk --analyze の使用、see myisamchk syntax、または USE INDEX/IGNORE INDEX の使用によって。See JOIN。

key_len
     key_len 項目は、MySQL が使用すると決めたキーの長さを示します。もし key が NULL なら、長さは NULL です。注意: これはMySQL がマルチパートキーのいくつのパートを実際に使用するかを示します。

ref
     ref 項目は、テーブルからレコードを select するために、どのフィールドや定数が key と共に使用されたかを示します。

rows
     rows フィールドは、MySQL がクエリを実行するために検査する必要があると考えているレコードの数を示します。

Extra
     This column contains additional information of how MySQL will resolve the query. Here follows an explanation of the different text strings that can be found in this column:

     Not exists
          MySQL was able to do a LEFT JOIN optimisation on the query and will not examine more rows in this table for a row combination after it founds one rows that matches the LEFT JOIN criteria.

     range checked for each record (index map: #)
          MySQL didn't find a real good index to use. It will instead for each row combination in the preceding tables do a check which index to use (if any) use this index to retrieve the rows from the table.  This isn't very fast but is of course faster than having to do a join without an index.

     Using filesort
          MySQL will need to do an extra pass to find out how to retrieve the rows in sorted order.  The sort is done by going through all rows according to the join type and storing the sort key + pointer to the row for all rows that match the WHERE. Then the keys are sorted. Finally the rows are retrieved in sorted order.

     Using index
          The column information is retrieved from the table using only information in the index tree without having to do an additional seek to read the actually row.  This can be done when all the used columns for the table are part of the same index.

     Using temporary
          To be able to resolve the query MySQL will need to create a temporary table to hold the result.  This typically happens if you do an ORDER BY on a different column set than you did an GROUP BY on.

     where used
          A WHERE clause will be used to restrict which rows will be matched against the next table or sent to the client.  If you don't have this information and the the table is of type ALL or index you may have something wrong in your query (if you don't intend to fetch/examine all rows from the table).

     If you want to get your queries as fast as possible, you should look out for Using filesort and Using temporary.

join type は以下のものがあります。良い物から順に書いています：

system
     テーブルが一レコードだけ持っている (= system table). これは const join type の特別な場合です。

const
     テーブルは、最もマッチするレコードを１つもっており、これはクエリの最初に読まれます。 1 つのレコードであるため、このレコード中のフィールドの値はオプティマイザーによって常数としてみなされます。 1回だけ読まれるので、const テーブルはとても速いです!

eq_ref
     前のテーブルのそれぞれのレコードと結合する際、このテーブルから1レコード読まれます。これは join では const よりも良い形です。インデックスの全てのパートが join で使用され、かつ、インデックスが UNIQUE か PRIMARY KEY であるときに、これは使用されます。

ref
     インデックスの値に合ったすべてのレコードは、前のテーブルからレコードと結合するために、このテーブルから読まれるでしょう。もしその join がキーの一番左の接頭部分だけを使用するならば、あるいは、もしそのキーが UNIQUE や PRIMARY KEY でなければ (言い換えるなら、もし join がキーの値を元に一つだけの、レコードを選択できなければ)、 ref は使用されます。もしそのキーがいくつかのマッチするレコードに使用されるだけなら、 join は良い形です。

range
     示された範囲内にあるレコードのみが検索されます。 ref 項目はどのインデックスが使用されているか示します。

index
     ALL と同じですが、インデックスツリーが走査される場合のみを除きます。これは、インデックスファイルはデータファイルよりも小さいため、通常 ALL より速いです。

ALL
     前のテーブルのレコードとのそれぞれの結合において、全テーブルが走査されます。もしそのテーブルが最初のテーブルで const 状態ではないなら、通常これは良くありません。他の状態ではとても悪くなります。これは普通、レコードががより早いテーブルからから定数値に基づいて検索することができるように、インデックスを追加することにより ALL を避けることが可能です。

EXPLAIN 出力の rows フィールド内のすべての値を増やすことにより、join がどのように良くなるかの良い表示を得ることができます。これは、 MySQL がクエリ実行の検査をする必要があるレコードのおおよその数を知らせます。この数は max_join_size 変数でのクエリを制限する時にも使用します。 See Server parameters.

以下の例は、EXPLAIN が提供する情報を元に、いかに JOIN が最適化できるかの例です。

以下のような EXPLAIN で検査する SELECT 構文があるとします：

     EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
                 tt.ProjectReference, tt.EstimatedShipDate,
                 tt.ActualShipDate, tt.ClientID,
                 tt.ServiceCodes, tt.RepetitiveID,
                 tt.CurrentProcess, tt.CurrentDPPerson,
                 tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
                 et_1.COUNTRY, do.CUSTNAME
             FROM tt, et, et AS et_1, do
             WHERE tt.SubmitTime IS NULL
                 AND tt.ActualPC = et.EMPLOYID
                 AND tt.AssignedPC = et_1.EMPLOYID
                 AND tt.ClientID = do.CUSTNMBR;

この例では、以下のように仮定します：

  * フィールドは以下のように定義されています：

     Table   Column   Column type
     tt        ActualPC        CHAR(10)
     tt        AssignedPC      CHAR(10)
     tt        ClientID        CHAR(10)
     et        EMPLOYID        CHAR(15)
     do        CUSTNMBR        CHAR(15)

  * テーブルは以下のインデックスを持ちます：

     Table   Index
     tt        ActualPC
     tt        AssignedPC
     tt        ClientID
     et        EMPLOYID (primary key)
     do        CUSTNMBR (primary key)

  * tt.ActualPC の値は、いちように分布して(配置されて)いません。

最初、いかなる最適化も行われていない状態では、EXPLAIN 構文は以下の情報を提示します：

     table type possible_keys                key  key_len ref  rows  Extra
     et    ALL  PRIMARY                      NULL NULL    NULL 74
     do    ALL  PRIMARY                      NULL NULL    NULL 2135
     et_1  ALL  PRIMARY                      NULL NULL    NULL 74
     tt    ALL  AssignedPC,ClientID,ActualPC NULL NULL    NULL 3872
           range checked for each record (key map: 35)

それぞれのテーブルで、type が ALL になっています。これは MySQL が全てのテーブルを全結合することを示します！それぞれのテーブル内の行数分から作った物が調べられるので、とても長い時間がかかります！この場合、74 * 2135 * 74 * 3872 = 45,268,558,720 行調べることになります。テーブルが肥大化したときにかかる時間を考えてください....

一つ問題があります。(まだ) MySQL がフィールドのインデックスを効果的に使用できていません。この例の場合では、VARCHAR と CHAR は、それらが同じ長さで定義されていれば、変わりがありません。 tt.ActualPC は CHAR(10) と定義されており、 et.EMPLOYID は CHAR(15) です。これらの長さは違います。

この不釣り合いを修正するにあたり、ALTER TABLE を使って ActualPC の長さを 10 文字から 15 文字にします：

     mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

これで tt.ActualPC and et.EMPLOYID は両方とも VARCHAR(15) になりました。 EXPLAIN 構文を実行し直すと、以下を提示します：

     table type   possible_keys   key     key_len ref         rows    Extra
     tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL 3872    where used
     do    ALL    PRIMARY         NULL    NULL    NULL        2135
           range checked for each record (key map: 1)
     et_1  ALL    PRIMARY         NULL    NULL    NULL        74
           range checked for each record (key map: 1)
     et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC 1

まだ完全ではありませんが、よりよくなっています(rows 値の生成量は 74 より小さくなります)。この場合、実行は数秒でしょう。

tt.AssignedPC = et_1.EMPLOYID と tt.ClientID = do.CUSTNMBR の比較において、フィールドの長さの違いを排除することができます:

     mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
                           MODIFY ClientID   VARCHAR(15);

これで EXPLAIN は以下を出力します：

     table type   possible_keys   key     key_len ref            rows     Extra
     et    ALL    PRIMARY         NULL    NULL    NULL           74
     tt    ref    AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
     et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
     do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

これは ``ほとんど'' 最良に近いです。

残る問題は、デフォルトでは、MySQL は tt.ActualPC フィールド内の値がまんべんなく分布していると想定しており、この tt テーブルの場合には適合しません。幸運にも、これを MySQL に教えるのはとても簡単です：

     shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt
     shell> mysqladmin refresh

これで join は ``完璧'' です。 EXPLAIN は以下の結果を示します：

     table type   possible_keys   key     key_len ref            rows    Extra
     tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL    3872    where used
     et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC    1
     et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
     do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

EXPLAIN の出力中の rows 項目は、 MySQL JOIN オプティマイザーによる、``推測'' です；クエリの最適化のために、この数値が実際に近いかどうかをチェックすべきです。そうでなければ、SELECT ステートメントで STRAIGHT_JOIN を使用し、FROM 節に異なる順でテーブルを並べることで、良いパフォーマンスを得られます。

DESCRIBE 構文 (フィールドについての情報を得る)
=============================

     {DESCRIBE | DESC} tbl_name {col_name | wild}

DESCRIBE はフィールドについての情報を与えます。 col_name はフィールドはフィールド名または文字列です。文字列は SQL %,_ ワイルドカードを含めます。

もしフィールドの型があなたが CREATE TABLE 文で与えた物と違っているなら、これは MySQL がフィールドの型を変更していることに注意してください。 See Silent column changes.

このコマンドは Oracle の互換のためにあります。

SHOW 構文は似たような情報を提供します。 See SHOW.

BEGIN/COMMIT/ROLLBACK 構文
========================

デフォルトでは MySQL は autocommit モードで動作します。これは、更新を実行するとすぐに MySQL が更新をディスクに格納することを意味します。

もし BDB 型のテーブルを使用するなら, 以下のコマンドで MySQL を autocommit モードではない状態にすることができます：

     SET AUTOCOMMIT=0

この後、ディスクに変更を格納するためには COMMIT を使用し、また、変更を無視するためには ROLLBACK する必要があります。

If you want to switch from AUTOCOMMIT mode for one serie of statements, you can use the BEGIN statement.

     BEGIN;
     SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
     UPDATE table2 SET summmary=@A WHERE type=1;
     COMMIT;

注意: トランザクション安全テーブルを使用していない場合は、autocommit モードのステータスには依存せずに、変更はすぐに格納されます。See Table types.

LOCK TABLES/UNLOCK TABLES 構文
============================

     LOCK TABLES tbl_name [AS alias] {READ | [READ LOCAL] | [LOW_PRIORITY] WRITE}
                  [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
     ...
     UNLOCK TABLES

LOCK TABLES はカレントのスレッドのためにテーブルをロックします。 UNLOCK TABLES はこのスレッドの全てのロックを解除します。カレントスレッドによってロックされた全てのテーブルは、スレッドが他の LOCK TABLES を発行した場合やサーバーが接続を閉じた場合、自動で解除されます。

スレッドがテーブルに READ ロックを持つ場合、そのスレッド(と他の全てのスレッド)はテーブルからの読み込みだけができます。スレッドがテーブルに WRITE ロックを持つ場合、このスレッドだけがテーブルの READ と WRITE ができます。他のスレッドはブロックされます。

READ LOCAL と READ の違いは、READ LOCAL は、ロックが保持されている間にコンフリクトしない INSERT ステートメントを実行できることです。ただし、これはロックを保持している間に MySQL の外でデータベースファイルを操作しようとする場合は使用できません。

それぞれのスレッドはそれらが全てのロックを得るまで待ちます(タイムアウト無し)。

WRITE ロックは普通、できる限り更新を行わせるため、 READ ロックよりも優先順位が高くなっています。これはあるスレッドが READ ロックをかけ、それ以外のスレッドが WRITE を要求した場合、 READ は、WRITE スレッドがロックをし、それを解除するまで待つということです。 LOW_PRIORITY WRITE を使用すれば、 WRITE ロックを待っているスレッドに READ ロックを得させることができます。 LOW_PRIORITY WRITE は READ ロックをしているスレッドが一つもないとわかっている場合に使用すべきです。

LOCK TABLES を使用するとき、使用しようとする全てのテーブルをロックすべきです！そしてクエリで使用しようとしているのと同じエイリアスを使わなければなりません！もしクエリで並列に複数回テーブルを使用するなら(alias をともなって)、それぞれの alias をロックすべきです！このポリシーはテーブルロックをデッドロックフリーにすることを確かにします。

INSERT DELAYED で使用しているいかなるテーブルも、ロックすべきではありません。この場合 INSERT は別のスレッドで行なわれるからです。

通常、全ての単一の UPDATE 構文においては、テーブルをロックする必要はありません；スレッドは、他のスレッドが現在実行している SQL 文に干渉することができません。これらはテーブルをロックした方がよい、まれな場合です：

  * テーブルをまとめて多くの操作を実行しようとする場合、使用しようとしているテーブルをロックするととても速くなります。もちろん、他のスレッドは READ ロックされたテーブルの更新はできませんし、他のスレッドは WRITE ロックされたテーブルを読むことはできません。

  * MySQL はトランザクション環境をサポートしないため、他のスレッドが SELECT,UPDATEの間に来ないことを保証したい場合は、 LOCK TABLES を使用する必要があります。次の例は安全のためには LOCK TABLES を必要とします：

          mysql> LOCK TABLES trans READ, customer WRITE;
          mysql> select sum(value) from trans where customer_id= some_id;
          mysql> update customer set total_value=sum_from_previous_statement
                     where customer_id=some_id;
          mysql> UNLOCK TABLES;

     LOCK TABLES を使用しない場合、SELECT の実行と UPDATE の実行を行う間に、他のスレッドが新しい trans 行を挿入する隙ができます。

増加更新 (UPDATE customer SET value=value+new_value) または LAST_INSERT_ID() 関数の使用により、多くの場合 LOCK TABLES を回避できます。

いくつかの場合、ユーザレベルロック: GET_LOCK() と RELEASE_LOCK() の使用によっても解決できます。これらのロックはサーバ内のハッシュテーブル内に保持され、高速のため pthread_mutex_lock() で実装されました。 See Miscellaneous functions.

ロックポリシーのさらなる情報については Internal locking を見てください。

SET OPTION 構文
=============

     SET [OPTION] SQL_VALUE_OPTION= value, ...

SET OPTION はサーバやクライアントの操作に影響する様々なオプションを設定します. 現在のセッションが終わるか,またはあなたが異なった値にオプションを設定するまで, 設定されたオプション値は残っています.

CHARACTER SET character_set_name | DEFAULT
     これは指定されたマッピングに従って、すべての文字列をクライアントからクライアントにマップします. 現在、character_set_name に指定できるオプションは cp1251_koi8 だけですが, MySQL のソース中にある sql/convert.cc ファイルを編集することによって, 容易に新しいマッピングを加えることができます. 標準のマッピングに戻すには、 character_set_name に DEFAULT を指定します。

     CHARACTER SET オプションを設定するための構文は、他のオプションを設定する構文と異なっていることに注意してください.

PASSWORD = PASSWORD('some password')
     現在のユーザのパスワードを設定します。いかなる非匿名のユーザも、自分自身パスワードを変えることができます!

PASSWORD FOR user = PASSWORD('some password')
     現在ログインしているホストの特定ユーザのパスワードを設定します。 mysql データベースにアクセスができるユーザーだけが実行できます。ユーザは user@hostname 形式で与えなくてはなりません。ここで user と hostname は、mysql.user テーブルの User, Host フィールドに登録されていなくてはなりません。例えば、User と Host フィールドが 'bob' と '%.loc.gov' ならば、以下のようにします：

          mysql> SET PASSWORD FOR bob@"%.loc.gov" = PASSWORD("newpass");

          または

          mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' and host="%.loc.gov";

SQL_AUTO_IS_NULL = 0 | 1
     1 (デフォルト) を設定すると、次のようにして、auto_increment レコードを持つテーブルで、最後に挿入されたレコードを見つけることができます: WHERE auto_increment_column IS NULL。これは、Access のようないくつかの ODBC プログラムによって使用されます。

SET AUTOCOMMIT= 0 | 1
     1 を設定すると、テーブルへのすべての変更はすぐに行なわれます。 To start an multi command transaction you have to use the BEGIN statement. See COMMIT. 0 を設定すると、そのトランザクションを許可/破棄するために、 COMMIT / ROLLBACK を使用する必要があります。See COMMIT。注意: 非 AUTOCOMMIT モードから AUTOCOMMIT モードに変更する時、 MySQL はすべてのオープントランザクションを自動的に COMMIT します。

SQL_BIG_TABLES = 0 | 1
     0 の場合、全ての一時テーブルはメモリーではなくディスクに書き出されます。これは少し遅くなりますが、多くの一時テーブルを必要とする大きな SELECT を実行しても、The table tbl_name is full エラーが出なくなります。新しい接続におけるこの値のデフォルト値は 1 (メモリーに一時テーブルを作る) です。

SQL_BIG_SELECTS = 0 | 1
     1 の場合、とても時間のかかる SELECT が実行された場合、 MySQL はそれを中止します。これはあまり芳しくない(間違った) WHERE 構文が発行されたときに役立ちます。 max_join_size 行以上を検討するような SELECT が大きなクエリと定義されます。新しい接続におけるこの値のデフォルト値は 0 です。 (全ての SELECT 構文を許します)

SQL_BUFFER_RESULT = 0 | 1
     SQL_BUFFER_RESULT は一時ファイルに置かれる SELECT からの結果を強制的に置きます。これは MySQL がテーブルロックを早く解放する手助けをし、クライアントへ結果セットを送信するために長い時間が掛かる場合に役立ちます。

SQL_LOW_PRIORITY_UPDATES = 0 | 1
     1 の場合、全ての INSERT, UPDATE, DELETE, LOCK TABLE WRITE構文は、対象となるテーブルを処理中の SELECT や LOCK TABLE READ がなくなるまで待ちます。

SQL_MAX_JOIN_SIZE = value | DEFAULT
     おそらく value よりも多いレコードの組合せを試験する必要があるような SELECT を許可しません。この値を設定することで、キーが使用されないであろう SELECT と長い時間が掛かるであろう SELECT を捕捉できます。これを DEFAULT 以外の値に設定すると、SQL_BIG_SELECTS フラグをリセットします。SQL_BIG_SELECTS フラグを再び設定すると、 SQL_MAX_JOIN_SIZE 変数は無視されます。-O max_join_size=# で mysqld を起動することで、この変数のデフォルト値を設定できます。

SQL_SAFE_MODE = 0 | 1
     1 に設定すると、WHERE 節内でキーや LIMIT を使用しないで UPDATE または DELETE を行なおうとした場合に MySQL がアボートします。これは、手で SQL コマンドを生成する時の間違った更新の捕捉を可能にします。

SQL_SELECT_LIMIT = value | DEFAULT
     SELECT 構文から返されるレコードの最大値。もし SELECT に LIMIT 節を使用している場合、LIMIT は SQL_SELECT_LIMIT の値より優先されます。新しい接続におけるこの値の標準値は ``unlimited''. もしリミットを変えているならば、SQL_SELECT_LIMIT に DEFAULT を指定することにより、標準値に戻すことができます。

SQL_LOG_OFF = 0 | 1
     この値が 1 の場合、もしクライアントが process 権限を持っているならば、このクライアントのログが行われません。これは更新ログに影響しません！

SQL_LOG_UPDATE = 0 | 1
     0 の場合、もしクライアントが process 権限を持っているならば、このクライアントの更新ログの記録は行われません。これは通常のログには影響しません！

TIMESTAMP = timestamp_value | DEFAULT
     クライアントに時間を設定します。もしレコードのリストアに更新ログを使用する場合、オリジナルのタイムスタンプを得るために使用します。

LAST_INSERT_ID = #
     LAST_INSERT_ID() からの返り値を設定します。テーブルを更新するコマンド中に LAST_INSERT_ID() を使用した場合、これは更新ログに保存されます。

INSERT_ID = #
     AUTO_INCREMENT 値を挿入する時、 INSERT コマンドに従って使用される値をセットします。これは更新ログによって使用されます。

GRANT と REVOKE 構文
=================

     GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
         ON {tbl_name | * | *.* | db_name.*}
         TO user_name [IDENTIFIED BY 'password']
             [, user_name [IDENTIFIED BY 'password'] ...]
         [WITH GRANT OPTION]

     REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
         ON {tbl_name | * | *.* | db_name.*}
         FROM user_name [, user_name ...]

GRANT は MySQL 3.22.11 以上で実装されています; 前の MySQL バージョンでは、GRANT ステートメントは何も行ないません。

GRANT と REVOKE コマンドセットの主な目的は、システム管理者が MySQL ユーザに次の４つの権限レベルの権利を与えたり取り消すことをできるようにすることです:

Global レベル
     Global 権限は与えられたサーバ上の全てのデータベースに適用します。これらの権限は mysql.user テーブル内に格納されます。

Database レベル
     Database 権限は与えられたデータベース内の全てのテーブルに適用します。これらの権限は mysql.db テーブルと mysql.host テーブル内に格納されます。

Table レベル
     Table 権限は与えられたテーブル内の全てのフィールドに適用します。これらの権限は mysql.tables_priv テーブル内に格納されます。

Column レベル
     Column 権限は与えられたテーブル内の一つのフィールドに適用します。これらの権限は mysql.column_priv テーブル内に格納されます。

GRANT の動作例は → Adding users.

GRANT と REVOKE ステートメントにおいて priv_type には以下が指定できます:

     ALL PRIVILEGES      FILE                RELOAD
     ALTER               INDEX               SELECT
     CREATE              INSERT              SHUTDOWN
     DELETE              PROCESS             UPDATE
     DROP                REFERENCES          USAGE

ALL は ALL PRIVILEGES の同義語です. REFERENCES はまだ実行されません。 USAGE は ``no privileges'' と同義です. これはなんの権限も持たないユーザーを作る場合に使用します.

ユーザーから権限許可を取り除くには、GRANT OPTION オプションの値に priv_type を指定します：

     REVOKE GRANT OPTION ON ... FROM ...;

テーブルに対する許可のために指定できる priv_type は次のフィールドだけです： SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, INDEX, ALTER.

フィールドに対する許可のために指定できる priv_type は次のフィールドだけです (これは column_list 節を使用する場合に適用されます)： SELECT, INSERT, UPDATE.

WITH GRANT OPTION 節は、GRANT 構文を使用して他のユーザーに権限を与えることができるようにします。

ON *.* を使用してグローバル権限を設定できます。 ON db_name.* を使用してデータベース権限を設定できます。ON * を指定すると、現在のデータベースの権限を設定できます。 (警告： 現在のデータベースを持たない状態で ON * を指定した場合、 global 権限に影響します！)

ユーザへの権利の供与を他のホストから適応するために、MySQL は user_name の値を user@host の形で書けるようにしています。特殊文字(% のような)で user_name の値を指定したい場合、ユーザやホスト名をクォートできます; (例えば 'test-user'@'test-hostname')。

ホスト名にワイルドカードを使用できます。例えば、user@"%.loc.gov" は loc.gov ドメインの全てのホストの user を与え、 user@"144.155.166.%" は 144.155.166 クラスCサブネットのあらゆるホストの user となります。

単に user と書くと user@"%" と同じです. 注意： もし匿名ユーザーからの MySQL サーバーへの接続を許す場合(デフォルトです)、全てのローカルユーザー username@localhost を加えるべきです。なぜなら、匿名ユーザーは同じマシンから MySQL サーバーに入ろうとした場合に使用されるからです！匿名ユーザーは mysql.user ユーザーテーブルに、 User='' として登録されています。これを確認するには、以下のようにします：

     mysql> SELECT Host,User FROM mysql.user WHERE User='';

さしあたり, GRANT はホスト名、テーブル名、データベース名、フィールド名に最大60文字まで使用できます。ユーザー名は最大16文字までです。

テーブル/フィールドの権限は global(ユーザとデータベース)権限と GRANT 権限と OR されます。例えば、ユーザが mysql.user テーブル内の global select 権限を持っている場合、これはデータベースやテーブル/フィールドレベル内のエントリでは拒否できません。

フィールドの権利は次のように計算できます:

     global privileges
     OR (database privileges AND host privileges)
     OR table privileges
     OR column privileges

多くの場合、異なる権限レベルの一つでユーザに権利を与えるので、人生は通常上述のようには複雑ではありません。:) アクセス制限のチェックの詳細は→Privilege system.

ユーザへの権利の供与を他のホストから適応するために、MySQL はユーザ名が形式 user@host で指定できることをサポートします。簡単な形式 user は user@% の同義語です。特殊文字(. のような)でホスト名を指定したい場合、"user"@"hostname" 構文を使用できます。

ユーザとホスト名の組が存在しない場合、エントリは mysql.user テーブルに追加され、DELETE コマンドで削除されるまでそこに残ります。いうならば GRANT は user テーブルの登録を作りますが、 REVOKE はそれらを削除できません; そうするには DELETE を使用しなくてはなりません。

MySQL 3.22.12 以上では、新しいユーザーが作成された場合、あるいは、あなたがグローバルな権限を許可されている場合、ユーザーのパスワードは IDENTIFIED BY 節を使用して設定できます。すでにユーザーにパスワードがある場合、新しく設定されたパスワードに置き換えられます。

警告： もし新しいユーザーを作っても IDENTIFIED BY 節を指定しなければ、 そのユーザーはノーパスワードです。これは危険です。

パスワードは SET PASSWORD コマンドでも設定できます。 See SET OPTION.

データベースに権限を GRANT する場合、mysql.db テーブル内のエントリは必要な場合に生成されます。全てのデータベース権限が REVOKE で削除された時、このエントリは削除されます。

ユーザがテーブルに何も権限を持っていない場合、テーブルの一覧要求時(例えば、SHOW TABLES ステートメントで)には、テーブルは現れません。

WITH GRANT OPTION 節は、他のユーザーに、自分が持っている権限を与えることができます。権限許可を他に与える場合は注意してください。あなたと許可を与えるユーザーが違う権限を持っている場合、与えられる権限の許可は、二つを合わせた物になります！

自分自身が持っていない権限を他のユーザーに与えることはできません；権限許可はあなたが所有する権限の許可だけを与えることができます。

あなたがユーザーに格別の権限レベルを与えた場合、既にユーザーが持っているいかなる権限 (あるいは 将来持つ権限) はそのユーザーによっても許可が与えられます。あなたがデータベースに対する insert 許可をあるユーザーに与えたと仮定します。もし、データベースに対する select 権限を与えたり、 WITH GRANT OPTION を行うと、ユーザーは select 権限だけでなく insert も得ることになります。もし update 権限をユーザーに与えると、そのユーザーは insert, select, update が可能です。

alter 権限を一般ユーザに与えるべきではありません。この場合ユーザはテーブルをリネームでき、この方法で権限を回ることを試みることができます！

注意：もし table/column 権限を一人のユーザーにだけ与えた場合、 MySQL は全てのユーザーに対してテーブルとフィールドの承認権限を検討します。これは MySQL を少し遅くします。

mysqld 開始時、全ての権限はメモリに読み込まれます。データベース、テーブル、フィールド権限は一度効果を得ます。ユーザレベル権限はユーザ再接続時に効果を得ます。これらの許可テーブルを GRANT や REVOKE を使って変更してもサーバーにはすぐに反映されません。もしこれらの許可テーブルを手動で変更した場合(INSERT, UPDATE, 等で変更した場合)、 FLUSH PRIVILEGES 構文を実行するか、mysqladmin flush-privileges を実行してサーバーに許可テーブルの再読み込みを行わせなくてはなりません。 See Privilege changes.

ANSI SQL GRANT と MySQL GRANT との大きな違いは:

  * ANSI SQL はグローバルとデータベースレベル承認を持たず、ANSI SQL は MySQL がサポートする全ての権限をサポートしません。

  * ANSI SQL でテーブルを破棄する時、そのテーブルの全ての権限は破棄されます。ANSI SQL で権限を取り消す場合、この権限に基づいて承認された全ての権限も取り消されます。MySQL では、全ての権限は明示的な REVOKE コマンドまたは MySQL 権限テーブルの操作によってのみ破棄されます。

CREATE INDEX 構文
===============

     CREATE [UNIQUE] INDEX index_name ON tbl_name (col_name[(length)],... )

CREATE INDEX 構文は MySQL 3.22 より以前のバージョンではなにもしません。 3.22 以降で、CREATE INDEX はインデックスの作成のために ALTER TABLE を呼びだしています。 See ALTER TABLE.

通常、テーブル内の全てのインデックスは CREATE TABLE でテーブルを作るときに一度に作成されます。 See CREATE TABLE. CREATE INDEX は既に存在するテーブルに対し、インデックスを追加します。

フィールドを (col1,col2,...) として指定すると、複数フィールドインデックスを作成します。インデックスの値は、与えられたフィールドの値を連結して、構成されます。

CHAR と VARCHAR フィールドでは、インデックスはフィールドの一部分だけを使用して作成されます。これは col_name(length) 構文を使用します。 (BLOB と TEXT 節では length が必要です)。最初の10文字をインデックスとして使用するには、この構文は以下のようにして使用します(name フィールドにインデックスを作ります)：

     mysql> CREATE INDEX part_of_name ON customer (name(10));

フィールドの一部分だけをインデックスに使用すれば、インデックスファイルをはるかに小さくすることができます。ほとんどの名前が最初の10文字において通常異なるので、このインデックスは name フィールド全部を使用して創り出したインデックスに比べて遅くなることはありません。また、多くのディスクスペースを節約でき、 INSERT を速くするのです！

MySQL version 3.23.2 以上で MyISAM 型のテーブルを使用している場合、 NULL 値をもつフィールドや、 BLOB/TEXT フィールドに対してインデックスを張ることが可能です。

MySQL がどのようにしてインデックスを使用するかは → 　MySQL indexes.

DROP INDEX 構文
=============

     DROP INDEX index_name ON tbl_name

DROP INDEX は index_name という名前のインデックスをテーブル tbl_name から破棄します。 DROP INDEX は MySQL 3.22 より以前のバージョンではなにもしません。 3.22 以降で、DROP INDEX はインデックスの破棄のために ALTER TABLE を呼びだしています。 See ALTER TABLE.

コメント 構文
=======

MySQL は # 行末まで , -- 行末まで そして /* 行中または複数行 */ コメント書式をサポートします:

     mysql> select 1+1;     # このコメントは行末まで続く
     mysql> select 1+1;     -- このコメントは行末まで続く
     mysql> select 1 /* これは行中コメント */ + 1;
     mysql> select 1+
     /*
     これは
     複数行コメント
     */
     1;

-- コメントスタイルは -- の後ろに最低一つのスペースが必要であることに注意！

サーバーはコメント構文を理解しますが、 mysql クライアントが /* ... */ コメントを分析するにはいくつか制限があります：

  * シングルクウォートとダブルクオート文字は引用文字列のトークンの開始を示します。たとえコメントの中であっても。もしコメントの中でクオートが二つ目のクオートにマッチしなかった場合、パーサーはコメントが終了していないと認識します。 mysql を対話モードで実行している場合、プロンプトが mysql> から '> か "> に変わります。

  * セミコロンは SQL 構文の終了を示し、これに続く文字は次の構文の開始となります。

これらの制限は mysql を対話モードで実行している場合と、 mysql にファイルを読み込ませている場合 ( mysql < some-file ) の両方で現れます。

MySQL は ANSI SQL コメントの -- をサポートしません。 See Missing comments.

CREATE FUNCTION/DROP FUNCTION 構文
================================

     CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER}
            SONAME shared_library_name

     DROP FUNCTION function_name

ユーザー定義関数 (UDF : user-definable functions) は MySQL に新しい関数を持たせれる拡張方法です。これは MySQL のネイティブ(埋め込み)関数 (ABS(), CONCAT() のような)と同じように動作します。

AGGREGATE は MySQL 3.23 の新しいオプションです。 AGGREGATE 関数は、SUM や COUNT() のようなネイティブな MySQL GROUP 関数のように正確に動作します。

CREATE FUNCTION は、関数名、型、共有ライブラリ名を、 mysql.func システムテーブルに、保存します。関数の作成、破棄を行うには、 mysql データベースに対して、 insert , delete 権限がなければなりません。

全ての関数はサーバーの起動時に読み込まれます。ただし --skip-grant-tables オプションを mysqld につけていなければ。この場合、UDF の初期化は飛ばされ、UDF で作った関数は使用できません。 (関数は CREATE FUNCTION でロードされ、 DROP FUNCTION で削除されます)

ユーザー定義関数に関するさらなる情報は → Adding functions. UDF メカニズムで動かすためには、関数は C か C++ で書かれていなければなりません。かつ、あなたのオペレーティングシステムがダイナミックローディングをサポートしていなければなりません。さらに mysqld はスタティックではなくダイナミックでコンパイルされていなければなりません。

Is MySQL picky about reserved words?
====================================

共通の問題は、フィールドの名前を、 TIMESTAMP とか GROUP とかの MySQL に埋め込まれているデータ型や関数名と同名にして、テーブルを作った場合に起こります。このようなことは行えます(例えば ABS はフィールド名にできます)。しかし、関数として使用する場合、この名前がフィールド名として使用されているなら、関数名と ( の間の空白は許されません。

以下の語は MySQL に予約されています。これらのほとんどは、 ANSI SQL92 によって、テーブル、フィールド名としての使用は禁止されています。(例えば group)。またいくつかの語は MySQL が必要とし、 yacc パーサーで使用しているので予約されています。

action   add   aggregate   all
alter   after   and   as
asc   avg   avg_row_length   auto_increment
between   bigint   bit   binary
blob   bool   both   by
cascade   case   char   character
change   check   checksum   column
columns   comment   constraint   create
cross   current_date   current_time   current_timestamp
data   database   databases   date
datetime   day   day_hour   day_minute
day_second   dayofmonth   dayofweek   dayofyear
dec   decimal   default   delayed
delay_key_write   delete   desc   describe
distinct   distinctrow   double   drop
end   else   escape   escaped
enclosed   enum   explain   exists
fields   file   first   float
float4   float8   flush   foreign
from   for   full   function
global   grant   grants   group
having   heap   high_priority   hour
hour_minute   hour_second   hosts   identified
ignore   in   index   infile
inner   insert   insert_id   int
integer   interval   int1   int2
int3   int4   int8   into
if   is   isam   join
key   keys   kill   last_insert_id
leading   left   length   like
lines   limit   load   local
lock   logs   long   longblob
longtext   low_priority   max   max_rows
match   mediumblob   mediumtext   mediumint
middleint   min_rows   minute   minute_second
modify   month   monthname   myisam
natural   numeric   no   not
null   on   optimize   option
optionally   or   order   outer
outfile   pack_keys   partial   password
precision   primary   procedure   process
processlist   privileges   read   real
references   reload   regexp   rename
replace   restrict   returns   revoke
rlike   row   rows   second
select   set   show   shutdown
smallint   soname   sql_big_tables   sql_big_selects
sql_low_priority_updates   sql_log_off   sql_log_update   sql_select_limit
sql_small_result   sql_big_result   sql_warnings   straight_join
starting   status   string   table
tables   temporary   terminated   text
then   time   timestamp   tinyblob
tinytext   tinyint   trailing   to
type   use   using   unique
unlock   unsigned   update   usage
values   varchar   variables   varying
varbinary   with   write   when
where   year   year_month   zerofill

以下は ANSI SQL ではフィールド、テーブル名としての使用を禁止されていますが、 MySQL では許可されています。これは、これらの名前は凄く自然な名前で、多くの人がこれらを既に名前として使用しているからです。

  * ACTION

  * BIT

  * DATE

  * ENUM

  * NO

  * TEXT

  * TIME

  * TIMESTAMP

MySQL table types
*****************

With MySQL you can currently (version 3.23.6) choose between three basic table formats. When you create a new table, you can tell MySQL which table type it should use for the table.  MySQL will always create a .frm file to hold the table and column definitions.  Depending on the table type the index and data will be stored in other files.

The default table type in MySQL is MyISAM. If you are trying to use a table type that is not incompiled or activated, MySQL will instead create a table of type MyISAM.

ALTER TABLE 文を使用すれば、テーブルを違う形式に変更できます。 See ALTER TABLE.

Note that MySQL supports two different kind of tables. Transactions safe tables (BDB) and not transaction safe tables (ISAM,MyISAM and HEAP.

Advantages of transaction safe tables (TST)

  * Safer; Even if MySQL crashes or you get hardware problems, you can get your data back;  Either by automatic recovery or from a backup + the transaction log.

  * You can combine many statements and accept these all in one go with the COMMIT command.

  * You can execute ROLLBACK to ignore your changes (if you are not running in auto commit mode).

  * If an update fails, all your changes will be restored. (With NTST tables all changes that has taken place are permanent)

Advantages of not transaction safe tables (NTST):

  * Much faster as there is no transcation overhead.

  * Will use less disk space as there is no overhead of transactions.

  * Will use less memory to do updates.

You can combine TST and NTST tables in the same statements to get the best of both worlds.

MyISAM tables
=============

MyISAM は、MySQL 3.23 でのデフォルトのテーブル形式です．これは ISAM コードを基にし、多くの便利な拡張機能を持っています。

インデックスは .MYI (MYindex) 拡張子のつくファイルに保存され、データは、 .MYD (MYData) 拡張子のつくファイルに保存されます。 myisamchk ユーティリティを使用して、 MyISAM テーブルの検査・修復が可能です。 See Crash recovery.

The following is new in MyISAM:

  * あるスレッドが読み込み中のテーブルに対し、違うスレッドが同じテーブルに、新しい行を INSERT できます。削除はなしで You can INSERT new rows in a table without deleted rows, while other threads are reading from the table.

  * 大ファイル (63 bit) のサポート。ただし、filesystems/operating systems が巨大ファイルをサポートしている場合。

  * 全データは、下位バイトが先にかかれます。 これは、データを、マシン・OS 非依存にしました。 The only requirement is that the machine uses two's-complement signed integers (as every machine for the last 20 years has) and IEEE floating point format (also totally dominant among mainstream machines). The only area of machines that may not support binary compatibility are embedded systems (because they sometimes have peculiar processors).

  * 全数値キーは高位バイトが先に書かれます。 これはインデックスの圧縮率を良くします。

  * Internal handling of one AUTO_INCREMENT column. MyISAM will automatically update this on INSERT/UPDATE. The AUTO_INCREMENT value can be reset with myisamchk. This will make AUTO_INCREMENT columns faster (at least 10 %) and old numbers will not be reused as with the old ISAM. Note that when a AUTO_INCREMENT is defined on the end of a multi-part-key the old behavior is still present.

  * When inserted in sorted order (as when you are using an AUTO_INCREMENT column) the key tree will be split so that the high node only contains one key. This will improve the space utilization in the key tree.

  * BLOB と TEXT フィールドにインデックスが張れます

  * NULL 値をインデックスの張られたフィールドに許します． This takes 0-1 bytes/key.

  * 現在、キーの最大長はデフォルトで 500 です。 In cases of keys longer than 250 bytes, a bigger key block size than the default of 1024 bytes is used for this key.

  * Maximum number of keys/table enlarged to 32 as default. This can be enlarged to 64 without having to recompile myisamchk.

  * There is a flag in the MyISAM file that indicates whether or not the table was closed correctly.  This will soon be used for automatic repair in the MySQL server.

  * myisamchk will mark tables as checked if one runs it with --update-state. myisamchk --fast will only check those tables that don't have this mark.

  * myisamchk -a stores statistics for key parts (and not only for whole keys as in ISAM).

  * Dynamic size rows will now be much less fragmented when mixing deletes with updates and inserts.  This is done by automatically combining adjacent deleted blocks and by extending blocks if the next block is deleted.

  * myisampack は BLOB と VARCHAR フィールドをパックすることが可能です。

MyISAM also supports the following things, which MySQL will be able to use in the near future.

  * Support for a true VARCHAR type; A VARCHAR column starts with a length stored in 2 bytes.

  * Tables with VARCHAR may have fixed or dynamic record length.

  * VARCHAR and CHAR may be up to 64K. All key segments have their own language definition. This will enable MySQL to have different language definitions per column.

  * A hashed computed index can be used for UNIQUE; This will allow you to have UNIQUE on any combination of columns in a table. (You can't search on a UNIQUE computed index, however.)

Space needed for keys
---------------------

MySQL can support different index types, but the normal type is ISAM or MyISAM.  These use a B-tree index and you can roughly calculate the size for the index file as (key_length+4)/0.67, summed over all keys.  (This is for the worst case when all keys are inserted in sorted order and we don't have any compressed keys.)

String indexes are space compressed. If the first index part is a string, it will also be prefix compressed.  Space compression makes the index file smaller than the above figures if the string column has a lot of trailing space or is a VARCHAR column that is not always used to the full length. Prefix compression is used on keys that start with a string.  Prefix compression helps if there are many strings with an identical prefix.

In MyISAM tables, you can also prefix compress numbers by specifying PACK_KEYS=1 when you create the table.  This helps when you have many integer keys which have an identical prefix when the numbers are stored high-byte first.

MyISAM table formats
--------------------

MyISAM supports 3 different table types. 2 of them are chosen automatically depending on the type of columns you are using. The third, compressed tables, can only be created with the myisampack tool.

Static (Fixed-length) table characteristics
...........................................

This is the default format. It's used when the table contains no VARCHAR, BLOB or TEXT columns.

このフォーマットは、最も単純、かつ、安全なフォーマットです。これは, Disk 上に作られるテーブルの中で、最も速いフォーマットでもあります。これはディスク上のデータを見つけやすいからです。 When looking up something with an index and static format it is very simple, just multiply the row number with the row length.

Also when scanning a table it is very easy to read a constant number of records with each disk read.

安全、というのは、次の様なことです。もし仮に、静的(固定長) MyISAM ファイルに書き込み中に、あなたのコンピュータがクラッシュした場合、 myisamchk は、それぞれのレコードの開始点と終了点を安易に見つけることが出来ます。 So it can usually reclaim all records except the partially written one. MySQL では、常に、全てのインデックスが再構築できることに注意してください。

  * 全ての CHAR, NUMERIC, DECIMAL フィールドは、そのフィールド長に足りない部分にはスペースが埋められます。

  * とても速い

  * キャッシュしやすい。

  * クラッシュの後再構築しやすい。なぜならレコードが固定された位置に割り当てられているから。

  * Doesn't have to be reorganized (with myisamchk) unless a huge number of records are deleted and you want to return free disk space to the operating system.

  * 通常、動的テーブルよりも多くのディスク容量が必要。

Dynamic table characteristics
.............................

This format is used if the table contains any VARCHAR, BLOB or TEXT columns or if the table was created with ROW_FORMAT=dynamic.

この形式は少し複雑です。 なぜならそれぞれのレコードが、レコードがどのぐらいの長さを持っているかを記録するヘッダーを持っているからです。 One record can also end up at more than one location when it is made longer at an update.

OPTIMIZE table か myisamchk を使用して、テーブルのフラグメンテーションを修正することが可能です。 If you have static data that you access/change a lot in the same table as some VARCHAR or BLOB columns, it might be a good idea to move the dynamic columns to other tables just to avoid fragmentation.

  * 全ての文字フィールドが動的になります（ただし4byteより短い物は除きます）

  * それぞれのレコードの先頭には、フィールドの状態を表すビット・マップがきます。このビットは、どの文字型フィールドが空文字('')なのか、どの数値フィールドがゼロなのかを示します。 (これはフィールドの値が NULL 値とは違います)。もし、文字型フィールドの文字列の長さ(後に続く空白は取り除かれる)が ゼロ であったり、あるいは、数値フィールドの値が ゼロ であった場合は、そのフィールドはビット・マップにマークされ、値はディスクには保存されません。空文字ではない場合は、文字列のバイト数がビット・マップに記録され、文字列自身がフィールドに保存されます。

  * 通常、固定長のテーブルよりも少ないディスク容量ですみます

  * それぞれのレコードは、要求されただけのスペースを使用します。もしあるレコードが大きくなると、要求された分、それを多くの断片に分けます。この結果、レコードのフラグメンテーションが発生します。

  * If you update a row with information that extends the row length, the row will be fragmented.  In this case, you may have to run myisamchk -r from time to time to get better performance.  Use myisamchk -ei tbl_name for some statistics.

  * Not as easy to reconstruct after a crash, because a record may be fragmented into many pieces and a link (fragment) may be missing.

  * 期待されるレコードの長さは：

          3
          + (フィールド数 + 7) / 8
          + (char フィールドの数)
          + 数値フィールドをパックしたサイズ
          + 文字の長さ
          + (NULL フィールドの数 + 7) / 8

     There is a penalty of 6 bytes for each link. A dynamic record is linked whenever an update causes an enlargement of the record. Each new link will be at least 20 bytes, so the next enlargement will probably go in the same link. If not, there will be another link. You may check how many links there are with myisamchk -ed. All links may be removed with myisamchk -r.

Compressed table characteristics
................................

これは読み込み専用の型で、オプションツールの myisampack で作成されます。 (pack_isam for ISAM tables).

myisampack and pack_isam are available to all customers that have bought a MySQL license or MySQL support for their internal use.

  * The uncompress code exists in all MySQL distributions so that even customers who don't have myisampack can read tables that were compressed with myisampack

  * Compressed tables takes very little disk space. This minimizes disk usage which is very nice when using slow disks (like CD-ROMs).

  * Each record is compressed separately (very little access overhead).  The header for a record is fixed (1-3 bytes) depending on the biggest record in the table.  Each column is compressed differently. Some of the compression types are:

       - There is usually a different Huffman table for each column.

       - Suffix space compression.

       - Prefix space compression.

       - Numbers with value 0 are stored using 1 bit.

       - If values in an integer column have a small range, the column is stored using the smallest possible type. For example, a BIGINT column (8 bytes) may be stored as a TINYINT column (1 byte) if all values are in the range 0 to 255.

       - If a column has only a small set of possible values, the column type is converted to ENUM.

       - A column may use a combination of the above compressions.

  * Can handle fixed or dynamic length records, but not BLOB or TEXT columns.

  * Can be uncompressed with myisamchk.

ISAM tables
===========

You can also use the deprecated ISAM table type. This will disappear rather soon because MyISAM is a better implementation of the same thing. ISAM uses a B-tree index. The index is stored in a file with the .ISM extension and the data is stored in file with the .ISD extension.  You can check/repair ISAM tables with the isamchk utility. See Crash recovery.

ISAM has the following features/properties:

  * Compressed and fixed length keys

  * Fixed and dynamic record length

  * 16 keys with 16 key parts / key

  * Max key length 256 (default)

  * Data is stored in machine format;  this is fast, but is machine/OS dependent.

Most of the things for MyISAM tables are also true for ISAM tables. See MyISAM. The major differences compared to MyISAM tables are:

  * ISAM tables are not binary portable across OS/Platforms.

  * Can't handle tables > 4G.

  * Only support prefix compression on strings

  * Smaller key limits.

  * Dynamic tables gets more fragmented.

  * Tables are compressed with pack_isam rather than with myisampack.

HEAP tables
===========

HEAP tables use a hashed index and are stored in memory.  This makes them very fast, but if MySQL crashes you will lose all data stored in them.  HEAP is very useful as temporary tables!

MySQL 内部 HEAP テーブルは、100% ダイナッミック・ハッシングを使用しておいます（オーバーフローエリア無しに）。 There is no extra space needed for free lists. HEAP tables also don't have problems with delete + inserts, which normally is common with hashed tables..

     mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down
             FROM log_table GROUP BY ip;
     mysql> SELECT COUNT(ip),AVG(down) FROM test;
     mysql> DROP TABLE test;

Here are some things you should consider when you use HEAP tables:

  * You should always use specify MAX_ROWS in the CREATE statement to ensure that you accidently do not use all memory.

  * Indexes will only be used with = and <=> (but are VERY fast).

  * HEAP tables can only use whole keys to search for a row; compare this to MyISAM tables where any prefix of the key can be used to find rows.

  * HEAP tables use a fixed record length format.

  * HEAP doesn't support BLOB/TEXT columns.

  * HEAP doesn't support AUTO_INCREMENT columns.

  * HEAP doesn't support an index on a NULL column.

  * You can have non-unique keys in a HEAP table (this isn't common for hashed tables).

  * HEAP tables are shared between all clients (just like any other table).

  * You can't search for the next entry in order (that is to use the index to do a ORDER BY).

  * Data for HEAP tables are allocated in small blocks. The tables are 100% dynamic (on inserting). No overflow areas and no extra key space is needed.  Deleted rows are put in a linked list and are reused when you insert new data into the table.

  * You need enough extra memory for all HEAP tables that you want to use at the same time.

  * To free memory, you should execute DELETE FROM heap_table or DROP TABLE heap_table.

  * MySQL cannot find out how approximately many rows there are between two values (this is used by the range optimizer to decide which index to use).  This may affect some queries if you change a MyISAM table to a HEAP table.

  * To ensure that you accidentally don't do anything stupid, you can't create HEAP tables bigger than max_heap_table_size.

Memory needed for one row in a HEAP table is:

SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*)*2) + ALIGN(length_of_row+1,sizeof(char*))

sizeof(char*) is 4 on 32 bit machines and 8 on 64 bit machines.

BDB or Berkeley_db tables
=========================

Berkeley DB (http://www.sleepycat.com) has provided MySQL with a transaction safe table handler. This will survive crashes and also provides COMMIT and ROLLBACK on transactions. In order to build MySQL 3.23.x (BDB support first appeared in 3.23.15) with support for BDB tables, you will need Berkeley DB 3.1.11 or newer which can be downloaded from http://www.mysql.com/download_3.23.html; or also from Sleepycat's download page at http://www.sleepycat.com/download.html.

Even if Berkeley DB is in itself very tested and reliably, the MySQL interface is still very alpha, but we are actively improving and optimizing it to get it this stable real soon.

If you are running with AUTOCOMMIT=0 then your changes in BDB tables will not be updated until you execute COMMIT.  Instead of commit you can execute ROLLBACK to forget your changes. See COMMIT.

The following options to mysqld can be used to change the behavour of BDB tables:

--bdb-home=  directory    Berkeley home direcory
item --bdb-lock-detect=#    Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM or YOUNGEST)
--bdb-logdir=directory   Berkeley DB log file directory
--bdb-nosync   Don't synchronously flush logs
--bdb-recover   Start Berkeley DB in recover mode
--bdb-tmpdir=directory   Berkeley DB tempfile name
--skip-bdb   Don't use berkeley db.

If you use --skip-bdb, MySQL will not initialize the Berkeley DB library and this will save a lot of memory.  You can of course not use BDB tables if you are using this option.

Some characteristic of BDB tables:

  * All BDB tables must have a primary key.

  * If all columns you access in a BDB tables is part of the same index or part of the the primary key then MySQL can execute the query without having to access the actual row.  In a MyISAM table the above holds only if the columns are part of the same index.

  * LOCK TABLES works on BDB tables as with other tables.  If you don't use LOCK TABLE, MYSQL will issue an internal multiple write lock on the table to ensure that the table will be properly locked if one another thread issues a table lock.

  * ALTER TABLE doesn't yet work on BDB tables.

  * Internal locking in BDB tables are done on page level.

  * Scanning is slower than with MyISAM tables as one has data in BDB tables is stored in B-trees and not in a separate data file.

  * One must in the application always be prepared to handle the case that any change of a BDB table may make an automatic rollback and any read may fail with a deadlock error.

  * Keys are not compressed to previous keys as with ISAM or MyISAM tables. In other words, the key information will take a little more space in BDB tables compared to MyISAM tables with don't use PACK_KEYS=0.

  * One must do a FLUSH LOGS from time to time to sync to get checkpoints for the BDB tables.

  * As transaction logs take more place than ordinary logs it's more important to rotate and remove old logs when using BDB tables than using other table types.

Some things that we have to fix in the near future:

  * Remove the requirement that BDB tables must have a primary key.  This will be fixed by having an automatic hidden auto_increment column for the tables without a primary key.

  * LOCK TABLES should work as for other MySQL tables.

  * ALTER TABLE doesn't yet work.

  * SHOW TABLE STATUS doesn't yet provide that much information for BDB tables.

MySQL チュートリアル
*************

この章では、 mysql クライアントプログラムの使用の仕方と単純なデータベースの作成と使用の仕方を例題としてとり上げます。 mysql (``terminal monitor'' や ``monitor'' として参照されます)は MySQL サーバーに接続できる対話モードのプログラムで、クエリの実行や結果の表示が可能です。 mysql はバッチモードも可能です： クエリをまずファイルに書いておき、そしてそのファイルを mysql に実行させます。どちらの方法でも mysql はこの章の説明でカバーされます。

mysql の提供するオプションを見るには、 --help オプションを実行します：

     shell> mysql --help

この章では mysql が既にあなたのマシンにインストールされているものとし、また MySQL サーバーに接続可能であるとします。 もしそうでないなら、あなたの MySQL 管理者に連絡を取ってください。 (もしあなた自身が管理者なら、このマニュアルの他のセクションを参照してください。)

本章ではデータベース設定の全体のプロセス、データベースの使用について述べます。もしあなたが既に存在しているデータベースにアクセスする事だけに興味があるなら、この章のデータベース、テーブルの作成方法の説明を読み飛ばしてもかまいません。

この章が本質的にはチュートリアルであるので、多くの詳細は、かならず違う章にあります。ここに書かれている事柄で、さらに詳しい情報についてはマニュアルの適切なセクションを調べて下さい。

サーバーへの接続と切断
===========

サーバーに mysql コマンドから接続するためには、通常、 MySQL ユーザ名、パスワードを指定する必要があるでしょう。もしあなたがログインしている以外のマシンの上でサーバーが走っていれば、あなたは、ホスト名を明示する必要があるでしょう。まずあなたの管理者に問い合わせて、あなたが使うべき接続のためのパラメーターを見つけ出して下さい。 (すなわち、どのようなホスト、ユーザー名とパスワードを使うべきなのか。) 適切なパラメーターを知っていれば、あなたは、以下のようにして接続できます：

     shell> mysql -h host -u user -p
     Enter password: ********

******** とかかれている部分にはあなたのパスワードを入れます； mysql が Enter password: プロンプトを出したときに。

きちんと動けば、いくつかの情報と mysql> プロンプトが現れます：

     shell> mysql -h host -u user -p
     Enter password: ********
     Welcome to the MySQL monitor.  Commands end with ; or \g.
     Your MySQL connection id is 459 to server version: 3.22.20a-log

     Type 'help' for help.

     mysql>

このプロンプトは mysql がコマンド入力を待っている状態を示します。

いくつかの MySQL インストレーションでは、ローカルホストで実行されているサーバーに、ユーザーに``匿名''(名前無し)の接続を許しています。もしあなたのマシンがこの場合に当てはまるなら、mysql をオプション無しで起動すべきです：

     shell> mysql

接続が成功した後、 mysql> プロンプトで、QUIT とタイプすればいつでも接続を切ることができます：

     mysql> QUIT
     Bye

control-D で切断してもかまいません。

以下のセクションでのほとんどの例では、あなたがサーバーに接続しているものとしています。その場合は mysql> プロンプトによって、それを示しています。

クエリの入力
======

前のセクションで述べたように、あなたがサーバーとつながっていることを確かめて下さい。この状態ではまだどんなデータベースも選択していない状態です。しかしそれはかまいません。ここでは、テーブルの作成やデータの入力、取り出しよりも、いかにクエリを発行するかに重点を置きます。このセクションでは、あなた自身を mysql の動きに慣れさせるために、あなたがやってみることができるであろう、いくつかのクエリを使用して、コマンド入力の基本的な原則を述べます。

サーバーのバージョン、今日の日付をサーバーに問い合わせる、単純なコマンドがここにあります。 以下のように mysql> プロンプトの後に入力し RETURN キーを押してみてください：

     mysql> SELECT VERSION(), CURRENT_DATE;
     +--------------+--------------+
     | version()    | CURRENT_DATE |
     +--------------+--------------+
     | 3.22.20a-log | 1999-03-19   |
     +--------------+--------------+
     1 row in set (0.01 sec)
     mysql>

このクエリは、mysql のいくつかの事を説明しています：

  * 通常、コマンドは、セミコロンで終わる SQL ステートメントから、構成されます。 (セミコロンが必要とされないいくつかの例外があります。以前に述べた QUIT はそのうちの一つです。後で他も出てきます。)

  * コマンドを発行すると、mysql はそれをサーバーに送り、結果を表示します。その後、 mysql> プロンプトを出し、他のコマンドが受け付けれる状態であると示します。

  * mysql はクエリの結果を表にして出します。 最初の行は項目のラベル名です。その下の行に、クエリの結果が続きます。 通常、項目のラベル名はデータベースのテーブルからあなたが取り出したフィールド名になります。 テーブルのフィールド名以外の式をあなたが検索したのなら(ちょうど例のように)、mysql は与えられた式自身を項目のラベル名として表示します。

  * mysql は何レコード(rows)返ってきたかを示し、実行にどれくらいの時間がかかったかも示します。 これはおおざっぱなサーバーのパフォーマンスを示します。これらの値は wall clock time (CPU や マシンタイムではなく) を使用しており、さらに、サーバーの負荷、およびネットワーク待ち時間といった要因にも影響されるので、不正確です。 (この章の他の例題においては ``rows in set'' の行は省きます。)

キーワードは、いかなる大文字小文字でも記述できます。以下に示すクエリは同じです：

     mysql> SELECT VERSION(), CURRENT_DATE;
     mysql> select version(), current_date;
     mysql> SeLeCt vErSiOn(), current_DATE;

以下のクエリは、mysql を簡単な計算機として使用した例です：

     mysql> SELECT SIN(PI()/4), (4+1)*5;
     +-------------+---------+
     | SIN(PI()/4) | (4+1)*5 |
     +-------------+---------+
     |    0.707107 |      25 |
     +-------------+---------+

今までは見てきたたコマンドは、比較的短い、一行のの文です。あなたは一行に複数、文を書くことが出来ます。それぞれの文の終わりにはセミコロンを付けます：

     mysql> SELECT VERSION(); SELECT NOW();
     +--------------+
     | version()    |
     +--------------+
     | 3.22.20a-log |
     +--------------+

     +---------------------+
     | NOW()               |
     +---------------------+
     | 1999-03-19 00:15:33 |
     +---------------------+

コマンドは一行にかく必要もありません。 複数行にわたる長いコマンドでも問題ありません。 mysql はセミコロンで、一文の終わりと見なします。 その行の最後を文の最後とは見なしません。 （いうなれば、mysql は自由な入力を許し、セミコロンが現れるまではそれらの入力された行を実行しません）

複数行にまたがった文の例です：

     mysql> SELECT
         -> USER()
         -> ,
         -> CURRENT_DATE;
     +--------------------+--------------+
     | USER()             | CURRENT_DATE |
     +--------------------+--------------+
     | joesmith@localhost | 1999-03-18   |
     +--------------------+--------------+

この例では、複数にまたがるクエリにおいて、最初の行の入力のあと、いかにプロンプトが mysql> から -> に変わるかを示しています。これは mysql が、まだ文が終わっておらず、残りの部分の入力を待っていることを示します。  The prompt is your friend, because it provides valuable feedback.  If you use that feedback, you will always be aware of what mysql is waiting for.

入力中にコマンドの実行を取りやめようと思った場合、 \c でこれをキャンセルできます：

     mysql> SELECT
         -> USER()
         -> \c
     mysql>

Here, too, notice the prompt.  It switches back to mysql> after you type \c, providing feedback to indicate that mysql is ready for a new command.

以下の表に、 mysql のプロンプトとその状態の説明を示します：

プロンプト   意味
mysql>   新しいコマンドの待状態
    ->   複数行にまたがるコマンドの、次の行の入力を待っている状態。
    '>   シングルクオート (') で始められた文字の、次の行の入力を待っている状態。
    ">   ダブルクオート (") で始められた文字の、次の行の入力を待っている状態。

あなたが文をセミコロンで終わらすことを忘れて実行した場合に、複数行の入力待ちが起こります。 この場合、 mysql は次の入力を待ちます：

     mysql> SELECT USER()
         ->

If this happens to you (you think you've entered a statement but the only response is a -> prompt), most likely mysql is waiting for the semicolon.  If you don't notice what the prompt is telling you, you might sit there for a while before realizing what you need to do.  Enter a semicolon to complete the statement, and mysql will execute it:

     mysql> SELECT USER()
         -> ;
     +--------------------+
     | USER()             |
     +--------------------+
     | joesmith@localhost |
     +--------------------+

The '> and "> prompts occur during string collection. In MySQL, you can write strings surrounded by either ' or " characters (for example, 'hello' or "goodbye"), and mysql lets you enter strings that span multiple lines.  When you see a '> or "> prompt, it means that you've entered a line containing a string that begins with a ' or " quote character, but have not yet entered the matching quote that terminates the string. That's fine if you really are entering a multiple-line string, but how likely is that?  Not very.  More often, the '> and "> prompts indicate that you've inadvertantly left out a quote character.  For example:

     mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
         ">

If you enter this SELECT statement, then hit RETURN and wait for the result, nothing will happen.  Instead of wondering, ``why does this query take so long?,'' notice the clue provided by the "> prompt.  It tells you that mysql expects to see the rest of an unterminated string.  (Do you see the error in the statement?  The string "Smith is missing the second quote.)

At this point, what do you do?  The simplest thing is to cancel the command. However, you cannot just type \c in this case, because mysql interprets it as part of the string that it is collecting!  Instead, enter the closing quote character (so mysql knows you've finished the string), then type \c:

     mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
         "> "\c
     mysql>

The prompt changes back to mysql>, indicating that mysql is ready for a new command.

It's important to know what the '> and "> prompts signify, because if you mistakenly enter an unterminated string, any further lines you type will appear to be ignored by mysql --- including a line containing QUIT!  This can be quite confusing, especially if you don't know that you need to supply the terminating quote before you can cancel the current command.

Examples of common queries
==========================

Here follows examples of how to solve some common problems with MySQL.

Some of the examples use the table shop to hold the price of each article (item number) for certain traders (dealers).  Supposing that each trader has a single fixed price per article, then (item, trader) is a primary key for the records.

You can create the example table as:

     CREATE TABLE shop (
      article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
      dealer  CHAR(20)                 DEFAULT ''     NOT NULL,
      price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL,
      PRIMARY KEY(article, dealer));

     INSERT INTO shop VALUES
     (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),
     (3,'D',1.25),(4,'D',19.95);

Okay, so the example data is:

     SELECT * FROM shop

     +---------+--------+-------+
     | article | dealer | price |
     +---------+--------+-------+
     |    0001 | A      |  3.45 |
     |    0001 | B      |  3.99 |
     |    0002 | A      | 10.99 |
     |    0003 | B      |  1.45 |
     |    0003 | C      |  1.69 |
     |    0003 | D      |  1.25 |
     |    0004 | D      | 19.95 |
     +---------+--------+-------+

The maximum value for a column
------------------------------

``What's the highest item number?''

     SELECT MAX(article) AS article FROM shop

     +---------+
     | article |
     +---------+
     |       4 |
     +---------+

The row holding the maximum of a certain column
-----------------------------------------------

``Find number, dealer, and price of the most expensive article.''

In ANSI SQL this is easily done with a sub-query:

     SELECT article, dealer, price
     FROM   shop
     WHERE  price=(SELECT MAX(price) FROM shop)

In MySQL (which does not yet have sub-selects), just do it in two steps:

 1. Get the maximum price value from the table with a SELECT statement.

 2. Using this value compile the actual query:

          SELECT article, dealer, price
          FROM   shop
          WHERE  price=19.95

Another solution is to sort all rows descending by price and only get the first row using the MySQL specific LIMIT clause:

     SELECT article, dealer, price
     FROM   shop
     ORDER BY price DESC
     LIMIT 1

Note:  If there are several most expensive articles (e.g. each 19.95) the LIMIT solution shows only one of them!

Maximum of column: per group: only the values
---------------------------------------------

``What's the highest price per article?''

     SELECT article, MAX(price) AS price
     FROM   shop
     GROUP BY article

     +---------+-------+
     | article | price |
     +---------+-------+
     |    0001 |  3.99 |
     |    0002 | 10.99 |
     |    0003 |  1.69 |
     |    0004 | 19.95 |
     +---------+-------+

The rows holding the group-wise maximum of a certain field
----------------------------------------------------------

``For each article, find the dealer(s) with the most expensive price.''

In ANSI SQL, I'd do it with a sub-query like this:

     SELECT article, dealer, price
     FROM   shop s1
     WHERE  price=(SELECT MAX(s2.price)
                   FROM shop s2
                   WHERE s1.article = s2.article)

In MySQL it's best do it in several steps:

 1. Get the list of (article,maxprice). See example-Maximum-column-group-row.

 2. For each article get the corresponding rows which have the stored maximum price.

This can easily be done with a temporary table:

     CREATE TEMPORARY TABLE tmp (
             article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
             price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL);

     LOCK TABLES article read;

     INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;

     SELECT article, dealer, price FROM shop, tmp
     WHERE shop.article=tmp.article AND shop.price=tmp.price;

     UNLOCK TABLES;

     DROP TABLE tmp;

If you don't use a TEMPORARY table, you must also lock the 'tmp' table.

`Can it be done with a single query?''

Yes, but only by using a quite inefficient trick that I call the ``MAX-CONCAT trick'':

     SELECT article,
            SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer,
       0.00+LEFT(      MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price
     FROM   shop
     GROUP BY article;

     +---------+--------+-------+
     | article | dealer | price |
     +---------+--------+-------+
     |    0001 | B      |  3.99 |
     |    0002 | A      | 10.99 |
     |    0003 | C      |  1.69 |
     |    0004 | D      | 19.95 |
     +---------+--------+-------+

The last example can of course be made a bit more efficient by doing the splitting of the concatenated column in the client.

Using foreign keys
------------------

You don't need foreign keys to join 2 tables.

The only thing MySQL doesn't do is CHECK to make sure that the keys you use really exist in the table(s) you're referencing and it doesn't automatically delete rows from table with a foreign key definition. If you use your keys like normal, it'll work just fine!

     CREATE TABLE persons (
         id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
         name CHAR(60) NOT NULL,
         PRIMARY KEY (id)
     );

     CREATE TABLE shirts (
         id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
         style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
         color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
         owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,
         PRIMARY KEY (id)
     );

     INSERT INTO persons VALUES (NULL, 'Antonio Paz');

     INSERT INTO shirts VALUES
     (NULL, 'polo', 'blue', LAST_INSERT_ID()),
     (NULL, 'dress', 'white', LAST_INSERT_ID()),
     (NULL, 't-shirt', 'blue', LAST_INSERT_ID());

     INSERT INTO persons VALUES (NULL, 'Lilliana Angelovska');

     INSERT INTO shirts VALUES
     (NULL, 'dress', 'orange', LAST_INSERT_ID()),
     (NULL, 'polo', 'red', LAST_INSERT_ID()),
     (NULL, 'dress', 'blue', LAST_INSERT_ID()),
     (NULL, 't-shirt', 'white', LAST_INSERT_ID());

     SELECT * FROM persons;
     +----+---------------------+
     | id | name                |
     +----+---------------------+
     |  1 | Antonio Paz         |
     |  2 | Lilliana Angelovska |
     +----+---------------------+

     SELECT * FROM shirts;
     +----+---------+--------+-------+
     | id | style   | color  | owner |
     +----+---------+--------+-------+
     |  1 | polo    | blue   |     1 |
     |  2 | dress   | white  |     1 |
     |  3 | t-shirt | blue   |     1 |
     |  4 | dress   | orange |     2 |
     |  5 | polo    | red    |     2 |
     |  6 | dress   | blue   |     2 |
     |  7 | t-shirt | white  |     2 |
     +----+---------+--------+-------+

     SELECT s.* FROM persons p, shirts s
      WHERE p.name LIKE 'Lilliana%'
        AND s.owner = p.id
        AND s.color <> 'white';

     +----+-------+--------+-------+
     | id | style | color  | owner |
     +----+-------+--------+-------+
     |  4 | dress | orange |     2 |
     |  5 | polo  | red    |     2 |
     |  6 | dress | blue   |     2 |
     +----+-------+--------+-------+

Searching on two keys
=====================

MySQL doesn't yet optimize when you search on two different keys combined with OR (Searching on one key with different OR parts is optimized quite good):

     SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1'
     OR  field2_index = '1'

The reason is that we haven't yet had time to come up with an efficient way to handle this in the general case. (The AND handling is in comparison now completely general and works very well).

For the moment you can solve this very efficently by using a TEMPORARY table; This type of optimization is also very good if you are using very complicated queries where the SQL server does the optimizations in the wrong order.

     CREATE TEMPORARY TABLE tmp
     SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1';
     INSERT INTO tmp
     SELECT field1_index, field2_index FROM test_table WHERE field2_index = '1';
     SELECT * from tmp;
     DROP TABLE tmp;

The above way to solve this query is in effect an UNION of two queries.

Creating and using a database
=============================

Now that you know how to enter commands, it's time to access a database.

Suppose you have several pets in your home (your ``menagerie'') and you'd like to keep track of various types of information about them.  You can do so by creating tables to hold your data and loading them with the desired information.  Then you can answer different sorts of questions about your animals by retrieving data from the tables.  This section shows how to do all that:

  * How to create a database

  * How to create a table

  * How to load data into the table

  * How to retrieve data from the table in various ways

  * How to use multiple tables

The menagerie database will be simple (deliberately), but it is not difficult to think of real-world situations in which a similar type of database might be used.  For example, a database like this could be used by a farmer to keep track of livestock, or by a veterinarian to keep track of patient records.

Use the SHOW statement to find out what databases currently exist on the server:

     mysql> SHOW DATABASES;
     +----------+
     | Database |
     +----------+
     | mysql    |
     | test     |
     | tmp      |
     +----------+

The list of databases is probably different on your machine, but the mysql and test databases are likely to be among them.  The mysql database is required because it describes user access privileges.  The test database is often provided as a workspace for users to try things out.

If the test database exists, try to access it:

     mysql> USE test
     Database changed

Note that USE, like QUIT, does not require a semicolon.  (You can terminate such statements with a semicolon if you like; it does no harm.) The USE statement is special in another way, too:  it must be given on a single line.

You can use the test database (if you have access to it) for the examples that follow, but anything you create in that database can be removed by anyone else with access to it.  For this reason, you should probably ask your MySQL administrator for permission to use a database of your own.  Suppose you want to call yours menagerie.  The administrator needs to execute a command like this:

     mysql> GRANT ALL ON menagerie.* TO your_mysql_name;

where your_mysql_name is the MySQL user name assigned to you.

Creating and selecting a database
---------------------------------

If the administrator creates your database for you when setting up your permissions, you can begin using it.  Otherwise, you need to create it yourself:

     mysql> CREATE DATABASE menagerie;

Under Unix, database names are case sensitive (unlike SQL keywords), so you must always refer to your database as menagerie, not as Menagerie, MENAGERIE or some other variant.  This is also true for table names.  (Under Windows, this restriction does not apply, although you must refer to databases and tables using the same lettercase throughout a given query.)

Creating a database does not select it for use, you must do that explicitly. To make menagerie the current database, use this command:

     mysql> USE menagerie
     Database changed

Your database needs to be created only once, but you must select it for use each time you begin a mysql session.  You can do this by issuing a USE statement as shown above.  Alternatively, you can select the database on the command line when you invoke mysql.  Just specify its name after any connection parameters that you might need to provide.  For example:

     shell> mysql -h host -u user -p menagerie
     Enter password: ********

Note that menagerie is not your password on the command just shown. If you want to supply your password on the command line after the -p option, you must do so with no intervening space (e.g., as -pmypassword, not as -p mypassword).  However, putting your password on the command line is not recommended, because doing so exposes it to snooping by other users logged in on your machine.

Creating a table
----------------

Creating the database is the easy part, but at this point it's empty, as SHOW TABLES will tell you:

     mysql> SHOW TABLES;
     Empty set (0.00 sec)

The harder part is deciding what the structure of your database should be: what tables you will need, and what columns will be in each of them.

You'll want a table that contains a record for each of your pets.  This can be called the pet table, and it should contain, as a bare minimum, each animal's name.  Because the name by itself is not very interesting, the table should contain other information.  For example, if more than one person in your family keeps pets, you might want to list each animal's owner.  You might also want to record some basic descriptive information such as species and sex.

How about age?  That might be of interest, but it's not a good thing to store in a database.  Age changes as time passes, which means you'd have to update your records often.  Instead, it's better to store a fixed value such as date of birth.  Then, whenever you need age, you can calculate it as the difference between the current date and the birth date.  MySQL provides functions for doing date arithmetic, so this is not difficult. Storing birth date rather than age has other advantages, too:

  * You can use the database for tasks such as generating reminders for upcoming pet birthdays.  (If you think this type of query is somewhat silly, note that it is the same question you might ask in the context of a business database to identify clients to whom you'll soon need to send out birthday greetings, for that computer-assisted personal touch.)

  * You can calculate age in relation to dates other than the current date.  For example, if you store death date in the database, you can easily calculate how old a pet was when it died.

You can probably think of other types of information that would be useful in the pet table, but the ones identified so far are sufficient for now: name, owner, species, sex, birth and death.

Use a CREATE TABLE statement to specify the layout of your table:

     mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
         -> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);

VARCHAR is a good choice for the name, owner and species columns because the column values will vary in length.  The lengths of those columns need not all be the same, and need not be 20.  You can pick any length from 1 to 255, whatever seems most reasonable to you.  (If you make a poor choice and it turns out later that you need a longer field, MySQL provides an ALTER TABLE statement.)

Animal sex can be represented in a variety of ways, for example, "m" and "f", or perhaps "male" and "female".  It's simplest to use the single characters "m" and "f".

The use of the DATE data type for the birth and death columns is a fairly obvious choice.

Now that you have created a table, SHOW TABLES should produce some output:

     mysql> SHOW TABLES;
     +---------------------+
     | Tables in menagerie |
     +---------------------+
     | pet                 |
     +---------------------+

To verify that your table was created the way you expected, use a DESCRIBE statement:

     mysql> DESCRIBE pet;
     +---------+-------------+------+-----+---------+-------+
     | Field   | Type        | Null | Key | Default | Extra |
     +---------+-------------+------+-----+---------+-------+
     | name    | varchar(20) | YES  |     | NULL    |       |
     | owner   | varchar(20) | YES  |     | NULL    |       |
     | species | varchar(20) | YES  |     | NULL    |       |
     | sex     | char(1)     | YES  |     | NULL    |       |
     | birth   | date        | YES  |     | NULL    |       |
     | death   | date        | YES  |     | NULL    |       |
     +---------+-------------+------+-----+---------+-------+

You can use DESCRIBE any time, for example, if you forget the names of the columns in your table or what types they are.

Loading data into a table
-------------------------

After creating your table, you need to populate it.  The LOAD DATA and INSERT statements are useful for this.

Suppose your pet records can be described as shown below. (Observe that MySQL expects dates in YYYY-MM-DD format; this may be different than what you are used to.)

name   owner   species   sex   birth   death
Fluffy   Harold   cat   f   1993-02-04
Claws   Gwen   cat   m   1994-03-17
Buffy   Harold   dog   f   1989-05-13
Fang   Benny   dog   m   1990-08-27
Bowser   Diane   dog   m   1998-08-31   1995-07-29
Chirpy   Gwen   bird   f   1998-09-11
Whistler   Gwen   bird     1997-12-09
Slim   Benny   snake   m   1996-04-29

Because you are beginning with an empty table, an easy way to populate it is to create a text file containing a row for each of your animals, then load the contents of the file into the table with a single statement.

You could create a text file pet.txt containing one record per line, with values separated by tabs, and given in the order in which the columns were listed in the CREATE TABLE statement.  For missing values (such as unknown sexes, or death dates for animals that are still living), you can use NULL values.  To represent these in your text file, use \N.  For example, the record for Whistler the bird would look like this (where the whitespace between values is a single tab character):

Whistler   Gwen   bird   \N   1997-12-09   \N

To load the text file pet.txt into the pet table, use this command:

     mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

You can specify the column value separator and end of line marker explicitly in the LOAD DATA statement if you wish, but the defaults are tab and linefeed.  These are sufficient for the statement to read the file pet.txt properly.

When you want to add new records one at a time, the INSERT statement is useful.  In its simplest form, you supply values for each column, in the order in which the columns were listed in the CREATE TABLE statement. Suppose Diane gets a new hamster named Puffball.  You could add a new record using an INSERT statement like this:

     mysql> INSERT INTO pet
         -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);

Note that string and date values are specified as quoted strings here.  Also, with INSERT, you can insert NULL directly to represent a missing value.  You do not use \N like you do with LOAD DATA.

From this example, you should be able to see that there would be a lot more typing involved to load your records initially using several INSERT statements rather than a single LOAD DATA statement.

Retrieving information from a table
-----------------------------------

The SELECT statement is used to pull information from a table. The general form of the statement is:

     SELECT what_to_select
     FROM which_table
     WHERE conditions_to_satisfy

what_to_select indicates what you want to see.  This can be a list of columns, or * to indicate ``all columns.'' which_table indicates the table from which you want to retrieve data.  The WHERE clause is optional.  If it's present, conditions_to_satisfy specifies conditions that rows must satisfy to qualify for retrieval.

Selecting all data
..................

The simplest form of SELECT retrieves everything from a table:

     mysql> SELECT * FROM pet;
     +----------+--------+---------+------+------------+------------+
     | name     | owner  | species | sex  | birth      | death      |
     +----------+--------+---------+------+------------+------------+
     | Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
     | Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
     | Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
     | Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
     | Bowser   | Diane  | dog     | m    | 1998-08-31 | 1995-07-29 |
     | Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
     | Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
     | Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
     | Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
     +----------+--------+---------+------+------------+------------+

This form of SELECT is useful if you want to review your entire table, for instance, after you've just loaded it with your initial dataset.  As it happens, the output just shown reveals an error in your data file:  Bowser appears to have been born after he died!  Consulting your original pedigree papers, you find that the correct birth year is 1989, not 1998.

There are are least a couple of ways to fix this:

  * Edit the file pet.txt to correct the error, then empty the table and reload it using DELETE and LOAD DATA:

          mysql> DELETE FROM pet;
          mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

     However, if you do this, you must also re-enter the record for Puffball.

  * Fix only the erroneous record with an UPDATE statement:

          mysql> UPDATE pet SET birth = "1989-08-31" WHERE name = "Bowser";

As shown above, it is easy to retrieve an entire table.  But typically you don't want to do that, particularly when the table becomes large.  Instead, you're usually more interested in answering a particular question, in which case you specify some constraints on the information you want.  Let's look at some selection queries in terms of questions about your pets that they answer.

Selecting particular rows
.........................

You can select only particular rows from your table.  For example, if you want to verify the change that you made to Bowser's birth date, select Bowser's record like this:

     mysql> SELECT * FROM pet WHERE name = "Bowser";
     +--------+-------+---------+------+------------+------------+
     | name   | owner | species | sex  | birth      | death      |
     +--------+-------+---------+------+------------+------------+
     | Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
     +--------+-------+---------+------+------------+------------+

The output confirms that the year is correctly recorded now as 1989, not 1998.

String comparisons are normally case-insensitive, so you can specify the name as "bowser", "BOWSER", etc.  The query result will be the same.

You can specify conditions on any column, not just name.  For example, if you want to know which animals were born after 1998, test the birth column:

     mysql> SELECT * FROM pet WHERE birth >= "1998-1-1";
     +----------+-------+---------+------+------------+-------+
     | name     | owner | species | sex  | birth      | death |
     +----------+-------+---------+------+------------+-------+
     | Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
     | Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
     +----------+-------+---------+------+------------+-------+

You can combine conditions, for example, to locate female dogs:

     mysql> SELECT * FROM pet WHERE species = "dog" AND sex = "f";
     +-------+--------+---------+------+------------+-------+
     | name  | owner  | species | sex  | birth      | death |
     +-------+--------+---------+------+------------+-------+
     | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
     +-------+--------+---------+------+------------+-------+

The preceding query uses the AND logical operator.  There is also an OR operator:

     mysql> SELECT * FROM pet WHERE species = "snake" OR species = "bird";
     +----------+-------+---------+------+------------+-------+
     | name     | owner | species | sex  | birth      | death |
     +----------+-------+---------+------+------------+-------+
     | Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
     | Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL  |
     | Slim     | Benny | snake   | m    | 1996-04-29 | NULL  |
     +----------+-------+---------+------+------------+-------+

AND and OR may be intermixed.  If you do that, it's a good idea to use parentheses to indicate how conditions should be grouped:

     mysql> SELECT * FROM pet WHERE (species = "cat" AND sex = "m")
         -> OR (species = "dog" AND sex = "f");
     +-------+--------+---------+------+------------+-------+
     | name  | owner  | species | sex  | birth      | death |
     +-------+--------+---------+------+------------+-------+
     | Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
     | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
     +-------+--------+---------+------+------------+-------+

Selecting particular columns
............................

If you don't want to see entire rows from your table, just name the columns in which you're interested, separated by commas.  For example, if you want to know when your animals were born, select the name and birth columns:

     mysql> SELECT name, birth FROM pet;
     +----------+------------+
     | name     | birth      |
     +----------+------------+
     | Fluffy   | 1993-02-04 |
     | Claws    | 1994-03-17 |
     | Buffy    | 1989-05-13 |
     | Fang     | 1990-08-27 |
     | Bowser   | 1989-08-31 |
     | Chirpy   | 1998-09-11 |
     | Whistler | 1997-12-09 |
     | Slim     | 1996-04-29 |
     | Puffball | 1999-03-30 |
     +----------+------------+

To find out who owns pets, use this query:

     mysql> SELECT owner FROM pet;
     +--------+
     | owner  |
     +--------+
     | Harold |
     | Gwen   |
     | Harold |
     | Benny  |
     | Diane  |
     | Gwen   |
     | Gwen   |
     | Benny  |
     | Diane  |
     +--------+

However, notice that the query simply retrieves the owner field from each record, and some of them appear more than once.  To minimize the output, retrieve each unique output record just once by adding the keyword DISTINCT:

     mysql> SELECT DISTINCT owner FROM pet;
     +--------+
     | owner  |
     +--------+
     | Benny  |
     | Diane  |
     | Gwen   |
     | Harold |
     +--------+

You can use a WHERE clause to combine row selection with column selection.  For example, to get birth dates for dogs and cats only, use this query:

     mysql> SELECT name, species, birth FROM pet
         -> WHERE species = "dog" OR species = "cat";
     +--------+---------+------------+
     | name   | species | birth      |
     +--------+---------+------------+
     | Fluffy | cat     | 1993-02-04 |
     | Claws  | cat     | 1994-03-17 |
     | Buffy  | dog     | 1989-05-13 |
     | Fang   | dog     | 1990-08-27 |
     | Bowser | dog     | 1989-08-31 |
     +--------+---------+------------+

Sorting rows
............

You may have noticed in the preceding examples that the result rows are displayed in no particular order.  However, it's often easier to examine query output when the rows are sorted in some meaningful way.  To sort a result, use an ORDER BY clause.

Here are animal birthdays, sorted by date:

     mysql> SELECT name, birth FROM pet ORDER BY birth;
     +----------+------------+
     | name     | birth      |
     +----------+------------+
     | Buffy    | 1989-05-13 |
     | Bowser   | 1989-08-31 |
     | Fang     | 1990-08-27 |
     | Fluffy   | 1993-02-04 |
     | Claws    | 1994-03-17 |
     | Slim     | 1996-04-29 |
     | Whistler | 1997-12-09 |
     | Chirpy   | 1998-09-11 |
     | Puffball | 1999-03-30 |
     +----------+------------+

To sort in reverse order, add the DESC (descending) keyword to the name of the column you are sorting by:

     mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
     +----------+------------+
     | name     | birth      |
     +----------+------------+
     | Puffball | 1999-03-30 |
     | Chirpy   | 1998-09-11 |
     | Whistler | 1997-12-09 |
     | Slim     | 1996-04-29 |
     | Claws    | 1994-03-17 |
     | Fluffy   | 1993-02-04 |
     | Fang     | 1990-08-27 |
     | Bowser   | 1989-08-31 |
     | Buffy    | 1989-05-13 |
     +----------+------------+

You can sort on multiple columns.  For example, to sort by type of animal, then by birth date within animal type with youngest animals first, use the following query:

     mysql> SELECT name, species, birth FROM pet ORDER BY species, birth DESC;
     +----------+---------+------------+
     | name     | species | birth      |
     +----------+---------+------------+
     | Chirpy   | bird    | 1998-09-11 |
     | Whistler | bird    | 1997-12-09 |
     | Claws    | cat     | 1994-03-17 |
     | Fluffy   | cat     | 1993-02-04 |
     | Fang     | dog     | 1990-08-27 |
     | Bowser   | dog     | 1989-08-31 |
     | Buffy    | dog     | 1989-05-13 |
     | Puffball | hamster | 1999-03-30 |
     | Slim     | snake   | 1996-04-29 |
     +----------+---------+------------+

Note that the DESC keyword applies only to the column name immediately preceding it (birth); species values are still sorted in ascending order.

日付の計算
.....

MySQL はいくつかの日付の計算を行う関数を提供します。例えば、年の計算や日付の部分を取り出したり。

ペットの年齢が何才なのかを知るためには、現在の日付と誕生日との差を計算します。 このためには、二つの日付を日数に直し、差を取り、そして 365 (年の日数) で割ります：

     mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 FROM pet;
     +----------+-------------------------------------+
     | name     | (TO_DAYS(NOW())-TO_DAYS(birth))/365 |
     +----------+-------------------------------------+
     | Fluffy   |                                6.15 |
     | Claws    |                                5.04 |
     | Buffy    |                                9.88 |
     | Fang     |                                8.59 |
     | Bowser   |                                9.58 |
     | Chirpy   |                                0.55 |
     | Whistler |                                1.30 |
     | Slim     |                                2.92 |
     | Puffball |                                0.00 |
     +----------+-------------------------------------+

クエリは動きましたが、改良したいくつかのことがあります。第1に、この結果は、もしレコードにいくつかの順番を与えれば、簡単に並び換えが出来そうなこと。第2に、年齢欄の見出しは、このままではなんなのか分かりません。

最初の問題は ORDER BY name 節を加えることで name 順で並び換えが出来ます。二つ目の問題に対しては、違う見出しを出力に現れるように、欄の見出しを扱います (これを フィールドのエイリアス と呼びます) :

     mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age
         -> FROM pet ORDER BY name;
     +----------+------+
     | name     | age  |
     +----------+------+
     | Bowser   | 9.58 |
     | Buffy    | 9.88 |
     | Chirpy   | 0.55 |
     | Claws    | 5.04 |
     | Fang     | 8.59 |
     | Fluffy   | 6.15 |
     | Puffball | 0.00 |
     | Slim     | 2.92 |
     | Whistler | 1.30 |
     +----------+------+

name ではなく age で並び換えるには、 ORDER BY 節を以下のように変えます：

     mysql>  SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age
         ->  FROM pet ORDER BY age;
     +----------+------+
     | name     | age  |
     +----------+------+
     | Puffball | 0.00 |
     | Chirpy   | 0.55 |
     | Whistler | 1.30 |
     | Slim     | 2.92 |
     | Claws    | 5.04 |
     | Fluffy   | 6.15 |
     | Fang     | 8.59 |
     | Bowser   | 9.58 |
     | Buffy    | 9.88 |
     +----------+------+

似たクエリが、既に死んでしまった動物の、死んだ時点の年齢を調べるのにも使用できます。 どの動物が死んでいるかどうかは、death 値が NULL かどうかで判断します。 これらの値が 非NULL ならば、 death と birth の差の計算を行います：

     mysql>  SELECT name, birth, death, (TO_DAYS(death)-TO_DAYS(birth))/365 AS age
         ->  FROM pet WHERE death IS NOT NULL ORDER BY age;
     +--------+------------+------------+------+
     | name   | birth      | death      | age  |
     +--------+------------+------------+------+
     | Bowser | 1989-08-31 | 1995-07-29 | 5.91 |
     +--------+------------+------------+------+

このクエリでは、 death != NULL ではなく death IS NOT NULL を使用します。 なぜなら、 NULL は特別な値だからです。 これは後で解説します。 See Working with NULL.

もしあなたが翌月誕生日の動物を知りたいとします。 この種の計算では、年と日が関係ありません。  birth フィールドの月だけを単に取り出したくなるでしょう。 MySQL は日付の部分を取り出すいくつかの関数を提供します。 YEAR(), MONTH(), DAYOFMONTH() など。ここでは MONTH() がいいでしょう。 これがどのように動くか確かめるには、 birth と MONTH(birth) の両方を表示させるクエリを実行してみます：

     mysql> SELECT name, birth, MONTH(birth) FROM pet;
     +----------+------------+--------------+
     | name     | birth      | MONTH(birth) |
     +----------+------------+--------------+
     | Fluffy   | 1993-02-04 |            2 |
     | Claws    | 1994-03-17 |            3 |
     | Buffy    | 1989-05-13 |            5 |
     | Fang     | 1990-08-27 |            8 |
     | Bowser   | 1989-08-31 |            8 |
     | Chirpy   | 1998-09-11 |            9 |
     | Whistler | 1997-12-09 |           12 |
     | Slim     | 1996-04-29 |            4 |
     | Puffball | 1999-03-30 |            3 |
     +----------+------------+--------------+

来月誕生日を迎える動物を見つけるのは簡単です。 現在4月だとします。すると、5月生まれの動物を探します：

     mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
     +-------+------------+
     | name  | birth      |
     +-------+------------+
     | Buffy | 1989-05-13 |
     +-------+------------+

もし現在が12月なら、ちょっと困るかもしれません。 月の数字 (12) に 1 を足して 13 月生まれの動物を探すわけにはいきません。 かわりに1月生まれの動物を探します。

現在が何月なのかを気にすることなく、動作するクエリを書くことが可能です。この方法では、あなたは月の数字をクエリに使用することがありません。 DATE_ADD() 関数は与えた日付からある時間を足すことが可能です。もし現時点 NOW() の値に 1ヶ月 足し、 MONTH() で月の部分を取り出し、その結果を、誕生月を調べるために使用します：

     mysql> SELECT name, birth FROM pet
         -> WHERE MONTH(birth) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));

同じことができる別の方法として、剰余関数 を使用した結果に 1 を足す方法があります。 (もし今月が12月なら、剰余関数 (MOD) を使用した結果は 0 になります)：

     mysql> SELECT name, birth FROM pet
         -> WHERE MONTH(birth) = MOD(MONTH(NOW()), 12) + 1;

Note that MONTH return a number between 1 and 12. And MOD(something,12) returns a number between 0 and 11. So the addition has to be after the MOD() oterwise we would go from November (11) to January (1).

NULL 値の振る舞い
...........

あなたがそれに慣れるまでは、NULL 値には驚くかもしれません。概念的に、NULL 値は ``値無し'' か ``未知な値'' を意味し、他の値よりもいくぶん異なって扱われます。 NULL の評価の際には、数値の比較演算子 =, <, != を使用することは出来ません。 あなた自身これをデモするために、以下のようにしてみてください：

     mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
     +----------+-----------+----------+----------+
     | 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL |
     +----------+-----------+----------+----------+
     |     NULL |      NULL |     NULL |     NULL |
     +----------+-----------+----------+----------+

確実にこれらの比較からいかなる意味がある結果も受け取りません。この代わりに、 IS NULL , IS NOT NULL 演算子を使用します：

     mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
     +-----------+---------------+
     | 1 IS NULL | 1 IS NOT NULL |
     +-----------+---------------+
     |         0 |             1 |
     +-----------+---------------+

MySQL では, 0 は false（偽） で、1 が true（真）です。

この NULL の特別な扱いはなぜなのか。 前のセクションを見てください。どの動物がもはや生きていないことを決定づけるためには、 death != NULL ではなく death IS NOT NULL の使用が必要とされるのです。

パターン・マッチ
........

MySQL は標準SQLのパターン・マッチを提供します。また、拡張された正規表現を基にした形式のパターン・マッチ、これは vi, grep and sed など UNIX のユーティリティに使用されている物と似ていますが、これも提供します。

SQL パターン・マッチは、 _ でいかなる１文字とも一致し、 % であらゆる0こ以上の文字列に一致します。 MySQL では、デフォルトで SQL パターンはケース非依存です。いくつか例を以下に示します。 SQLパターンを使用する場合、 = や != を使用しないように注意してください。 LIKE か NOT LIKE を代わりに使用します。

b から始まる名前を見つけるには:

     mysql> SELECT * FROM pet WHERE name LIKE "b%";
     +--------+--------+---------+------+------------+------------+
     | name   | owner  | species | sex  | birth      | death      |
     +--------+--------+---------+------+------------+------------+
     | Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
     | Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
     +--------+--------+---------+------+------------+------------+

fy で終わる名前を見つけるには:

     mysql> SELECT * FROM pet WHERE name LIKE "%fy";
     +--------+--------+---------+------+------------+-------+
     | name   | owner  | species | sex  | birth      | death |
     +--------+--------+---------+------+------------+-------+
     | Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
     | Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
     +--------+--------+---------+------+------------+-------+

w を含む名前を見つけるには:

     mysql> SELECT * FROM pet WHERE name LIKE "%w%";
     +----------+-------+---------+------+------------+------------+
     | name     | owner | species | sex  | birth      | death      |
     +----------+-------+---------+------+------------+------------+
     | Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
     | Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
     | Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
     +----------+-------+---------+------+------------+------------+

5文字の名前を見つけるには, _ パターン文字を使用して：

     mysql> SELECT * FROM pet WHERE name LIKE "_____";
     +-------+--------+---------+------+------------+-------+
     | name  | owner  | species | sex  | birth      | death |
     +-------+--------+---------+------+------------+-------+
     | Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
     | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
     +-------+--------+---------+------+------------+-------+

MySQL では他のパターン・マッチの形も提供されます。正規表現の拡張を使用して。これらのパターン・マッチをテストする際には、REGEXP と NOT REGEXP 演算子（あるいはRLIKE, NOT RLIKE 演算子。これらは同義です）を使用します。

拡張正規表現のいくつかの特徴：

  * . はいかなる一文字とも一致します。

  * [...] は、かっこ内にある文字と一致します。例えば、[abc] は a, b あるいは c にマッチします。文字を範囲指定する場合にはダッシュを使用します。 [a-z] はいかなる小文字のアルファベット文字にも一致し、 [0-9] はいかなる数字にも一致します。

  * * は、先に指定されている文字 0 個以上にマッチします。例えば、x* は 文字 x がいくつも連続している物にマッチし、 [0-9]* はいかなる数値ともマッチし、 .* はあらゆる文字列に一致します。

  * 正規表現はケース依存です。 しかし大文字小文字どちらでもマッチさせたい場合、文字クラスを使用できます。 例えば、 [aA] は大文字小文字の a にマッチし、[a-zA-Z] は大文字小文字のいかなるアルファベット文字にもマッチします。

  * パターンは、テストされた値の中のどこかにある場合、マッチします。 (SQL patterns match only if they match the entire value).

  * 値のはじめ、あるいは終わりに位置を指定してマッチさせたい場合は、パターンの初めにマッチさせる場合は ^ を使用し、パターンの終わりにマッチさせる場合は $ を使用します。 (これらはアンカーと呼ばれます)

以下は拡張された正規表現がどう動くかの例です。上に示した LIKE のクエリは REGEXP で以下のように書き換えれます：

b で始まる名前をみつけるには、^ で名前の頭にマッチさせ、かつ [bB] として、大文字小文字にもマッチさせます：

     mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
     +--------+--------+---------+------+------------+------------+
     | name   | owner  | species | sex  | birth      | death      |
     +--------+--------+---------+------+------------+------------+
     | Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
     | Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
     +--------+--------+---------+------+------------+------------+

fy で終わる名前を見つけるには、 $ を使用して名前の最後にマッチさせます：

     mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
     +--------+--------+---------+------+------------+-------+
     | name   | owner  | species | sex  | birth      | death |
     +--------+--------+---------+------+------------+-------+
     | Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
     | Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
     +--------+--------+---------+------+------------+-------+

w を含む名前を見つけるには、[wW] を使用して大文字小文字にマッチさせます：

     mysql> SELECT * FROM pet WHERE name REGEXP "[wW]";
     +----------+-------+---------+------+------------+------------+
     | name     | owner | species | sex  | birth      | death      |
     +----------+-------+---------+------+------------+------------+
     | Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
     | Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
     | Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
     +----------+-------+---------+------+------------+------------+

正規表現はもし値中のどこかにでもあればマッチするため、 SQL パターンのように、パターンの前後にワイルドカードを書く必要はありません。

5文字の名前を見つけるには、^ と $ を使用して名前の初めと終わりにマッチさせ、その間に . を5個入れます：

     mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
     +-------+--------+---------+------+------------+-------+
     | name  | owner  | species | sex  | birth      | death |
     +-------+--------+---------+------+------------+-------+
     | Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
     | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
     +-------+--------+---------+------+------------+-------+

前のクエリは {n} ``n回繰り返し'' オペレーターで書換え可能です。

     mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$";
     +-------+--------+---------+------+------------+-------+
     | name  | owner  | species | sex  | birth      | death |
     +-------+--------+---------+------+------------+-------+
     | Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
     | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
     +-------+--------+---------+------+------------+-------+

Counting rows
.............

Databases are often used to answer the question, ``How often does a certain type of data occur in a table?''  For example, you might want to know how many pets you have, or how many pets each owner has, or you might want to perform various kinds of censuses on your animals.

Counting the total number of animals you have is the same question as ``How many rows are in the pet table?,'' because there is one record per pet. The COUNT() function counts the number of non-NULL results, so the query to count your animals looks like this:

     mysql> SELECT COUNT(*) FROM pet;
     +----------+
     | COUNT(*) |
     +----------+
     |        9 |
     +----------+

Earlier, you retrieved the names of the people who owned pets.  You can use COUNT() if you want to find out how many pets each owner has:

     mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
     +--------+----------+
     | owner  | COUNT(*) |
     +--------+----------+
     | Benny  |        2 |
     | Diane  |        2 |
     | Gwen   |        3 |
     | Harold |        2 |
     +--------+----------+

Note the use of GROUP BY to group together all records for each owner.  Without it, all you get is an error message:

     mysql> SELECT owner, COUNT(owner) FROM pet;
     ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
     with no GROUP columns is illegal if there is no GROUP BY clause

COUNT() and GROUP BY are useful for characterizing your data in various ways.  The following examples show different ways to perform animal census operations.

Number of animals per species:

     mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
     +---------+----------+
     | species | COUNT(*) |
     +---------+----------+
     | bird    |        2 |
     | cat     |        2 |
     | dog     |        3 |
     | hamster |        1 |
     | snake   |        1 |
     +---------+----------+

Number of animals per sex:

     mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
     +------+----------+
     | sex  | COUNT(*) |
     +------+----------+
     | NULL |        1 |
     | f    |        4 |
     | m    |        4 |
     +------+----------+

(In this output, NULL indicates ``sex unknown.'')

Number of animals per combination of species and sex:

     mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
     +---------+------+----------+
     | species | sex  | COUNT(*) |
     +---------+------+----------+
     | bird    | NULL |        1 |
     | bird    | f    |        1 |
     | cat     | f    |        1 |
     | cat     | m    |        1 |
     | dog     | f    |        1 |
     | dog     | m    |        2 |
     | hamster | f    |        1 |
     | snake   | m    |        1 |
     +---------+------+----------+

You need not retrieve an entire table when you use COUNT().  For example, the previous query, when performed just on dogs and cats, looks like this:

     mysql> SELECT species, sex, COUNT(*) FROM pet
         -> WHERE species = "dog" OR species = "cat"
         -> GROUP BY species, sex;
     +---------+------+----------+
     | species | sex  | COUNT(*) |
     +---------+------+----------+
     | cat     | f    |        1 |
     | cat     | m    |        1 |
     | dog     | f    |        1 |
     | dog     | m    |        2 |
     +---------+------+----------+

Or, if you wanted the number of animals per sex only for known-sex animals:

     mysql> SELECT species, sex, COUNT(*) FROM pet
         -> WHERE sex IS NOT NULL
         -> GROUP BY species, sex;
     +---------+------+----------+
     | species | sex  | COUNT(*) |
     +---------+------+----------+
     | bird    | f    |        1 |
     | cat     | f    |        1 |
     | cat     | m    |        1 |
     | dog     | f    |        1 |
     | dog     | m    |        2 |
     | hamster | f    |        1 |
     | snake   | m    |        1 |
     +---------+------+----------+

Using more than one table
-------------------------

The pet table keeps track of which pets you have.  If you want to record other information about them, such as events in their lives like visits to the vet or when litters are born, you need another table.  What should this table look like?

  * It needs to contain the pet name so you know which animal each event pertains to.

  * It needs a date so you know when the event occurred.

  * It needs a field to describe the event.

  * If you want to be able to categorize events, it would be useful to have an event type field.

Given these considerations, the CREATE TABLE statement for the event table might look like this:

     mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
         -> type VARCHAR(15), remark VARCHAR(255));

As with the pet table, it's easiest to load the initial records by creating a tab-delimited text file containing the information:

Fluffy   1995-05-15   litter   4 kittens, 3 female, 1 male
Buffy   1993-06-23   litter   5 puppies, 2 female, 3 male
Buffy   1994-06-19   litter   3 puppies, 3 female
Chirpy   1999-03-21   vet   needed beak straightened
Slim   1997-08-03   vet   broken rib
Bowser   1991-10-12   kennel
Fang   1991-10-12   kennel
Fang   1998-08-28   birthday   Gave him a new chew toy
Claws   1998-03-17   birthday   Gave him a new flea collar
Whistler   1998-12-09   birthday   First birthday

Load the records like this:

     mysql> LOAD DATA LOCAL INFILE "event.txt" INTO TABLE event;

Based on what you've learned from the queries you've run on the pet table, you should be able to perform retrievals on the records in the event table; the principles are the same.  But when is the event table by itself insufficient to answer questions you might ask?

Suppose you want to find out the ages of each pet when they had their litters.  The event table indicates when this occurred, but to calculate age of the mother, you need her birth date.  Because that is stored in the pet table, you need both tables for the query:

     mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark
         -> FROM pet, event
         -> WHERE pet.name = event.name AND type = "litter";
     +--------+------+-----------------------------+
     | name   | age  | remark                      |
     +--------+------+-----------------------------+
     | Fluffy | 2.27 | 4 kittens, 3 female, 1 male |
     | Buffy  | 4.12 | 5 puppies, 2 female, 3 male |
     | Buffy  | 5.10 | 3 puppies, 3 female         |
     +--------+------+-----------------------------+

There are several things to note about this query:

  * The FROM clause lists two tables because the query needs to pull information from both of them.

  * When combining (joining) information from multiple tables, you need to specify how records in one table can be matched to records in the other. This is easy because they both have a name column.  The query uses WHERE clause to match up records in the two tables based on the name values.

  * Because the name column occurs in both tables, you must be specific about which table you mean when referring to the column.  This is done by prepending the table name to the column name.

You need not have two different tables to perform a join.  Sometimes it is useful to join a table to itself, if you want to compare records in a table to other records in that same table.  For example, to find breeding pairs among your pets, you can join the pet table with itself to pair up males and females of like species:

     mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
         -> FROM pet AS p1, pet AS p2
         -> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";
     +--------+------+--------+------+---------+
     | name   | sex  | name   | sex  | species |
     +--------+------+--------+------+---------+
     | Fluffy | f    | Claws  | m    | cat     |
     | Buffy  | f    | Fang   | m    | dog     |
     | Buffy  | f    | Bowser | m    | dog     |
     +--------+------+--------+------+---------+

In this query, we specify aliases for the table name in order to be able to refer to the columns and keep straight which instance of the table each column reference is associated with.

データベースとテーブルの情報を得る
=================

データベースやテーブルの名前が何であったか、あるいはテーブルの構造はどうであったか、 (なんというフィールドがあったのか)忘れてしまった場合。 MySQL ではいくつかのデータベースとテーブルの情報を提供する文を通じてこの問題を処理します。

あなたは既に SHOW DATABASES を知っているはずで, これはサーバーが管理するデーターベースの一覧を表示します。 現在選択しているデータベースが何であるかを知るには、DATABASE() 関数を使用します：

     mysql> SELECT DATABASE();
     +------------+
     | DATABASE() |
     +------------+
     | menagerie  |
     +------------+

もしデータベースをまだ何も選択していなければ、結果はブランクです。

データベースに含まれるテーブルを見つけるには(たとえば、あなたがテーブル名を知らない場合)、このコマンドを使用します：

     mysql> SHOW TABLES;
     +---------------------+
     | Tables in menagerie |
     +---------------------+
     | event               |
     | pet                 |
     +---------------------+

もしテーブルの構造を知りたいなら、DESCRIBE コマンドが便利です；これはテーブルのそれぞれのフィールドについての情報を表示します。

     mysql> DESCRIBE pet;
     +---------+-------------+------+-----+---------+-------+
     | Field   | Type        | Null | Key | Default | Extra |
     +---------+-------------+------+-----+---------+-------+
     | name    | varchar(20) | YES  |     | NULL    |       |
     | owner   | varchar(20) | YES  |     | NULL    |       |
     | species | varchar(20) | YES  |     | NULL    |       |
     | sex     | char(1)     | YES  |     | NULL    |       |
     | birth   | date        | YES  |     | NULL    |       |
     | death   | date        | YES  |     | NULL    |       |
     +---------+-------------+------+-----+---------+-------+

Field はフィールド名を示し、Type はフィールドのデータ型、 Null はこのフィールドが Null 値を含むかを示し、 Key はこのフィールドがインデックス化されているかを示し、 Default はフィールドのデフォルトの値を示します。

もしテーブルにインデックスを持っているなら、 SHOW INDEX FROM tbl_name がそれらの情報を示します。

mysql のバッチモードでの使用
=================

前のセクションでは、mysql を対話モードで使用し、クエリの入力と結果を表示しました。 mysql はバッチモードでも実行可能です。これを行うには、あなたが実行したいコマンドをファイルに書いておき、そのファイルから入力を読み込むようにして mysql を実行します：

     shell> mysql < batch-file

もし接続パラメターを指定する必要がある場合は、以下のようになるでしょう：

     shell> mysql -h host -u user -p < batch-file
     Enter password: ********

この方法で mysql を使用するとき、あなたはスクリプトファイルを作成し、それを実行することになるでしょう。

なぜスクリプトを使用するのか？ それには以下の理由があります：

  * もし繰り返しクエリを実行する場合(毎日とか毎週とか)、スクリプトを書くことで、その実行の度にあなたがコマンドをタイプすることを省くことが可能です。

  * もし既にあるクエリに似た新しいクエリを書く場合、それらをコピーしスクリプトファイルを編集できます。

  * バッチモードはクエリの開発中や複数にまたがるコマンドには役に立ちます。もしコマンドが間違っていたとしても全てを打ち直す必要がありません。エラーを修正するためにスクリプトを編集し、再び mysql に実行させます。

  * もし多くの出力を出すようなクエリの場合、ページャーを使用して出力を見ることが出来ます。 出力がスクロールして画面から見えなくなるよりいいでしょう：

          shell> mysql < batch-file | more

  * あなたはより処理を行うために、結果をファイルに書き出すことが可能です：

          shell> mysql < batch-file > mysql.out

  * あなたは、他人へのあなたのスクリプトを配布することができます。これにより、ほかの人たちもコマンドを実行することができます。

  * いくつかの状況では、対話モードでは使用に耐えません。 たとえば、クエリを cron ジョブとして実行する場合。 この場合、バッチモードでなければなりません。

  * 端末が正しく扱えない文字を mysql コマンドに渡す場合。たとえば、EUC-JP, Shift_JIS の漢字文字などは、端末や環境によっては直接入力できない場合もあるでしょう。

mysql をバッチモードで使用するか、対話モードで使用するかで、デフォルトの出力形式が変わります。 例えば、 SELECT DISTINCT species FROM pet の出力は対話モードでは次のようになります：

     +---------+
     | species |
     +---------+
     | bird    |
     | cat     |
     | dog     |
     | hamster |
     | snake   |
     +---------+

しかし、バッチモードでは：

     species
     bird
     cat
     dog
     hamster
     snake

もしバッチモードでも対話モードのような出力を得たい場合には、mysql -t とします。出力中に、実行したコマンドを表示させるならば、mysql -vvv とします。

Queries from twin project
=========================

At Analytikerna and Lentus, we have been doing the systems and field work for a big research project. This project is a collaboration between the Institute of Environmental Medicine at Karolinska Institutet Stockholm and the Section on Clinical Research in Aging and Psychology at the University of Southern California.

The project involves a screening part where all twins in Sweden older than 65 years are interviewed by telephone. Twins who meet certain criteria are passed on to the next stage. In this latter stage, twins who want to participate are visited by a doctor/nurse team. Some of the examinations include physical and neuropsychological examination, laboratory testing, neuroimaging, psychological status assessment, and family history collection. In addition, data are collected on medical and environmental risk factors.

More information about Twin studies can be found at:

     http://www.imm.ki.se/TWIN/TWINUKW.HTM

The latter part of the project is administered with a web interface written using Perl and MySQL.

Each night all data from the interviews are moved into a MySQL database.

Find all non-distributed twins
------------------------------

The following query is used to determine who goes into the second part of the project:

     select
             concat(p1.id, p1.tvab) + 0 as tvid,
             concat(p1.christian_name, " ", p1.surname) as Name,
             p1.postal_code as Code,
             p1.city as City,
             pg.abrev as Area,
             if(td.participation = "Aborted", "A", " ") as A,
             p1.dead as dead1,
             l.event as event1,
             td.suspect as tsuspect1,
             id.suspect as isuspect1,
             td.severe as tsevere1,
             id.severe as isevere1,
             p2.dead as dead2,
             l2.event as event2,
             h2.nurse as nurse2,
             h2.doctor as doctor2,
             td2.suspect as tsuspect2,
             id2.suspect as isuspect2,
             td2.severe as tsevere2,
             id2.severe as isevere2,
             l.finish_date
     from
             twin_project as tp
             /* For Twin 1 */
             left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab
             left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab
             left join harmony as h on tp.id = h.id and tp.tvab = h.tvab
             left join lentus as l on tp.id = l.id and tp.tvab = l.tvab
             /* For Twin 2 */
             left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab
             left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab
             left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab
             left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,
             person_data as p1,
             person_data as p2,
             postal_groups as pg
     where
             /* p1 gets main twin and p2 gets his/her twin. */
             /* ptvab is a field inverted from tvab */
             p1.id = tp.id and p1.tvab = tp.tvab and
             p2.id = p1.id and p2.ptvab = p1.tvab and
             /* Just the sceening survey */
             tp.survey_no = 5 and
             /* Skip if partner died before 65 but allow emigration (dead=9) */
             (p2.dead = 0 or p2.dead = 9 or
              (p2.dead = 1 and
               (p2.death_date = 0 or
                (((to_days(p2.death_date) - to_days(p2.birthday)) / 365)
                 >= 65))))
             and
             (
             /* Twin is suspect */
             (td.future_contact = 'Yes' and td.suspect = 2) or
             /* Twin is suspect - Informant is Blessed */
             (td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or
             /* No twin - Informant is Blessed */
             (ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or
             /* Twin broken off - Informant is Blessed */
             (td.participation = 'Aborted'
              and id.suspect = 1 and id.future_contact = 'Yes') or
             /* Twin broken off - No inform - Have partner */
             (td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0))
             and
             l.event = 'Finished'
             /* Get at area code */
             and substring(p1.postal_code, 1, 2) = pg.code
             /* Not already distributed */
             and (h.nurse is NULL or h.nurse=00 or h.doctor=00)
             /* Has not refused or been aborted */
             and not (h.status = 'Refused' or h.status = 'Aborted'
             or h.status = 'Died' or h.status = 'Other')
     order by
             tvid;

Some explanations:

concat(p1.id, p1.tvab) + 0 as tvid
     We want to sort on the concatenated id and tvab in numerical order. Adding 0 to the result causes MySQL to treat the result as a number.

column id
     This identifies a pair of twins. It is a key in all tables.

column tvab
     This identifies a twin in a pair. It has a value of 1 or 2.

column ptvab
     This is an inverse of tvab. When tvab is 1 this is 2, and vice versa. It exists to save typing and to make it easier for MySQL to optimize the query.

This query demonstrates, among other things, how to do lookups on a table from the same table with a join (p1 and p2). In the example, this is used to check whether a twin's partner died before the age of 65. If so, the row is not returned.

All of the above exist in all tables with twin-related information. We have a key on both id,tvab (all tables) and id,ptvab (person_data) to make queries faster.

On our production machine (A 200MHz UltraSPARC), this query returns about 150-200 rows and takes less than one second.

The current number of records in the tables used above:

Table              Rows
person_data          71074
lentus		  5291
twin_project         5286
twin_data		  2012
informant_data	  663
harmony		  381
postal_groups	  100

Show a table on twin pair status
--------------------------------

Each interview ends with a status code called event. The query shown below is used to display a table over all twin pairs combined by event. This indicates in how many pairs both twins are finished, in how many pairs one twin is finished and the other refused, and so on.

     select
             t1.event,
             t2.event,
             count(*)
     from
             lentus as t1,
             lentus as t2,
             twin_project as tp
     where
             /* We are looking at one pair at a time */
             t1.id = tp.id
             and t1.tvab=tp.tvab
             and t1.id = t2.id
             /* Just the sceening survey */
             and tp.survey_no = 5
             /* This makes each pair only appear once */
             and t1.tvab='1' and t2.tvab='2'
     group by
             t1.event, t2.event;

MySQL サーバーファンクション
*****************

MySQL がサポートしている言語は？
===================

mysqld は次の言語でエラーメッセージを提供できます: チェコ語, オランダ語, 英語(デフォルト), Estonia, フランス語, ドイツ語, ノルウェー語, 新ノルウェー語,ポーランド語, ポルトガル語, スペイン語そしてスウェーデン語。

ある言語で mysqld を開始するためには --language=lang または -L lang スイッチの一つを使います:

     shell> mysqld --language=swedish

or:

     shell> mysqld --language=/usr/local/share/swedish

言語名は全て小文字であることに注意してください。

言語ファイルは(デフォルトでは)次の場所にあります。 MYSQL_BASE_DIR/share/LANGUAGE/.

エラーメッセージファイルを更新したい場合は、 errmsg.txt ファイルを編集し、 errmsg.sys ファイルを作成するために以下のように実行します:

     shell> comp_err errmsg.txt errmsg.sys

もし MySQL を新しいものにアップグレードしたなら、以前修正した部分と同じところに、新しい errmsg.txt ファイルに修正をほどこしてください。

データとソートに使用されるキャラクターセット
----------------------

デフォルトでは、MySQL は ISO8859-1 (Latin1) キャラクターセットを使用します。これは USA と西ヨーロッパで使用されるキャラクターセットです。

キャラクターセットは名前として許される文字と、ORDER BY と GROUP BY コマンドによってソートされる方法を決定します。キャラクターセットは、名前として使用してもよい文字と SELECT 構文中の ORDER BY と GROUP BY コマンドを用いたソート方法を決定します。

You can change the character set with the --default-character-set option when you start the server. The character sets available depend on the --with-charset=charset option to configure, and the character set configuration files listed in SHAREDIR/charsets/Index. See Quick install.

When a client connects to a MySQL server, the server sends the default character set in use to the client.  The client will switch to use this character set for this connection.

One should use mysql_real_escape_string() when escaping strings for a SQL query.  mysql_real_escape_string() is identical to the old mysql_escape_string() function, except that it takes the MYSQL connection handle as the first parameter.

If the client is compiled with different paths than where the server is installed and the user that configured MySQL didn't included all character sets in the MySQL binary one must specify for the client where it can find the additional character sets it will need if the server runs with a different character set than the client.

On can specify this by putting in a MySQL option file:

     [client]
     default-set-dir=/usr/local/mysql/share/mysql/charsets

where the path points to where the dynamic MySQL character sets are stored.

One can force the client to use specific character set by specifying:

     [client]
     default-character-set=character-set-name

but normally this is never needed.

To add another character set to MySQL, use the following procedure:

新しいキャラクターセットの追加
---------------

 1. Decide if the set is simple or complex.  If the character set does not need to use special string collating routines for sorting, and does not need mulit-byte character support, it is simple.  If it needs either of those features, it is complex.

 2. If the character set is simple, then create the file sql/share/charsets/MYSET.conf, and add MYSET the sql/share/charsets/Index file.  Read the sql/share/charsets/README for more instructions.

 3. Add the character set name to the CHARSETS_AVAILABLE and COMPILED_CHARSETS lists in configure.in.

 4. Reconfigure, recompile and test.

 5. If the character set is complex, create the file strings/ctype-MYSET.c ファイルを MySQL のソースディレクトリ以下に作成します。

 6. Add MYSET to the end of the sql/share/charsets/Index file.  Take note of its position in the file - this is its character set number, denoted MYNUMBER below.

 7. 必要な定義されるものを調べるために、既存の ctype-*.c ファイルの一つを見てください。このファイル中で使用する配列の名前は、 ctype_MYSET, to_lower_MYSET のようにしなければいけないことに注意してください。

     Near the top of the file, place a special comment like this:

          /*
           * This comment is parsed by configure to create ctype.c,
           * so don't change it unless you know what you are doing.
           *
           * .configure. number_MYSET=MYNUMBER
           * .configure. strxfrm_multiply_MYSET=N
           * .configure. mbmaxlen_MYSET=N
           */

     The configure program uses this comment to include the character set into the MySQL library automatically.

     The strxfrm_multiply and mbmaxlen lines will be explained in the following sections.  Only include them if you the string collating functions or the multi-byte character set functions, respectively.

     to_lower[] と to_upper[] は、それぞれのキャラクターセットに於ける大文字、小文字の対応を定義した、単純な配列です。例えば：

          to_lower['A'] should contain 'a'
          to_upper['a'] should contain 'A'

     sort_order[] は文字がどのようにソートされるべきかのマップです。多くのセットでは、これは to_upper[] と同じです (ケース非依存ソート)。 MySQL は sort_order[character] の値を元に文字をソートします。 For more complicated sorting rules, see the discussion of string collating below.

     ctype[] は各文字を説明するビットの配列で、1かたまりのビット列が1文字を定義します。 ( to_lower[], to_upper[],sort_order[]は、文字の値でインデックスされますが、 ctype[]は文字の値+1 でインデックスされます。これは EOF を操作するためにずいぶん前から使われているので、この方法を使用しています。) m_ctype.h に次のビットマスクの定義を見ることができます:

          #define _U      01      /* Upper case */
          #define _L      02      /* Lower case */
          #define _N      04      /* Numeral (digit) */
          #define _S      010     /* Spacing character */
          #define _P      020     /* Punctuation */
          #define _C      040     /* Control character */
          #define _B      0100    /* Blank */
          #define _X      0200    /* heXadecimal digit */

     それぞれの文字に対する ctype[] は、文字を確定するためにビット列と組になっていなければなりません。たとえば、'A' は大文字定義 (_U) と 16進定義 (_X) 両方ともに属するので、ctype['A'+1] は以下の値を含まなくてはなりません:

          _U + _X = 01 + 0200 = 0201

 8. Add support for the string collating or multi-byte features needed, as described in the following sections.

 9. CHARSETS_AVAILABLE リストと configure.in の中の COMPILED_CHARSETS リストにキャラクターセット名を追加します。

 10. configureとコンパイルをしなおし、テストしてください。

String collating support
------------------------

If the sorting rules for your language are too complex to be handled with the simple sort_order[] table, you need to use the string collating functions.

Right now the best documentation on this is the character sets that are already implemented.  Look at the big5, czech, gbk, sjis and tis160 character sets for examples.

You must specify the strxfrm_multiply_MYSET=N value in the special comment at the top of the file.  N should be set to the maximum ratio the strings may grow during my_strxfrm_MYSET (it must be a positive integer).

マルチバイト文字のサポート
-------------

If your character set includes multi-byte characters, you need to use the multi-byte character functions.

Right now the best documentation on this is the character sets that are already implemented.  Look at the euc_kr, gb2312, gbk, sjis and ujis character sets for examples.

You must specify the mbmaxlen_MYSET=N value in the special comment at the top of the file.  N should be set to the size in bytes of the largest character in the set.

MySQL はテーブルをどれくらい大きくできるか？
=========================

MySQL 3.22 のテーブルサイズの制限は 4G です。 MySQL 3.23 の新しい MyISAM では、最大のテーブルサイズは 800万テラバイト (2 ^ 63 bytes) です.

しかし、それとは別に OS 自身のファイルサイズの制限があります。例えばいくつかの OS では以下のようになっています：

Linux-Intel   2G (or 4G with reiserfs)
Linux-Alpha   8T (?)
Solaris 2.5.1   2G (possible 4G with patch)
Solaris 2.6   4G
Solaris 2.7 Intel   4G
Solaris 2.7 ULTRA-SPARC   8T (?)

これは、通常、MySQL のテーブルサイズはオペーレーティングシステムによって制限されるということです。

By default, MySQL tables have a maximum size of about 4G.  You can check the maximum table size for a table with the SHOW TABLE STATUS command or with the myisamchk -dv table_name. See SHOW.

If you need bigger tables than 4G (and your operating system supports this), you should set the AVG_ROW_LENGTH and MAX_ROWS parameter when you create your table.  See CREATE TABLE.  You can also set these later with ALTER TABLE. See ALTER TABLE.

If you need to have bigger tables than 2G / 4G

もし大きなテーブルをリードオンリーで使用するなら、myisampackを使って複数のテーブルを結合したうえで圧縮することができます。myisampackは少なくとも 50% テーブルを圧縮することができ、その結果、大きなテーブルを使用することができます。 See myisampack.

他の方法として、"同じような"テーブルを一つにできる MERGE ライブラリーを含む方法があります。 ("同じような" とは、同じ項目情報をもって全てのテーブルが作られている状態をさします) MERGE はインデックスをサポートしていないため、同種のテーブルしか走査できません。これにインデックスの機能を近い将来追加する予定です。

Replication in MySQL
********************

Introduction
============

One way replication can be used both to increase robustness and speed. For robustness you have two systems and switch to the backup if you have problems with the master. The extra speed is achieved by sending a part of the non-updating queries to the replica server. Of course this only works if non-updating queries dominate, but that is the normal case.

Starting in 3.23.15, MySQL supports one-way replication internally. One server acts as the master, while the other acts as the slave. Note that one server could play the roles of master in one pair and slave in the other. The master server keeps a binary log of updates and an index file to binary logs to keep track of log rotation.  The slave upon connecting informs the master where it left off sinse the last successfully propogated update, catches up on the updates, and then blocks and waits for the master to notify it of the new updates.

Replication Implementation Overview
===================================

MySQL internal replication uses the master-slave approach. One server is designated as the master, while the other ( or others) as slave(s). The master keeps a binary log of updates. The slave connects to the master, catches up on the missed updates, and then starts receiving updates immediately as they come to the master. If the connection is lost, the slave will reconnect. If the master goes down, the slave will keep trying to connect every master-connect-retry seconds until the master comes back up and the connection can be established. The slave keeps track of where it left off in the replication process, so it can use the info in the case it goes down and gets restarted later.

HOWTO
=====

Below is a quick HOWTO on how to set up replication on your current system:

  * Upgrade both slave and master to 3.23.15 or higher.

  * Set up special replication user(s) on the master with the FILE privilege and permission to connect from all the slaves

  * Take a snapshot of all the tables/databases on the master that could possibly be involved in the update queries before taking the next step

  * In my.cnf on the master add log-bin and restart it. Make sure there are no important updates to the master between the time you have taken the snapshot and the time master is restarted with log-bin option

  * Load the snapshot of the master to all the slaves

  * Add the following to my.cnf on the slave(s):

          master-host=<hostname of the master>
          master-user=<replication user name>
          master-password=<replication user password>

     replacting the values in <> with what is relevant to your system.

  * Restart the slave(s)

After you have done the above, the master and the slave(s) should be in sync.

Replication Features
====================

Below is an explanation of what is supported and what is not:

  * Replication will be done correctly with AUTO_INCREMENT, LAST_INSERT_ID, and TIMESTAMP values

  * LOAD DATA INFILE will be handled properly as long as the file still resides on the master server at the time of update propogation. LOAD LOCAL DATA INFILE will be skipped.

  * Update queries that use user variables are not replication-safe (yet)

  * If the query on the slave gets an error, the slave thread will terminate, and a message will appear in .err file. You should then connect to the slave manually, fix the cause of the error (eg. non-existent table), and then run SLAVE START sql command ( available starting in 3.23.16, in 3.23.15 you will have to restart the server).

  * If connection to the master is lost, the slave will retry immediately, and then in case of failure every master-connect-retry (default 60) seconds. Because of this, it is safe to shut down the master, and then restart it after a while. The slave will also be able to deal with network connectivity outages.

  * Shutting down the slave (cleanly) is also safe, as it keeps track of where it left off.  Unclean shutdowns might produce problems, especially if disk cache was not synced before the system died. Your system fault tolerance will be greatly increased if you have a good UPS.

  * If the master is listening on a non-standard port, you will also need to specify this with master-port parameter in my.cnf .

  * In 3.23.15,all of the tables and databases will be replicated. Starting in 3.23.16, you can restrict replication to a set of databases with replicate-do-db directives in my.cnf or just excluse a set of databases with replicate-ignore-db.

  * Starting in 3.23.16, SET SQL_LOG_BIN = 0 will turn off replication (binary) logging on the master, and SET SQL_LOG_BIN = 1 will turn in back on - you must have the process privilege to do this.

  * The slave thread does not log updates to the binary log of the slave, so it is possible to couple two servers in a mutual master-slave relationship. You can actually set up a load balancing scheme and do queries safely on either of the servers. Just do not expect to do LOCK TABLES on one server, then connect to the other and still have that lock :-) .

Replication Options in my.cnf
=============================

The table below explains the replications options in my.cnf . All of the are available starting in 3.23.15 unless indicated otherwise.

Option   Description   Where to set   Example
log-bin   Should be set on the master. Tells it to keep a binary update
log. If a parameter is specified, the log will be written to the specified location.   Master
log-bin
log-bin-index   Because the user could issue FLUSH LOGS command, we need to
know which log is currently active and which ones have been rotated out and it what sequence. This info
is stored in the binary log index file. The default is `hostname`.index . You can use this option
if you want to be a rebel.   Master   log-bin-index=db.index
master-host   Master hostname or IP address for replication. If not set,
the slave thread will not be started   Slave   master-host=db-master.mycompany.com
master-user   The user the slave thread will authenticate as when connecting to
the master. The user must have FILE privilige. If the master user is not set, user test
is assumed.   Slave   master-user=scott
master-password   The password the slave thread will authenticate with when
connecting to the master. If not set, empty password is assumed   Slave
master-password=tiger
master-port   The port the master is listening on. If not set, the compiled setting of
MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be
3306.   Slave   master-port=3306
master-connect-retry   The number of seconds the slave thread will sleep before retrying
to connect to the master in case the master goes down or the connection is lost.
Default is 60.   Slave   master-connect-retry=60
master-info-file   The location of the file that remembers where we left off on the
master during the replication process. The default is master.info in the data directory.
Sasha:  The only reason I see for ever changing the default is the desire to
be rebelious.   Slave   master-info-file=master.info
replicate-do-db   Tells the slave thread to restrict replication to the specified database. To sp
cify more than one database, use the directive multiple times, once for each database.
Note that this will only work if you do not use cross-database queries such as
UPDATE some_db.some_table SET foo='bar' while having selected a different or
no database.   Slave   replicate-ignore-db=some_db
replicate-ignore-db   Tells the slave thread to not replicate to the specified
database. To specify more than one database to ignore, use the directive multiple times,
once for each database. You must not use cross database updates for this option.   Slave   replicate-
o-db=some_db
sql-bin-update-same   If set, setting  SQL_LOG_BIN to a value will
automatically set SQL_LOG_UPDATE to the same value and vice
versa.   Master   sql-bin-update-same

log-slave-updates   Tells the slave to log the updates from the slave thread to the binary log. Off by default. You will need to turn it on if you plan to daisy-chain the slaves   Slave   log-slave-updates

SQL commands related to replication
===================================

Replication can be controlled through the SQL interface. Below is the summary of commands:

Command   Description   Where to run
SLAVE START   Starts the slave thread.   Slave
SLAVE STOP   Stops the slave thread.   Slave
SET SQL_LOG_BIN=0   Disables update logging   Master
SET SQL_LOG_BIN=1   Re-enable update logging   Master

MySQL の最大性能をひきだすには
******************

Optimization is a complicated task because it ultimately requires understanding of the whole system. While it may be possible to do some local optimizations with small knowledge of your system/application, the more optimal you want your system to become the more you will have to know about it.

So this chapter will try to explain and give some examples of different ways to optimize MySQL. But remember that there are always some (increasingly harder) ways to make the system even faster left to do.

最適化 概要
======

システムを速くするための最も重要な部分は、もちろん基礎的な設計です。 You also need to know what kinds of things your system will be doing, and what your bottlenecks are.

主なボトルネックは：

  * Disk シーク ：一片のデータを見つけるためには、ディスクに時間がかかります。 1999年の最新型のディスクでは、このための平均時間は、10msよりも通常より小さいです。したがって、我々は、理論上は 1秒で約1000 シークすることができます。この時間は、一つのテーブルであるならば、データの増加と共にディスクアクセスの時間が少しずつ増加することになり、とても最適化するのは難しくなっていきます。これを最適化する方法は、データを 1個以上のディスクに分散する事です。

  * Disk reading/writing When the disk is at the correct position we need to read the data. With modern disks in 1999 one disk delivers something like 10-20Mb/s. This is easier to optimize than seeks because you can read in parallel from multiple disks.

  * CPU cycles ：データをメイン・メモリーの中に入れた(または既にメモリに存在している)場合に、結果を得るためには、それを処理する必要があります。メモリー容量よりも小さなテーブルを持っている場合、これは、制限の要因となります。小さいテーブルでは、スピードは、通常問題にはなりません。

  * Memory bandwidth ： CPU がキャッシュに収まらないようなデータを要求した場合、メイン・メモリーのバンド幅はボトルネックになります。これはほとんどのシステムで分かりにくいボトルネックとなりますが、誰かはそれを知っているべきです。

システム、コンパイル時、スタートパラメターのチューニング
============================

We start with the system level things since some of these decisions have to be made very early. In other cases a fast look at this part may suffice because it not that important for the big gains. However, it is always nice to have a feeling about how much one could gain by changing things at this level.

使うべき OS はとても重要です！ 複数の CPU を持つマシンでは、 Solaris (なぜなら、Solaris のスレッドはとても素晴らしく動作するから)、あるいは、Linux ( kernel 2.2 は良い SMP をサポートしているから) を使用すべきです。 32bit マシンの Linux では、2G bytes のファイルサイズの制限があります。 これは新しいファイルシステム (XFS) のリリース時になくなって欲しいものです。

Because we have not run MySQL in production on that many platforms we advice you to test your intended platform before choosing it, if possible.

Other tips:

  * 充分 RAM があるならば、全ての swap を外してもよいでしょう。いくつかのシステムでは、たとえメモリーが空いていても、 swap を使用する場合があります。

  * 外部のロックを避けるため、--skip-locking MySQL オプションを使用します。 Note that this will not impact MySQL's functionality as long as you only run one server. myisamchk を実行する前に、サーバーを止めることを忘れないでください。 On some system this switch is mandatory because the external locking does not work in any case.

     MIT スレッドでコンパイルする時は --skip-locking がデフォルトです。これは全てのプラットフォームで MIT スレッドが flock() を完全にサポートしていないためです。

     --skip-locking が使用できないただ一つの状態は、もしあなたが複数の MySQL サーバー (クライアントではない) を同じデータに対して走らせている場合です。 Or run myisamchk on the table without first flushing and locking the mysqld server tables first.

     たとえ --skip-locking を使用していても、 LOCK TABLES / UNLOCK TABLES の使用は可能です。

MySQL の速度に影響するコンパイルとリンク方法
-------------------------

次のテストの多くは Linux 上で MySQL ベンチマークで行われました。しかし、これらは他の OS についてもいくつかの指標を与えます。

-static でのリンク時に最速の実行形式を得ます。 TCP/IP の代わりに Unix ソケットをデータベースへの接続に使用することも、より良い性能を与えます。

Linux では、pgcc と -O6 でコンパイルした時に最速のコードを得られます。このオプションで sql_yacc.cc をコンパイルすると、gcc/pgcc は全ての関数をインラインにするために多くのメモリを必要とするので、200M のメモリが必要です。 libstdc++ ライブラリの増加を避けるためには、 MySQL の configure 時に CXX=gcc も設定すべきです。

より良いコンパイラー、そしてコンパイラーのオプションは、10-30% の速度の向上をもたらします。 これはあなた自身が MySQL をコンパイルする時に重要なことです！

Intel では、例えば pgcc か Cygnus CodeFusion compiler で最速となります。我々は 新しい Fujitsu コンパイラーでもテストしましたが、 MySQL を最適化オプションでコンパイルするには、まだ完全なバグ・フリーではありませんでした。

Here is a list of some mesurements that we have done:

  * pgcc を使用して -O6 で全てをコンパイルすると、 gcc 2.95.2 より古いバージョンでは、 mysqld サーバーは 11% 速くなります。

  * 動的リンク(-static) 無し)の場合、結果は 13% 遅くなります。 Note that you still can use a dynamic linked MySQL library. It is only the server that is critical for performance.

  * (localhost への接続に) Unix ソケットの代わりに TCP/IP を使用すると、結果は 7.5% 遅くなります。

  * SPARCstation 10 では、gcc 2.7.3 は Sun Pro C++ 4.2 より 13% 速くなります。

  * シングルプロセッサの Solaris 2.5.1 では、mit-pthreads は Solaris ネイティブスレッドより 8-12% 遅くなります。 With more load/CPUs the difference should get bigger.

TCX により配布されている MySQL-Linux 配布は pgcc でコンパイルされていますが、 but we had to go back to regular gcc because of a bug in pgcc that would generate the code that does not run on AMD. We will continue using gcc until that bug is resolved. In the meantime, if you have a non-AMD machine, you can get a faster binary by compiling with pgcc. The Linux binary is linked statically.

Disk の問題
--------

  * 前に述べたディスクシークが大きなボトルネックです。 この問題は、データが効果的にキャッシングが不可能になるほど、大きくなり始めるときに、だんだん明白になってきます。 For large databases, where you access data more or less randomly, you can count on that you will need at least one disk seek to read and a couple of disk seeks to write things. この問題を少なくするには、diskシーク時間の少ないディスクを使用します。

  * 利用できるディスクスピンドルの数を増やします(それによってディスクシークのオーバーヘッドは縮小します)。これは違うディスクにシンボリックリンクをはったり、ストライプを行うことで可能です。

     symbolic link の使用
          これは通常のデータディレクトリから、違うディスクへ、インデックスやデータファイルをシンボリック・リンクすることです。これは シーク と リード を速くします。 (もしそのディスクが他に使用されていなければ). See Symbolic links.

     Striping
          ストライピングは、複数のディスクに対して、まずデータの最初のブロックを 1番目の disk に書き、2番目のブロックを2つ目のdiskに書き、順次 N 番目 (N は disk の数) まで順に書いていきます。 これは、もしデータがストライプのサイズよりも小さければ、よりよいパフォーマンスを得ることが出来ます。ストライピングは、OS や ストライプのサイズにとても依存していることに注意してください。そのため、あなたのアプリケーションのベンチマークがストライプサイズによって変わるでしょう。 See Benchmarks.

          ストライピングのスピードの違いは、とても パラメターに依存しています。 Depending on how you set the striping parameters and number of disks you may get difference in orders of magnitude. Note that you have to choose to optimize for random or sequential access.

  * 信頼性のため、あなたは RAID 0+1 (striping + mirroring) を使用したいと思うかもしれません。 しかしこれは N 個のドライブのデータを収めるのに 2*N 個のドライブが必要となります。これはもし資金があるならば一番よい方法でしょう！ しかし、能率的にそれを取り扱うために、ボリューム・マネージメント・ソフトウェアに投資する必要があってもよいです。

  * A good option is to have semi-important data (that can be re-generated) on RAID 0 disk while store really important data (like host information and logs) on a RAID 0+1 or RAID N disks. RAID N can be a problem if you have many writes because of the time to update the parity bits.

  * データベースに使用しているファイルシステムの mount パラメターを変更しても良いでしょう。 一つの簡単な方法としては、noatime オプションでファイルシステムをマウントします。 これは inode にある最後にアクセスした時間の更新をスキップします。 これでいくらか ディスクシークを避けることができるでしょう。

データベースとテーブルにシンボリックリンクを使用する
..........................

テーブルとデータベースのファイルを MySQL のデータベースディレクトリーから違う場所に移動し、 それに対してシンボリックリンクを張ることができます。これは例えばディスク容量が少なくなって、データベースを移動したい場合にそうしたくなるでしょう。

MySQL が、テーブルがシンボリックリンクであることに気づいた場合、 symlink を解析し、代わりにその実体のテーブルを使用します。これは realpath() コールをサポートする全てのシステムで働きます（少なくとも Linux と Solaris は realpath() をサポートします！）。 realpath() をサポー トしないシステム上では、symlink とテーブルを同時に使用すべきでありません！ テーブルはテーブルの更新後に矛盾する事になるでしょう。

MySQL はデフォルトではデータベース同士のリンクをサポートしません。が、データベース間のシンボリックリンクを作成しない限り、これは正常に働くでしょう。 MySQL データディレクトリに db1 データベースがあるとして、仮に db2 を db1 のシンボリックリンクにしたとします:

     shell> cd /path/to/datadir
     shell> ln -s db1 db2

すると、db1 中の tbl_a テーブルは db2 の  tbl_a テーブルとして見えます。もしあるスレッドが db1.tbl_a を更新し、他のスレッドが db2.tbl_a を更新した場合、 問題が発生します。

こういった使用をどうしてもしたい場合、mysys/mf_format.c を以下のように変更します:

     if (!lstat(to,&stat_buff))  /* Check if it's a symbolic link */
         if (S_ISLNK(stat_buff.st_mode) && realpath(to,buff))

Change the code to this:

     if (realpath(to,buff))

サーバーパラメーターのチューニング
-----------------

mysqld サーバーが使用している現在のバッファサイズを次で得ることができます:

     shell> mysqld --help

この結果、全ての mysqld オプションと次のようなコンフィグ可能変数のリストを得られます。出力結果にはデフォルト値が含まれ、以下のように表示されます:

     Possible variables for option --set-variable (-O) are:
     back_log              current value: 5
     connect_timeout       current value: 5
     delayed_insert_timeout  current value: 300
     delayed_insert_limit  current value: 100
     delayed_queue_size    current value: 1000
     flush_time            current value: 0
     interactive_timeout   current value: 28800
     join_buffer_size      current value: 131072
     key_buffer_size       current value: 1048540
     lower_case_table_names  current value: 0
     long_query_time       current value: 10
     max_allowed_packet    current value: 1048576
     max_connections       current value: 100
     max_connect_errors    current value: 10
     max_delayed_threads   current value: 20
     max_heap_table_size   current value: 16777216
     max_join_size         current value: 4294967295
     max_sort_length       current value: 1024
     max_tmp_tables        current value: 32
     max_write_lock_count  current value: 4294967295
     net_buffer_length     current value: 16384
     query_buffer_size     current value: 0
     record_buffer         current value: 131072
     sort_buffer           current value: 2097116
     table_cache           current value: 64
     thread_concurrency    current value: 10
     tmp_table_size        current value: 1048576
     thread_stack          current value: 131072
     wait_timeout          current value: 28800

もし mysqld サーバーを走らせているなら、以下のコマンドでも変数の値を見ることができます:

     shell> mysqladmin variables

これらのオプションは以下のように決めてください。 buffer size, buffer length, stack size は byte 単位で与えます。これらの値の後ろに K や M を追加すると、キロバイト、メガバイトになります。例えば、16M は16メガバイトを示します。大文字小文字の区別はなく、 16M と 16m は同じ意味になります。

稼働中のサーバーの統計情報は SHOW STATUS で参照できます. See SHOW.

ansi_mode.
     もし mysqld が --ansi オプションで起動されているなら、ON. See Ansi mode.

back_log
     MySQL が持てる未解決の接続要求の数です。これは MySQL スレッドがものすごく多くの接続要求をとても短い時間に得た時に、働きます。接続のチェックと新しいスレッドの開始はメインスレッドにすこし時間 (しかしほんのわずか)がかかります。back_log は、MySQL が瞬間的に新しい要求への回答を停止する前に、この短い時間の間にスタックできる接続数です。短い期間に多くの接続を期待する場合にだけ、これを増加する必要があります。

     いいかえるなら、これは TCP/IP 接続の入力 listen キューのサイズです。オペレーティングシステムはこのキューの大きさを制限しています。 UNIX システムコール listen(2) のマニュアルページに、さらに詳細があります。この値を最大限にしたい場合、お使いのOSのドキュメントを見てください。 back_log をこのOSの制限値より多く取ってもは全く効果ありません。

thread_cache_size
     How many threads we should keep keep in a cache for reuse.  When a client disconnects the clients threads is put in the cache if there isn't more than thread_cache_size threads from before.  All new threads are first taken from the cache and only when the cache is empty a new thread is created.  This variable can be increased to improve performance if you have a lot of new connections (Normally this doesn't however give a notable performance improvement if you have a good thread implementation).

concurrent_inserts
     もし ON (これはデフォルトです) なら、MySQL は、 SELECT クエリが実行されている MyISAM テーブルに対して、同時に INSERT が使用できるようにします。このオプションは mysqld のオプションに --safe か --skip-new を指定することで  OFF にできます。

connect_timeout
     mysqld サーバーが接続パケットを待つ秒数。 (Bad handshake を返すまでの秒数)

delayed_insert_timeout
     どれぐらい INSERT DELAYED スレッドが INSERT 文を待つべきか。

delayed_insert_limit
     delayed_insert_limit 個のレコードを挿入した後、 INSERT DELAYED ハンドラーは待たされている SELECT 文がないかチェックします。 もしあるなら、挿入を続ける前にそれらの実行を許します。

delay_key_write
     もし enabled であれば(これがデフォルト)、MySQL は CREATE TABLE 文の DELAY_KEY_WRITE オプションを尊重します。 DELAY_KEY_WRITEオプションを指定されて作られたテーブルのキーバッファは、毎回のインデックスの更新にはフラッシュされず、ただテーブルが閉じられたときにだけフラッシュされます。 これはキーの書き出しを速くしますが、もしこれを使用するなら、全てのテーブルを myisamchk --fast --force で自動的に検査するようにすべきです。もし mysqld を --delay-key-write_for_all_tables オプション付きで起動した場合、これは、全てのテーブルが delay_key_write オプション指定されて作成されたものとして扱われる事に注意してください。このフラグは、mysqld を --skip-new や --safe-mode オプションで起動すれば無効にすることも出来ます。

delayed_queue_size
     What size queue (in rows) should be allocated for handling INSERT DELAYED.  If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.

flush_time
     これがもし、非ゼロにセットされたなら、毎 flush_time 秒ごとに全てのテーブルが閉じられます。 (リソースの解放とDiskへのsyncのために)

init_file
     サーバー起動時に、--init-file オプションに与えたファイルの名前です。このファイルには、サーバー起動時に実行したい SQL 文を書いておきます。

interactive_timeout
     The number of seconds the server waits for activity on an interactive connection before closing it.  インタラクティブ クライアントを作るには、 C API mysql_real_connect() に CLIENT_INTERACTIVE オプションをセットします。  See also wait_timeout.

join_buffer_size
     このバッファは(インデックス無しの)完全な結合に使用されます。それは2つのテーブル間の完全な結合ごとに1回割り当てられます。インデックスの追加ができない時、より速い完全な結合を得るために、これを増加してください。通常、速い結合を得る一番良い方法は、インデックスを追加することです。

key_buffer_size
     インデックス・ブロックはバッファされ、そして全てのスレッドに共有されます。 key_buffer_size はインデックス・ブロックのためのバッファ・サイズです。

     Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.  If you however make this too big (more than 50 % of your total memory?) your system may start to page and become REALLY slow. Remember that because MySQL does not cache data read, that you will have to leave some room for the OS filesystem cache.

     You can check the performance of the key buffer by doing show status and examine the variables Key_read_requests, Key_reads, Key_write_requests and Key_writes.  The Key_reads/Key_read_request ratio should normally be < 0.01. The Key_write/Key_write_requests is usually near 1 if you are using mostly updates/deletes but may be much smaller if you tend to do updates that affect a lot of rows at the same time or if you are using delay_key_write. See SHOW.

     To get even more speed when writing many rows at the same time use LOCK TABLES.  See LOCK TABLES.

lower_case_table_names
     Change all table names to lower case on disk.

long_query_time
     もしあるクエリがこの値(秒)より時間がかかれば、Slow_queries カウンターが増やされます。

max_allowed_packet
     一つのパケットの最大サイズ。メッセージバッファは net_buffer_length バイトに初期化されますが、 max_allowed_packetまで大きくすることができます。このデフォルト値は、大きなパケット、間違ったパケットをを受けるには小さい値です。大きな BLOB を使用している場合は、これを増加する必要があります。使用したい最大の BLOB と同じくらい大きくするべきです。

max_connections
     許される同時クライアントの数。これを増加する場合は、mysqld が持つファイルディスクリプタの数を増やす必要があるでしょう。後述のファイルデスクリプターの制限の説明を参照のこと。 See Too many connections.

max_connect_errors
     もしあるホストからの接続中断がこの値を以上になった場合、これ以後、そのホストからの接続を拒絶します。FLUSH HOSTS コマンドでホストの拒否を解除できます。

max_delayed_threads
     この値を超えて INSERT DELAYED を扱うスレッドを起動できません。もし全ての INSERT DELAYED スレッドが使用されていて、さらに新しいテーブルにデータを挿入しようとすると、そのレコードは DELAYED が与えられていない場合と同様に挿入されます。

max_join_size
     max_join_size より多いレコードを触るとエラーが返ります。長い時間をかけて百万行を返すような WHERE なしの結合を作成するようなユーザを持っている場合にこれを設定してください。

max_heap_table_size
     Don't allow creation of heap tables bigger than this.

max_sort_length
     BLOB または TEXT 項目上でソートする時に使用するバイト数。 (最初の max_sort_length バイトだけがそれぞれの値で使用でき、残りは無視されます)

max_tmp_tables
     (このオプションはまだなにも行いません). クライアントが同時にオープンできるテーブル数の最大値。

max_write_lock_count
     After this many write locks, allow some read locks to run in between.

net_buffer_length
     通信バッファがクエリ間でこのサイズにリセットされます。これは通常は変更すべきではありませんが、とても小さなメモリしかない場合は、これを期待されるクエリのサイズに設定してください。 ( これは、クライアントから送られてくるSQL文の長さ分あればいいでしょう。もし構文がこの値をこえた場合、バッファは自動的に大きくなります。ただし max_allowed_packet バイトまでです)

net_retry_count
     If a read on a communication port is interrupted, retry this many times before giving up.  This value should be quite high on FreeBSD as internal interrupts is sent to all threads.

record_buffer
     順序スキャンを行う各スレッドが、スキャンするテーブル毎に、このサイズのバッファを割り当てます。多くの順序スキャンを行う場合は、これを増加させてください。

query_buffer_size
     The initial allocation of the query buffer. If most of your queries are long (like when inserting blobs), you should increase this!

skip_show_databases
     これは、 PROCESS_PRIV 権限を持っていないユーザーが SHOW DATABASES する事を阻止します。 もし、他人のデータベースやテーブルを見ようとする人がいる事を、あなたが心配するならば、これはセキュリティを強化できます。

sort_buffer
     ソートを行う必要がある各スレッドがこのサイズのバッファを割り当てます。より速い ORDER BY または GROUP BY のためにはこれを増やしてください。 See Temporary files.

table_cache
     全てのスレッドについてのオープンテーブルの数。これを増加する場合は、 mysqldが要求するオープンファイルディスクリプタの数も増加することに注意しないといけません。 MySQL はユニークテーブル毎に2つのファイルディスクリプタを必要とします。後述のファイルデスクリプターの制限の説明を参照のこと。 You can check if you need to increase the table cache by checking the Opened_tables variable. See SHOW.  If this variable is big and you don't do FLUSH TABLES a lot (which just forces all tables to be closed and reopenend), then you should increase the value of this variable.

     テーブルキャッシュがどのように働くかはこちらを参照 Table cache.

tmp_table_size
     メモリー内の 一時テーブルがこの値を超えようとした場合、MySQL は自動的に、これを、disk ベースの MyISAM テーブルに変換します。多くの先進的な GROUP BY クエリを行う場合は、この tmp_table_size を増加してください。

thread_stack
     各スレッドのスタックの大きさ。crash-me によって検出される多くの制限がこれに依存します。デフォルトでは、通常のオペレーションに対して十分とってあります。 See Benchmarks.

wait_timeout
     サーバーがコネクションを閉じるまでにアクティブなコネクションを待つ秒数。 interactive_timeout も参照のこと。

MySQL はとてもスケーラブルなアルゴリズムを使用します。そのため通常はとても少ないメモリで動作し、またより良い性能を得るために MySQL に多くのメモリを与えることができます。

When tuning a MySQL server, the two most important variables to use are key_buffer_size and table_cache.  You should first feel confident that you have these right before trying to change any of the other variables.

多くのメモリ(>=256M)と多くのテーブルを持っていて、適度のクライアント数で最大性能を得たい場合、次のようなものを使用します:

     shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
                -O sort_buffer=4M -O record_buffer=1M &

If you have only 128M and only a few tables, but you still do a lot of sorting, you can use something like:

     shell> safe_mysqld -O key_buffer=16M -O sort_buffer=1M

多くの接続で少ないメモリしかない場合、次のようなものを使用します:

     shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
                -O record_buffer=100k &

or even:

     shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
                -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &

もしとても多くの接続があり、mysqld が各接続に対して少ないメモリーで動作するように設定されていれば、スワップの読み書きによるパフォーマンスの低下がおきます。もちろん十分なメモリーがあれば、全ての接続にたいして mysqld のパフォーマンス良くなります。

mysqld へのオプションを変更する場合、そのサーバのインスタンスにだけに有効であることに注意して下さい。

パラメータ変更の効果を見るには、このようにします:

     shell> mysqld -O key_buffer=32m --help

--help オプションは最後につけてください。その他のオプションを --help の後につけると、そのオプションは反映されません。

MySQL はどのようにテーブルのオープン & クローズを行なうか？
----------------------------------

table_cache , max_connections , max_tmp_tables はサーバーが開いた状態にしておく事が出来るファイルの最大数に影響します。もしこれらの変数のうちの一つ、あるいは複数を増加させるなら、あなたのオペレーティング・システムの、1 プロセスあたりに開かれるファイル・デスクリプタ の最大値を増やすことになるかもしれません。多くのシステムではこの制限を増やすことが可能です。これをどうやって行うかは、あなたの使用している OS のドキュメントを見てください。制限値の変更方法は、システムによってまちまちだからです。

table_cache は max_connections に関連します。例えば 200 のコネクションを同時に開けるなら、少なくとも 200 * n のテーブル・キャッシュが必要です。 ここで n は join におけるテーブルの最大数です。

オープンテーブルのキャッシュは最大で table_cache まで大きくなります(デフォルトは 64, mysqld のオプション -O table_cache=# で変更可能)。キャッシュが一杯になって、他のスレッドがテーブルのオープンを試みた時、または mysqladmin refresh mysqladmin flush-tables を使用した場合を除いて、テーブルはクローズされません。

キャッシュがいっぱいになった場合、サーバーは以下の処置を取ってキャッシュを使用できるように配置します：

  * 現在使われていないテーブルが解放されます。もっとも使用されていないテーブルからから順に。

  * もしキャッシュが一杯でテーブルを解放することが出来ず、さらに新しいテーブルのオープン要求がある場合、キャッシュは一時的な拡張を必要とします。

  * もしそのキャッシュが一時拡張に配置されていて、かつ、テーブルが使用状態から未使用状態に移行した場合、そのテーブルは閉じられ、キャッシュから解放されます。

テーブルは各同時アクセスに (再び) オープンされます。これは、同じテーブルで2つのスレッドが実行されている場合、または同じクエリで(AS で)テーブルを2回アクセスする場合、テーブルは2回オープンする必要があることを意味します。最初のテーブルのオープンは2つのファイル記述子を使用し、続くテーブルの各使用は1つだけのファイル記述子を使用します。

Drawbacks of creating large numbers of tables in the same database
------------------------------------------------------------------

もしたくさんのファイルが一つのディレクトリにある場合、オープン、クローズ、作成操作は遅くなるでしょう、 もし SELECT 文を多くのテーブルに対し実行した場合、テーブルキャッシュが一杯ならば、このオーバーヘッドは多くなるでしょう。なぜなら、それぞれのテーブルにつきオープンし、クローズしなくてはならないからです。このオーバーヘッドを緩和するには、テーブルキャッシュを大きくします。

何故そんなに多くのテーブルをオープンするのか？
-----------------------

mysqladmin status を実行すると、次のようなものが得られます:

     Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12

確かにたった6個しかテーブルがないのに、このような結果が出るので少々戸惑われるかもしれません。

MySQL はマルチスレッドなので、同じテーブルで一度に多くのクエリを持てます。同じファイル上で異なる状態を持つ2つのスレッドで、問題を最小化するため、同時に動作する各スレッドのためテーブルを再びオープンします。これはいくつかのメモリとデータファイルについての一つの拡張ファイル記述子を使用します。インデックスファイル記述子は全てのスレッド間で共有されます。

MySQL はどのようにメモリを使用するのか？
-----------------------

以下に mysqld サーバーがどのようにメモリーを使用するか、いくつか示します。サーバーに与える変数名は、サーバーのメモリーの使用方に関連した名前となっています。

  * キーバッファ (変数 key_buffer) は全てのスレッドで共有され、残りは必要時に割り当てられます。 See Server parameters.

  * 各接続はいくつかのスレッド空間を使用します；スタック (64K, 変数 thread_stack), 接続バッファ(variable net_buffer_length), 結果バッファ(variable net_buffer_length)。接続バッファと結果バッファは必要となった時、動的に最大 max_allowed_packet まで増えます。クエリが走っている時、そのクエリの文字のコピーが割り当てられます。

  * 全てのスレッドは同じベースメモリを共有します。

  * まだ memory-mapped を使用していません (圧縮テーブルは除きますが、これは別の話)。これは 4GB の 32bit メモリ空間は多くの大きなテーブルを扱うには小さいためです。 64bit アドレス空間を持つシステムを我々が手に入れた時、我々は mmemory-mapping を通常にサポートします。

  * テーブルを越えて順次スキャンを行なう各要求は、読み込みバッファを割り当てます (変数 record_buffer)

  * 全ての結合は1パスで行なわれ、多くの結合は一時テーブルを使用せずに行なわれます。多くの一時テーブルはメモリベース(HEAP)のテーブルです。大きなレコードサイズ (= 全フィールド長の合計) を持つ一時テーブルまたは、BLOB を含むテーブルはディスク上に置かれます。

     MySQL 3.23.2 以前での問題は、HEAP テーブルが tmp_table_size のサイズを越えると、エラー The table tbl_name is full が出ることです。将来我々は、必要時にメモリ (HEAP) テーブルをディスクベース (NISAM) テーブルに自動的に変更することにより、これを修正します。この問題を回避するため、mysqld への tmp_table_size オプションまたはクライアント側で SQL オプション SQL_BIG_TABLES で増加できます。 See SET OPTION. MySQL 3.20 では、一時テーブルの最大サイズは recordbuffer*16 でした。そのため、このバージョンを使用していると、 recordbuffer を追加する必要があります。 mysqld を --big-tables で開始することで、常に一時テーブルをディスク上に格納できます。しかしこれは多くの複雑なクエリの速度に影響します。

  * ほとんどのリクエストは、1,2個の一時ファイルとわずかなソートバッファへの割り当てを行います。 See Temporary files.

  * 変形と演算時に使用されるほとんど全てのメモリはローカルメモリストア内で行なわれます。小さな項目に必要とされるメモリオーバーヘッドはなく、通常の遅いメモリ割り当て/解放が回避されます。メモリは予期しない大きな文字列にだけ割り当てられます(これは malloc() と free() で行なわれます)。

  * 各インデックスファイルは一度オープンされ、データファイルは各同時実行スレッド毎に一度オープンされます。各同時スレッドには、テーブル構造、各フィールドの構造そして 3 * n のサイズのバッファが割り当てられます。 ( n は BLOB 型のフィールドの長さを含めない、一レコードの最大長です ) BLOB は 5 から 8 バイト + BLOB データの長さを使用します。

  * BLOB を持つ各テーブルでは、より大きな BLOB の読み込みでバッファは動的に拡大されます。テーブルのスキャンをする場合、割り当てられたバッファは最も大きい BLOB と同じ大きさになります。

  * 全ての使用されているテーブルのテーブルハンドラーはキャッシュ内に保存され、 FIFO として管理されます。通常、キャッシュは 64 個のテーブルです。テーブルが 2 つの実行しているスレッドで同時に使用される場合、キャッシュ内にテーブルの 2 つのエントリがあります。 See Table cache.

  * mysqladmin refresh は使用されていない全てのテーブルをクローズし、使用されている全てのテーブルを、実行中スレッドが終った時にクローズするようにマークします。これは多くの使用メモリを解放するのに有効です。全てのログファイルもクローズと再オープンされます。

mysqld 実行時、ps や他のプログラムは、それが多くのメモリを使用していると報告するでしょう。これは異なったメモリアドレス上のスレッドスタックによって発生します。例えば、Solaris ps はスタック間の未使用メモリを使用メモリとして計算します。'swap -s' で有効なスワップをチェックすることでこれを確かめられます。我々は市販のメモリリーク検出プログラムで mysqld をテストしました。そのため、メモリリークは全くありません。

MySQL はどのようにテーブルをロックするか
-----------------------

MySQL の全てのロックはデッドロックフリーです。これは、常にクエリ開始時に一度ロックを必要とする全てを要求し、常に同じ順でテーブルをロックすることで管理されます。

MySQL が使用する WRITE ロックは次のように働きます:

  * テーブル上にロックがない場合 write ロックを置きます。

  * そうでなければ write ロックキューにロックを置きます。

MySQL の READ ロックは次のように動きます:

  * テーブル上に write ロックがない場合 read ロックを置きます。

  * そうでなければ read ロックキューにロックを置きます。

ロックが解放されたとき、最初に write ロックキュー内のスレッドに、その後 read ロックキュー内のスレッドにロックを与えます。

これは、同じテーブルで多くの更新をする場合、SELECT 構文は update がなくなるまで待たされることを意味します。

同じテーブルで多くの INSERT と多くの SELECT を行う場合、これを解決するには、他のテーブルに行を挿入して、たまに、その一時テーブルから全てのレコードをもう一方のテーブルに update します。

これは次のコードで行えます:

     mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
     mysql> insert into real_table select * from insert_table;
     mysql> delete from insert_table;
     mysql> UNLOCK TABLES;

決まりきった検索に優先権を与えるため、INSERT 構文で LOW_PRIORITY か HIGH_PRIORITY オプションが使用できます。 See INSERT.

一つのキューだけを使用するように mysys/thr_lock.c 内のロックコードを変更することもできます。この場合、いくつかのアプリケーションのために、 write ロックは read ロックと同じ優先順位にします。

テーブル・ロッキングの問題
-------------

MySQL のテーブル・ロッキングのコードはデッドロック・フリーです。

MySQL はとても速いロックスピードを得るために、 (レコードのロックやフィールドのロックの代わりに) テーブルのロックを使用します。大きなテーブルには、 テーブルのロックはレコードのロックよりはるかに良いですが、いくつかの落とし穴があります。

MySQL 3.23.7 以上では、あるスレッドが MyISAM テーブルを読んでいる最中に、同じテーブルにレコードを挿入する事ができます。これは現在、削除がない場合にのみ動きます。

テーブルのロックはたくさんのスレッドが同時にあるテーブルから読み出すのを可能にしますが、もしあるスレッドがあるテーブルに対し書込み要求を出す場合、それはまず最初に排他的なアクセスを得なければなりません. その更新の間、更新が完了するまで、この特定のテーブルにアクセスしようとする他の全てのスレッドが待たされることになります。

通常データベースの更新は SELECT よりも重要とされるため、テーブルを更新する全てのスレッドが、テーブルから情報を検索するスレッドよりも高い優先順位を持ちます。 これは ある特定のテーブルに対して、多くの重いクエリが発行された場合に、 更新が不完全に終わらないことを確実にするためです。

MySQL 3.23.7 から、max_write_lock_count 変数が使用できます。これは、一つのテーブルに対して、指定された回数だけ INSERT が行われた後に、 SELECT を発行するようにします。

この1つの主な問題が以下です：

  * あるクライアントが実行に長い時間のかかる SELECT を発行。

  * その後に、他のクライアントが、使用されているテーブルに対し UPDATE を発行；このクライアントは先の SELECT が完了するまで待ちます

  * さらに他のクライアントが同じテーブルに対して SELECT 構文を発行； UPDATE は SELECT よりも高い優先度を持つので、この SELECT は先の UPDATE が完了するまで待ちます。これは一番最初の SELECT が 終了するまで待たされます！

この問題のいくつかの可能な解決は以下の通りです：

  * SELECT 構文を速く実行できるように試みます； これを行うにあたり、いくつかのサマリーテーブルを作成しなければならないかもしれません.

  * mysqld を --low-priority-updates オプションで起動。これは全てのあるテーブルを更新する構文に対して、 SELECT 構文よりも低い優先度を与えます。 この場合、前述のシナリオ中の最後の SELECT 構文は INSERT 構文が完了する前に実行されます。

  * LOW_PRIORITY 属性指定を用いて、 INSERT,UPDATE,DELETE 構文に低い優先度を与えることも出来ます。

  * Start mysqld with a low value for max_write_lock_count to give READ locks after a certain number of WRITE locks.

  * SQL コマンドの SET SQL_LOW_PRIORITY_UPDATES=1 を使用して、ある特定のスレッドからの全ての更新を、低い優先度に指定する事ができます。 See SET OPTION.

  * HIGH_PRIORITY 属性を用いて、特定の SELECT がとても重要であると指定することが可能です。. See SELECT.

  * もし INSERT と SELECT をあわせて使用した場合に問題が起きた場合、新しい MyISAM テーブルに切り替えます。 これは SELECT と INSERT を同時に行えます。

  * もし INSERT と SELECT 構文を主に混在させるのなら、 INSERT の DELAYED 属性指定はこの問題を解決させるでしょう。 See INSERT.

  * もし SELECT と DELETE で問題があるなら、 DELETE の LIMIT オプションが助けになるでしょう。 See DELETE.

可能な限りデータを小さくする
==============

One of the most basic optimization is to get your data (and indexes) to take as little space on the disk (and in memory) as possible. This can give huge improvements because disk reads are faster and normally less main memory will be used. Indexing also takes less resources if done on smaller columns.

MySQL supports a lot of different table types and row formats. Choosing the right table format may give you a big performance gain. See Table types.

以下に挙げるテクニックを使用すれば、テーブルでのパフォーマンスの向上、保存領域の縮小化が可能でしょう：

  * 可能ならば、一番小さな型を使用します。 MySQL はディスクとメモリーを節約する多くの型を持っています。

  * より小さな整数型を可能ならば使用します。 例えば、 MEDIUMINT は INT より良いでしょう。

  * 可能ならフィールドを NOT NULL に定義してください。これは全てをより速くし、各フィールド毎に1ビットを節約します。 Note that if you really need NULL in your application you should definitely use it. Just avoid haveing it on all columns by default.

  * 可変長のフィールド (VARCHAR, TEXT, BLOB) を持たない場合は、固定サイズレコード形式が使用されます。これはかなり速いです。しかしあいにくいくらかの領域を浪費します。 See MyISAM table formats.

  * それぞれのテーブルは可能な限り短いプライマリ・インデックスを持つべきです。これは１レコードを一意にし、効率的にします。

  * それぞれのテーブルについて、どのテーブルの形式を使用するかを決めます。 See Table types.

  * 本当に必要な物にだけインデックスを作成します。インデックスは検索には良いですが、より速く保存したい場合には良くありません。もしテーブルをフィールドの組み合わせでサーチすることがほとんどであれば、それらにインデックスを作成します。 最初のインデックスの部分は、もっとも使用されるフィールドにすべきです。 If you are ALWAYS using many columns you should use the column with more duplicates first to get better compression of the index.

  * もしインデックスが頭からの何文字かで一意性を持っているなら、この部分にだけインデックスを張る方が良いでしょう。 MySQL は文字列フィールドの一部分に対してのインデックスをサポートします。短いインデックスは、ディスクスペースを節約するだけでなく、インデックスのキャッシュに収まりやすくなることにより、ディスク・シークも少なくなるので、速くなります。 See Server parameters.

  * いくつかの状況下で、とてもよく走査されるテーブルを２つに分割することは、利益になることがあります。 This is especially true if it is a dynamic format table and it is possible to use a smaller static format table that can be used to find the relevant rows when scanning the table.

MySQL はどのようにインデックスを使用するか？
=========================

Indexes are used to find rows with a specific value of one column fast. インデックスがない場合、MySQL は、そのレコードが見つかるまで、最初のレコードからテーブルをなめていきます。 大きなテーブルでは多くの手間がかかります。 もし問い合わせの中にインデックスを持ったフィールドがある場合、MySQL は全てのデータをみることなく、データの途中の位置を速く得ることができます。 もしあるテーブルが1000レコード持っていたとすると、順番に頭からなめていくことに比べて、これは少なくとも100倍速いことになります。 Note that is you need to access almost all 1000 rows it is faster to read sequentially because we then avoid disk seeks.

全ての MySQL インデックス, PRIMARY, UNIQUE そして INDEX() は B tree に格納されます。文字列は自動的に始めと終りの空白が圧縮されます。 See CREATE INDEX.

Indexes are used to:

  * WHERE節にマッチした行の素早い検索

  * join を実行したときの他のテーブルからの行の検索

  * 与えられたフィールドの MAX() や MIN() 値の割り出し

  * テーブルをソートかグループ化する場合で、ソート(グループ化)が一番左(接頭部)のキーを使用して行われる場合(例えば ORDER BY key_part_1,key_part_2 )。もし DESC 指定があれば、全てのキーは逆順に読まれます。

     The index can also be used even if the ORDER BY doesn't match the index exactly, as long as all the not used index parts and all the extra are ORDER BY columns are constants in the WHERE clause. The following queries will use the index to resolve the ORDER BY part.

          SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3;
          SELECT * FROM foo WHERE column=constant ORDER BY column, key_part1;
          SELECT * FROM foo WHERE key_part1=const GROUP BY key_part2;

  * データファイルを参照することなく値を検索する場合。もし使用する全てのフィールドが数値でかつ、一番左から(接頭部から)キーを形成する場合、値はインデックスツリーから検索され、これはとても速くなります。

以下のような SELECT 文を発行したとします：

     mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

もし col1 と col2 に複数フィールドインデックスが定義されている場合、すぐに思ったとおりの結果が得られます。 If separate single-column indexes exist on col1 and col2, the optimizer tries to find the most restrictive index by deciding which index will find fewer rows and using that index to fetch the rows.

もしテーブルが複数フィールドインデックスを持つなら、インデックスの接頭部一番左の部分がレコードを見つけるための最適化に使用されます。例えば、3つのフィールド (col1,col2,col3) に対して一つのインデックスを持っていたとします。すると、これは (col1), (col1,col2) , (col1,col2,col3) でインデックスがサーチされます。

もし一番左に指定しているフィールドがインデックスを作成していないなら、 MySQL は部分的なインデックスを使用しません。

以下のような SELECT 文を発行したとします：

     mysql> SELECT * FROM tbl_name WHERE col1=val1;
     mysql> SELECT * FROM tbl_name WHERE col2=val2;
     mysql> SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

もしインデックスが (col1,col2,col3) にあるならば、上に示した最初のクエリだけがインデックスを使用します。二番目三番目のクエリはインデックスを持つフィールドを発動しますが、 (col2) と (col2,col3) は、(col1,col2,col3) の接頭部一番左に指定されていません。

MySQL は、もし  LIKE がワイルドカードから始まっていなくて、ある種固定された文字で始まっているなら、 LIKE の評価にインデックスを使用します。例えば、以下の SELECT 文はインデックスを使用します:

     mysql> select * from tbl_name where key_col LIKE "Patrick%";
     mysql> select * from tbl_name where key_col LIKE "Pat%_ck%";

一つ目の文は、"Patrick" <= key_col < "Patricl" となるレコードだけ、考慮されます。二つ目の文は、"Pat" <= key_col < "Pau" となるレコードだけ、考慮されます。

以下の SELECT 文はインデックスを使用しません:

     mysql> select * from tbl_name where key_col LIKE "%Patrick%";
     mysql> select * from tbl_name where key_col LIKE other_col;

最初の文は、LIKE がワイルドカード文字で始まっています。二つ目の文は、LIKE が定数ではありません。

Searching using column_name IS NULL will use indexes if column_name is an index.

MySQL は通常、一番少ないレコード数を見つけるインデックスを使用します。インデックスは、以下に示す演算子を用いて比較できるフィールドに対して、使用されます： =, >, >=, <, <=, BETWEEN そして 'something%' の様に頭にワイルドカードがない LIKE。

WHERE 節内の全ての AND にかからないインデックスは、全くクエリの最適化に使用されません。 In other words:  To be able to use an index, a prefix of the index must be used in every AND group.

以下の WHERE 節はインデックスを使用します：

     ... WHERE index_part1=1 AND index_part2=2 AND other_column=3
     ... WHERE index=1 OR A=10 AND index=2      /* index = 1 OR index = 2 */
     ... WHERE index_part1='hello' AND index_part_3=5
               /* optimized like "index_part1='hello'" */
     ... WHERE index1=1 and index2=2 or index1=3 and index3=3;
               /* Can use index on index1 but not on index2 or index 3 */

以下の WHERE 節はインデックスを使用しません：

     ... WHERE index_part2=1 AND index_part3=2  /* index_part_1 is not used */
     ... WHERE index=1 OR A=10                  /* Index is not used in both AND parts */
     ... WHERE index_part1=1 OR index_part2=10  /* No index spans all rows */

データをアクセス・更新するクエリの速度
===================

最初に、全てのクエリに影響する一つの事柄をのべます：より複雑な権限の設定を行うと、オーバーヘッドが多くなります。

もしあなたがいかなる GRANT 文も行っていなければ、 MySQL はパーミッションの検査を少ししか最適化しないでしょう。 So if you have a very high volume it may be worth the time to avoid grants. Otherwise more permission check results in a larger overhead.

もし MySQL 関数のあるものが確実に問題を引き起こしているのならば、常に MySQL クライアント側は以下のようになります：

     mysql> select benchmark(1000000,1+1);
     +------------------------+
     | benchmark(1000000,1+1) |
     +------------------------+
     |                      0 |
     +------------------------+
     1 row in set (0.32 sec)

上の例では MySQL は 1,000,000 + 式を 0.32 秒で実行できています (たんなる PentiumII 400MHz マシンで)。

全ての MySQL 関数は最適化されていますが、いくつかは例外があるかもしれません。 benchmark(loop_count,expression)はあなたのクエリの問題を見つけるためのとてもよいツールです。

クエリの性能評価
--------

ほとんどの場合、ディスク・シークを数えることでだいたいのパフォーマンスを予測できます。小さなテーブルでは、通常、1回のディスク・シークでレコードを見つけれるでしょう (インデックスがたぶんキャッシュされるので)。 大きなテーブルでは、おおよその予測として、(B++ ツリーインデックスを使用している場合)、 log(row_count) / log(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1 シーク、1レコードを見つけるのに必要となるでしょう。

MySQL では、インデックス・ブロックは通常 1024 バイトで、データ・ポインターは通常 4 バイトです。 これは、インデックス長が 3 (medium integer) 、データが 500,000 レコードあるテーブルでは、 log(500,000)/log(1024/3*2/(3+4)) + 1 = 4 シークとなります。

As the above index would require about 500,000 * 7 * 3/2 = 5.2M, (assuming that the index buffers are filled to 2/3 (which is typical) ) you will probably have much of the index in memory and you will probably only need 1-2 calls to read data from the OS to find the row.

書き込み時には、上の場合、新しいインデックスを書き込める場所を探し出すのに、4 シークかかり、さらに、通常、インデックスを更新し、レコードを書くのに 2 シーク必要です。

Note that the above doesn't mean that your application will slowly degenerate by N log N!  As long as everything is cached by the OS or SQL server things will only go marginally slower while the table gets bigger. After the data gets too big to be cached, things will start to go much slower until your applications is only bound by disk-seeks (which increase by N log N). To avoid this, increase the index cache as the data grows. See Server parameters.

SELECT クエリの速度
-------------

通常、遅い SELECT ... WHERE を速くするには、まず最初にインデックスがあるかどうかをチェックします。See MySQL indexes. 違うテーブルを参照する場合には、普通はインデックスをともなうべきです。 EXPLAIN コマンドを使用すれば、SELECT でどのインデックスが使用されているか確認できます。 See EXPLAIN.

Some general tips:

  * To help MySQL optimize queries better, run myisamchk --analyze on a table after it has been loaded with relevant data. This updates a value for each index part that indicates the average number of rows that have the same value.  (For unique indexes, this is always 1, of course.).  MySQL will use this to decide which index to choose when you connect two tables with 'a non-constant expression'. You can check the result from the analyze run by doing SHOW INDEX FROM table_name and examining the Cardinality column.

  * インデックスとデータをインデックス順に従ってソートするには、 myisamchk --sort-index --sort-records=1 を使用します (もし １番目のインデックス順にソートするなら)。 If you have a unique index from which you want to read all records in order according to that index, this is a good way to make that faster. しかし、このソート方法は最適状態では書かれず、また大きなテーブルでは多くの時間がかかることに注意してください！

MySQL はどのように WHERE 節を最適化するか？
----------------------------

WHERE の最適化は、WHERE がほとんど SELECT で使用されるため、 SELECT に置かれています。 しかし、同じ最適化は DELETE や UPDATE 文でも使用されます。

このセクションの最適化の説明はまだ不十分です。なぜなら、 MySQL はとても多くの最適化を行っており、それら全てについての説明を書ける時間が、我々はとれません。

MySQLによる最適化のいくつかを以下に示します:

  * 括弧の除去 (全ての不必要な括弧は削除されます):

             ((a AND b) AND c OR (((a AND b) AND (c AND d))))
          -> (a AND b AND c) OR (a AND b AND c AND d)

  * 定数の保持:

             (a<b AND b=c) AND a=5
          -> b>5 AND b=c AND a=5

  * 定数条件の除去 (定数保持のために必要とされます):

             (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
          -> B=5 OR B=6

  * インデックスに使用される全ての表現は一度だけ評価されます。

  * 一つのテーブル上の WHERE がない CONST(*) は、テーブルから直接取り出されます。これはまた同じ条件下での任意の NOT NULL 表現のためにも行われます。

  * 不当な定数表現は早く検出されます。 MySQL は不可能な  SELECT 構文を素早く見つけ、0 行を結果として返します。

  * GROUP BY または group 関数 (COUNT(), MIN()...) を使用しない場合は、 HAVING は WHERE とマージされます。

  * 各サブ結合についての速い WHERE 評価を得るために、また、可能な限り早くレコードをスキップするために、各サブ結合についてより簡単な WHERE が構築されます。

  * 全ての定数テーブルをクエリー中の他のテーブルより先に読みます。定数テーブルは次です:

       - 0 または 1 行のテーブル。

       - WHERE 節で UNIQUE インデックスや PRIMARY KEY が使用されたテーブルで、かつ、全てのインデックスが定数式で使用されていて、かつ、インデックスのパートが NOT NULL で定義されているテーブル。

     以下のテーブルのように定数だけを使用するテーブル:

          mysql> SELECT * FROM t WHERE primary_key=1;
          mysql> SELECT * FROM t1,t2
                     WHERE t1.primary_key=1 AND t2.primary_key=t1.id;

  * テーブルを結合するために最良の結合の組合せを見つけます。全ての可能性を試して 。 ORDER BY または GROUP 内の全てのフィールドが同じテーブルの場合は、このテーブルは結合時に最初に優先されます。

  * ORDER BY 節と GROUP BY 節がある場合、または ORDER BY か GROUP BY が結合キュー内の最初のテーブルではない他のテーブルからの項目を含む場合、一時テーブルが生成されます。

  * もし SQL_SMALL_RESULT を使用するなら, MySQL はメモリー内の一次テーブルを使用します

  * DISTINCT は、全てのフィールドに対する GROUP BY に変換されるため、 ORDER BY と合わした DISTINCT は多くの場合で一時テーブルが必要になります。

  * 各テーブルのインデックスはクエリされ、得られる行の 30% 未満の幅しかない最良のインデックスが使用されます。そのようなインデックスが見つけられない場合、素早いテーブルの走査(quick table scan)が使用されます。

  * 同じように、MySQL はデータファイルを等しく調べはしないインデックスからレコードを読むことが可能です。もし全てのフィールドが数値型のインデックスなら、インデックスツリーだけがクエリの解決に使用されます。

  * 各レコードが出力される前に、HAVING 節に適合するものをスキップします。

以下はとても速いクエリの例です:

     mysql> SELECT COUNT(*) FROM tbl_name;
     mysql> SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
     mysql> SELECT MAX(key_part2) FROM tbl_name
                WHERE key_part_1=constant;
     mysql> SELECT ... FROM tbl_name
                ORDER BY key_part1,key_part2,... LIMIT 10;
     mysql> SELECT ... FROM tbl_name
                ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;

以下のクエリはインデックスツリーのみを使用します(インデックス化されているフィールドは数値型と仮定します)：

     mysql> SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
     mysql> SELECT COUNT(*) FROM tbl_name
                WHERE key_part1=val1 AND key_part2=val2;
     mysql> SELECT key_part2 FROM tbl_name GROUP BY key_part1;

以下のクエリは、ソートされた行の検索にインデックスを使用します：

     mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,...
     mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,...

MySQL はどのように LEFT JOIN を最適化するか？
-------------------------------

A LEFT JOIN B は MySQL に以下のように組みこまれています：

  * The table B is set to be dependent on table A and all tables that A is dependent on.

  * テーブル A が LEFT JOIN 条件中に使用される全てのテーブル（ただし B は除く）に依存すると、セットされます。

  * 全ての LEFT JOIN 条件が WHERE 節に移動されます。

  * All standard join optimizations are done, with the exception that a table is always read after all tables it is dependent on.  If there is a circular dependence then MySQL will issue an error.

  * 全ての WHERE 節の最適化が行われます。

  * WHERE 節にマッチするレコードが A にあり、 LEFT JOIN 条件にマッチするレコードが B にない場合、全てのフィールドが NULL にセットされた B のレコードが作成されます。

  * If you use LEFT JOIN to find rows that doesn't exist in some table and you have the following test: column_name IS NULL in the WHERE part, where column_name is a column that is declared as NOT NULL, then MySQL will stop searching after more rows (for a particular key combination) after it has found one row that matches the LEFT JOIN condition.

The table read order forced by LEFT JOIN and STRAIGHT JOIN will help the join optimizer (which calculates in which order tables should be joined) to do its work much more quickly as there are fewer table permutations to check.

Note that the above means that if you do a query of type:

     SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key

Then MySQL will do a full scan on b as the LEFT JOIN will force it to be read before d.

The fix in this case is to change the query to:

     SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key

MySQL はどのように LIMIT を最適化するか？
---------------------------

In some cases MySQL will handle the query differently when you are using LIMIT # and not using HAVING:

  * もし LIMIT を使用して限定した数だけ select を行うなら、 MySQL は、ある場合、テーブルを全て走査するよりも、インデックスを使用しようとします。

  * もし LIMIT # を ORDER BY と共に使用するなら, MySQL は最初の # 行を見つけたらすぐに、全テーブルのソートは行わずに、ソートを終わらせます。

  * LIMIT # を DISTINCT と共に使用するなら, MySQL は # 個の一意なレコードを見つけた時点で終わります。

  * In some cases a GROUP BY can be resolved by reading the key in order (or do a sort on the key) and then calculate summaries until the key value changes.  In this case LIMIT # will not calculate any unnecessary GROUP BY's.

  * MySQL は、最初の # 行をクライアントに送ったあと直に、クエリを中断します。

  * LIMIT 0 は常に素早く空の結果を返します。これはクエリのチェックや結果として得られるフィールドの型を得るために利用できます。

  * 一時テーブルの大きさは、クエリを解決するためにどれぐらいのスペースがいるかを計算するのに、LIMIT # を使用します。

INSERT クエリの速度
-------------

レコードを挿入する時間はおおよそ次からなります:

  * 接続:                    (3)

  * クエリをサーバへ送信:    (2)

  * クエリの解析:            (2)

  * レコードの挿入:          (1 x size of record)

  * インデックスの挿入:      (1 x number of indexes)

  * クローズ:                (1)

ここで (数字) は比例時間です。これは、テーブルのオープンにかかる初期オーバーヘッド(これは同時に動作する各クエリ毎に1回行なわれます)は考慮されていません。

テーブルのサイズはインデックスの挿入を N log N で遅くします (B-tree)。

INSERT を速くするいくつかの方法：

  * もし同じクライアントから多くのレコードを同時にインサートするなら、複数の値が書ける INSERT 文を使用します。 これは個々に INSERT 文を発行する場合に比べて、とても速くなります。

  * もし違うクライアントから多くのレコードを同時にインサートするなら、 INSERT DELAYED 文の使用で、より速くなるでしょう。 See INSERT.

  * MyISAM では、複数の SELECT が走っているテーブルに対して、同時に、レコードを挿入できます。 ただしそのテーブルに対してレコードの削除がない場合に。

  * テキストファイルからテーブルにデータをいれる場合は、 LOAD DATA INFILE を使用します。 これはたくさんの INSERT 文の発行に比べて通常 20倍 程度速くなります see LOAD DATA.

  * テーブルが多くのインデックスを持っている場合、ある方法で、 LOAD DATA INFILE の実行を速くすることが可能です。以下の手順で行います：

      1. Optionally create the table with CREATE TABLE. For example using mysql or Perl-DBI.

      2. FLUSH TABLES の実行。 あるいは mysqladmin flush-tables コマンドの実行。

      3. myisamchk --keys-used=0 -rq /path/to/db/tbl_name の使用。これは指定されたテーブルから全てのインデックスを削除します。

      4. そのテーブルに LOAD DATA INFILE を使用してデータを入れます. これはいかなるインデックスも更新しないでしょうし、そのため、速くもなるでしょう。

      5. もし myisampack をお持ちで、テーブルを圧縮したいなら、 myisampack を実行します. See Compressed format.

      6. myisamchk -r -q /path/to/db/tbl_name でインデックスを再構築. これは disk に書き込む前にインデックスをメモリに作成します。これは多くのディスクシークを避けることが出来るのでとても速くなります。でき上がったインデックスツリーは、バランスのよいものになります。

      7. FLUSH TABLES の実行。 あるいは mysqladmin flush-tables コマンドの実行。

     この手順は、将来の MySQL の LOAD DATA INFILE に組み込むかもしれません。

  * テーブルをロックすることで、挿入を速くすることも可能です：

          mysql> LOCK TABLES a WRITE;
          mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33);
          mysql> INSERT INTO a VALUES (8,26),(6,29);
          mysql> UNLOCK TABLES;

     主な速度差は、全ての INSERT 構文でインデックスバッファが一度だけディスクにフラッシュされることです。通常は  INSERT 構文があるのと同じくらい多くのインデックスバッファフラッシュがあります。単一構文の全てのレコードは、ロックなしで挿入できます。

     ロックも複数接続テストの合計時間を低くしますが、いくつかのスレッドの最大待ち時間は上がります(ロックを待っているから)。例えば:

          thread 1 does 1000 inserts
          thread 2, 3, and 4 does 1 insert
          thread 5 does 1000 inserts

     ロックを使用しない場合、2, 3 そして 4 は 1 と 5 の前に終ります。ロックを使用する場合、2,3,4 は 1 や 5 の前に終わることはおそらくありませんが、合計時間は約 40 % 速くなります。

     INSERT, UPDATE , DELETE は、 MySQL ではとても速いので、 1 行で約 5 つ以上、値を 挿入・更新 をする操作に対して、ロックを追加すれば、全般的により良い性能が得られます。とても多い insert を行なう場合、他のスレッドにそのロックしたテーブルへのアクセスを与えるために 、だいたい 1000 レコードごとに一度、UNLOCK TABLES した後に LOCK TABLES を行います。 これでもまだ良い性能が得られます。

     もちろん LOAD DATA INFILE はとても速いです。

LOAD DATA INFILE と INSERT を共に速くするためには、キーバッファを増やします。 See Server parameters.

UPDATE クエリの速度
-------------

UPDATE クエリは SELECT クエリのように最適化されますが、書き込みのオーバーヘッドが加わります。書き込み速度は、更新されるデータの大きさ、更新されるインデックス数に依ります。 変更されないインデックスは更新されません。

Also another way to get fast updates is to delay updates and then do many updates in a row later. 一文で多くの更新を行えば、もしテーブルがロックされていれば、一文で一個づつ更新するよりも、とても速くなります。

Note that, with dynamic record format, updating a record to a longer total length may split the record.  So if you do this often it is very important to OPTIMIZE TABLE sometimes. See OPTIMIZE TABLE.

DELETE クエリの速度
-------------

1レコードを削除する時間は、ちょうどインデックスの数に比例します。より速くレコードを削除したいなら、インデックス・キャッシュを増やします。 See Server parameters.

テーブル中からレコードの大きな部分を消すよりも、全てのレコードを消すほうが、とても速いです。

最適化に関するその他の助言
=============

Unsorted tips for faster systems:

  * コネクションオーバーヘッドを避けるために、データベースに対して、逐次コネクションを落とさないように、常に接続を保ちます。 If you can't use persistent connections and you are doing a lot of new connections to the database, you may want to change the value of the thread_cache_size variable. See Server parameters.

  * あなたのクエリがテーブルのインデックスを使用しているか、いつもチェックします。 MySQL では EXPLAIN コマンドでこれが行えれます。 See Explain (manual).

  * たくさん変更されるようなテーブルに対して、複雑な SELECT クエリを避けるように試みます。 これはテーブル・ロックの問題を避けるためです。

  * 新しい MyISAM テーブルでは、あるテーブルにレコードが挿入(削除は無しで) されている最中に、同時に、同じテーブルからデータを読むことが可能です。これがあなたにとって重要項目であるなら、レコードの削除の必要のない方法や、多くのレコードを削除した後に OPTIMIZE TABLE を実行することを、考慮すべきです。

  * In some cases it may make sense to introduce a column that is 'hashed' based on information from other columns. If this column is short and reasonably unique it may be much faster than a big index on many columns. In MySQL its very easy to use this extra column: SELECT * from table where hash='calculated hash on col1 and col2' and col_1='constant' and col_2='constant' and ..

  * 多くの変更がなされるテーブルに対しては、全ての VARCHAR や BLOB フィールドを避けるように試みるべきです。 You will get dynamic row length as soon as you are using a single VARCHAR or BLOB columns. See Table types.

  * 通常、あるテーブルを違うテーブルに分けることは、レコードが大きくなるために役立ちません。レコードにアクセスする際、そのレコードの最初のバイトを見つけるためのディスク・シークが、一番かかります。 After finding the data most new disks can read the whole row fast enough for most applications. The only cases it really matters to split up a table is if its a dynamic row size table (see above) that you can change to a fixed row size. Or if you very often need to scan the table and don't need most of the columns. See Table types.

  * もし、多くのレコードからの情報を元にした計算(あるもののカウントとか)をしょっちゅう行う必要があるなら、新しいテーブルを用意し、逐次カウンターを更新した方が多分良いでしょう。 UPDATE table set count=count+1 where index_column=constant の更新はとても速いです！

     これは、MySQL のようなテーブル・ロッキング (multiple readers / single writers)をもつデータベースを使う上で、本当に重要なことです。 This will also give better performance with most databases as the row locking manager in this case will have less to do.

  * もしたくさんの大きなテーブルから統計を収集する必要があるなら、全テーブルを走査する代わりに、サマリーテーブルを使用します。 Maintaing the summarys should be much faster than trying to do statistics 'live'. It's much faster to re-generate new summary tables from the logs when things changes (depending on business decisions) than to have to change the running application!

  * If possible one should classify reports as 'live' or 'statistical', where data needed for statistical reports are only generated based on summary tables that are generated from the actual data.

  * フィールドにはデフォルト値があるという事を利用して下さい。値がデフォルトとは違う場合に限り、値を挿入します。これは MySQL が必要とする分析を少なくし、インサートの速度が向上します。

  * ある場合では、BLOB にデータをパックして保存するのが便利です。この場合、BLOB に入れた値を パック・アンパック するためのコードをあなたのアプリケーションに組み込まなくてはなりません。しかしこれは、多くのアクセスを抑制するでしょう。これは、静的(固定長)テーブル構造に適しないデータを持っている場合に実用になります。

  * 通常、あなたは全てのデータを冗長の無いように(データベース理論で第３正規形 , 3rd Normal Form , 3NF と呼ばれる) しようとするかもしれませんが、しかし、よりスピードを求める場合は、重複やサマリーテーブルの作成をおそれてはいけません。

  * ストアド・プロシージャ や UDF (ユーザー定義関数) はよりパフォーマンスを得るためにはよい方法かもしれません。 In this case you should however always have a way to do this some other (slower) way if you use some database that doesn't support this.

  * You can always gain something by caching queries/answers in your application and trying to do many inserts/updates at the same time.  If your database supports lock tables (like MySQL and Oracle), this should help to ensure that the index cache is only flushed once after all updates.

  * データをすぐには書く必要がないとき、INSERT /*! DELAYED */ を使用します。これは、一回のディスクへの書き込みで、多くのレコードがかかれるので、速くなります。

  * SELECT がより重要な場合、INSERT /*! LOW_PRIORITY */ を使用します。

  * キューを無視して SELECT を優先的に行いたいときは SELECT /*! HIGH_PRIORITY */ を使用します。これは、たとえ誰かが書き込みを待っていたとしても、その SELECT は実行されます。

  * 複数行 INSERT 文の使用。 これは多くのレコードを一つの SQL コマンドで挿入することが出来ます。 (多くの SQL サーバーがこれをサポートしています)

  * 大きなデータの読み込みには LOAD DATA INFILE を使用します。 This if faster than normal inserts and will be even faster when myisamchk is integrated in mysqld.

  * 一意の値を作るために、 AUTO_INCREMENT を使用します。

  * 動的テーブルフォーマットの使用時には、フラグメンテーションを避けるために、 OPTIMIZE TABLE を時々使用します。 See OPTIMIZE TABLE.

  * 可能ならば HEAP テーブルをスピードアップのために使用します. See Table types.

  * 通常の Web サーバーの設定ならば、イメージはファイルに保存すべきです。データベースには、それらファイルの参照(パスとか)のみを入れます。この主な理由は、通常の Web サーバーはデータベースよりもコンテンツをよりよくキャッシュしてくれるからです。 それでファイルを使用するなら、速いシステムをより簡単に得ることができます。

  * 重要でないデータで、よくアクセスされる物は、メモリテーブルにいれます。 (like information about the last shown banner for users that doesn't have cookies)

  * Columns with identical information in different tables should be declared identical and have identical names. Before version 3.23 you got slow joins otherwise.

     名前は単純にしてください（customer テーブルでは customer_name のかわりに name を使うとか）。 他の SQL サーバーへの移植を考慮するなら、名前は 18 文字より短くすべきです。

  * もし本当にハイ・スピードが必要なら、SQL サーバーがサポートしている物とは違う、ローレベルのデータ保存のインターフェースに注目すべきです。例えば、 MySQL MyISAM を直接アクセスすることは、 SQL インターフェースを介してアクセスするよりも、2〜5倍速くなるでしょう。これを可能にするには、そのデータは、アプリケーションと同じマシン上になくてはならず、通常、一つのプロセスだけでアクセスされるべきです。 (なぜなら、外部ファイルロックは、とても遅いから)。上の問題は、MySQL サーバー内の MyISAM のローレベルのコマンドの導入で解決できるでしょう。 (これはよりよいパフォーマンスを得ることの出来る、簡単な方法の一つです)。 By carefully designing the database interface it should be quite easy to support this types of optimisations.

  * 多くの場合、データベースからデータをアクセスする方が(接続を維持していれば)、テキストファイルからデータをアクセスするよりも速いです。 なぜなら、データベースはテキストファイルよりもコンパクトになり（数値データの場合）、このため、ディスクアクセスが少なくなるからです。また、行や項目を見つけるために、テキストファイルを解析する必要も省けます。

  * 複製もスピードアップに使用できるでしょう。 See Replication.

  * DELAY_KEY_WRITE=1 が定義されたテーブルは、インデックスの更新が速くなります。これはそのインデックス・ファイルが閉じられるまでディスクに記録されないからです。したがって、なにかが途中で mysqld をキルしてもテーブルが大丈夫なようにするため、 mysqld を起動する前には、myisamchk をそれらのテーブルに対して実行すべきです。 As the key information can always be generated from the data you should not lose anything by using DELAY_KEY_WRITE.

Using your own benchmarks
=========================

You should definately benchmark your application and database to find out where the bottlenecks are.  By fixing it (or by replacing the bottleneck with a 'dummy module') you can then easily identify the next bottleneck (and so on).  Even if the overall performance for your application is sufficient you should at least make a plan for each bottleneck, and decide how to solve it if someday you really need the extra performance.

For an example of portable benchmark programs look at the MySQL benchmark suite. See MySQL Benchmarks. You can take any program from this suite and modify it for your needs. By doing this, you can try different solutions to your problem and test which is really the fastest solution for you.

It is very common that some problems only occur when the system is very heavily loaded. We have had many customers who contact us when they have a (tested) system in production and have encountered load problems. In every one of these cases so far it has been problems with basic design (table scans are NOT good at high load) or OS/Library issues. Most of this would be a LOT easier to fix if the systems were not already in production.

To avoid problems like this you should put some effort into benchmarking your whole application under the worst possible load! You can use Sasha's recent hack for this - mysql-super-smack (http://www.mysql.com/Contrib/mysql-bench-0.6.tar.gz). As the name suggests, it can bring your system down to its knees if you ask it, so make sure to use it only on your developement systems.

Design choices
==============

MySQL は、レコードのデータとインデックスを別のファイルに保存します。他の多くの(ほとんど全て)データベースでは、同じファイルにデータとインデックスを混在させて保存します。 我々は、最近のシステムには、MySQL の選択の方が良いと信じています。

Another way to store the row data is to keep the information for each column in a separate area (examples are SDBM and Focus). This will cause a performance hit for every query that accesses more than one column. Because this degenerates so quickly when more than one column is accessed, we believe that this model is not good for general purpose databases.

The more common case is that the index and data are stored together (like in Oracle/Sybase et al). In this case you will find the row information at the leaf page of the index. The good thing with this layout is that it, in many cases, depending on how well the index is cached, saves a disk read.  The bad things with this layout is:

     Table scanning is much slower because you have to read through the indexes to get at the data.

     You lose a lot of space as you must duplicate indexes from the nodes (as you can't store the row in the nodes).

     Deletes will degenerate the table over time (as indexes in nodes are usually not updated on delete).

     You can't use only the index table to retrieve data for a query.

     The index data is harder to cache.

MySQL design limitations/tradeoffs
==================================

Because MySQL uses extremely fast table locking (multiple readers / single writers) the biggest remaining problem is a mix of a steady stream of inserts and slow selects on the same table.

We belive that for a huge number of systems the extremely fast performance in other cases make this choice a win. This case is usually also possible to solve by having multiple copies of the table, but it takes more effort and hardware.

We are also working on some extensions to solve this problem for some common application niches.

Portability
===========

Because all SQL servers implement different parts of SQL, it takes work to write portable SQL applications. For very simple selects/inserts it is very easy but the more you need the harder it gets. If you want an application that is fast with many databases it becomes even harder!

To make a complex application portable you need to choose a number of SQL servers that it should work with.

You can use the MySQL crash-me program/web-page http://www.mysql.com/crash-me-choose.htmy to find functions, types and limits you can use with a selection of database servers. Crash-me now tests far from everything possible but it is still comprehensive with about 450 things tested.

For example, you shouldn't have column names longer than 18 characters if you want to be able to use Informix or DB2.

Both the MySQL benchmarks and crash-me programs are very database-independent.  By taking a look at how we have handled this, you can get a feeling of what you have to do to write your application database-independent.  The benchmarks themselves can be found in the sql-bench directory in the MySQL source distribution. They are written in Perl with DBI database interface (which solves the access part of the problem).

See http://www.mysql.com/benchmark.html the results from this benchmark.

As you can see in these results all databases have some weak points. That is, they have different design compromises that lead to different behavior.

If you strive for database independence you need to get a good feeling of each SQL server's bottlenecks. MySQL is VERY fast in retrieving and updating things, but will have a problem in mixing slow readers/writers on the same table. Oracle on the other hand has a big problem when you try to access rows that you have recently updated (until they are flushed to disk). Transaction databases in general are not very good at generating summary tables from log tables as in this case row locking is almost useless.

To get your application really database-independent you need to define an easy extendable interface through which you manipulate your data. As C++ is available on most systems, it makes sense to use a C++ classes interface to the databases.

If you use some specific feature for some database (like the REPLACE command in MySQL), you should code a method for the other SQL servers to implement the same feature (but slower).  With MySQL you can use the /*!  */ syntax to add MySQL specific keywords to a query.  The code inside /**/ will be treated as a comment (ignored) by most other SQL servers.

If REAL high performance is more important than exactness, like in some web applications, a possibility is to create an application layer that caches all results to give you even higher performance. By letting old results 'expire' after a while you can keep the cache reasonably fresh.  This is quite nice in case of extremely high load, in which case you can dynamically increase the cache and set the expire timeout higher until things get back to normal.

In this case the table creation information should contain information of the initial size of the cache and how often the table should normally be refreshed.

What have we used MySQL for?
============================

MySQL の初期の開発期には、MySQL は我々のもっとも大口の顧客に合うように機能が作成されました。 彼らは、いくつかのスウェーデン最大手の小売り業者のために、倉庫に入れている（商品）データを取り扱います。

我々は、すべての店から、全ボーナス・カード取扱高の、その週間まとめを得ます。そして、その店のオーナにとって有益な情報、その店の広告キャンペーンがお客にどの程度影響を及ぼすか、を提供することが、我々に求められています。

そのデータは、とても大きくて (約700万/月 回の取り扱い)、我々はその顧客に提供する必要のあるデータを 4〜10年分、持っています。我々は、カスタマーから、彼らがこのデータからできる新しいレポートに ”即時に”アクセスしたいという、要求を受けました。

我々はこれを、全ての月ごとの情報を圧縮した 'transaction' テーブルに保存することで解決しました。 We have a set of simple macros (script) that generates summary tables grouped by different criteria (product group, customer id, store ...) from the transaction tables. そのレポートは Web ページで、これは小さな perl スクリプトで動的に作成されます。 この perl script は Web Page を分析し、SQL 文を実行し、結果を挿入します。 We would have used PHP or mod_perl instead but they were not available at that time.

画像データのために、我々は簡単なツールを C でかきました。これは SQL のクエリの結果を元に(結果にいくつか処理をして) GIF を提供します。これも動的に perl スクリプト(HTML ファイルを分析する)から実行されます。

In most cases a new report can simply be done by copying an existing script and modifying the SQL query in it.  In some cases we will need to add more fields to an existing summary table or generate a new one, but this is also quite simple as we keep all transactions tables on disk. (Currently we have at least 50G of transactions tables and 200G of other customer data).

We also let our customers access the summary tables directly with ODBC so that the advanced users can themselves experiment with the data.

我々はこれらを  Sun Ultra SPARCstation (2x200 Mz) で扱っていますが、なんの問題もありません。 We recently upgraded one of our servers to a 2 CPU 400 Mhz UltraSPARC and we are now planning to start handling transactions on the product level, which would mean a ten-fold increase of data. We think we can keep up with this by just adding more disk to our systems.

We are also experimenting with Intel-Linux to be able to get more CPU power cheaper.  現在、我々はバイナリ互換のデータベースフォーマットを持っており (new in 3.23) 、我々はこれをアプリケーションのいくつかの部分に使用しはじめる事でしょう。

Our initial feelings are that Linux will perform much better on low to medium load but Solaris will perform better when you start to get a high load because of extreme disk IO, but we don't yet have anything conclusive about this. After some discussion with a Linux Kernel developer this might be a side effect of Linux giving so much resources to the batch job that the interactive performance gets very low. This makes the machine feel very slow and unresponsive while big batches are going. Hopefully this will be better handled in future Linux Kernels.

MySQL ベンチマークスイート
****************

ここには MySQL ベンチマークスイート(と crash-me)の技術上の解説が書かれるはずですが、まだ書かれていません。現在、ベンチマークのコードと結果はソースの中の sql-bench ディレクトリにあります。 (もちろん Web ページ http://www.mysql.com/crash-me-choose.htmy にも)

なんの SQL 実装のパフォーマンスが良いのか悪いのかを、どんなユーザーに対しても示すのがベンチマークです。

Note that this benchmark is single threaded so it measures the minimum time for the operations.

For example (run on the same NT 4.0 machine):

Reading 2000000 rows by index   Seconds   Seconds
mysql               367   249
mysql_odbc         464
db2_odbc           1206
informix_odbc      121126
ms-sql_odbc        1634
oracle_odbc        20800
solid_odbc         877
sybase_odbc        17614

Inserting (350768) rows   Seconds   Seconds
mysql              381   206
mysql_odbc         619
db2_odbc           3460
informix_odbc      2692
ms-sql_odbc        4012
oracle_odbc        11291
solid_odbc         1801
sybase_odbc        4802

In the above test MySQL was run with a 8M index cache.

Note that Oracle is not included because they asked to be removed. All Oracle benchmarks has to be passed by Oracle! We believe that makes Oracle benchmarks VERY biased because the above bechmarks are supposed to show what a standard installation can do for a single client.

crash-me は、データベースがサポートする機能、能力、制限について、実際にクエリを走らせて確認します。例えば、以下のような事について調べます：

  * サポートしている項目の型はなにか

  * サポートするインデックスの最大数は

  * どのような関数があるのか

  * 受けれるクエリの大きさはどこまでか

  * VARCHAR 型はどこまで大きくできるのか

MySQL ユーティリティ
*************

様々な MySQL プログラムの概要
==================

サーバと通信する mysqlclient ライブラリを使用している全ての MySQL クライアントは次の環境変数を使用します:

Name   Description
MYSQL_UNIX_PORT   デフォルトのソケット; localhost への接続に使用される
MYSQL_TCP_PORT    デフォルトの TCP/IP ポート
MYSQL_PWD   デフォルトのパスワード
MYSQL_DEBUG   デバッグオプション
TMPDIR   一時 tables/files が作成されるディレクトリ

MYSQL_PWD の使用は安全ではありません。 See Connecting.

mysql クライアントは、MYSQL_HISTFILE 環境変数に指定されているファイルにコマンドラインの履歴を書き出します。デフォルトの履歴ファイルは、 $HOME/.mysql_history で、$HOME は HOME 環境変数の値です。 See Environment variables.

全ての MySQL プログラムは多くの様々なオプションを持ちます。種々のオプションの完全な説明を得るにはスイッチ --help を使用してください。例えばmysql --help を試してください。

オプションファイルで、全ての標準クライアントのデフォルトのオプションを変更することが可能です。 Option files.

MySQL プログラムを以下に示します:

myisamchk
     MySQL テーブルをチェック, 最適化そして修復します。 myisamchk には多くの機能があるので、一章割り当てて説明しています。 See Maintenance.

make_binary_release
     コンパイルされた MySQL のバイナリリリースを作成します。これは他の MySQL ユーザの利便のために、ftp で ftp.tcx.se の  /pub/mysql/Incoming に送ることができます。

msql2mysql
     mSQL プログラムを MySQL に変換するシェルスクリプト。全てのケースで処理できるわけではありませんが、変換時に良いスタートを与えます。

mysql
     mysql は簡単な SQL シェル (GNU readline つき) です。これは対話的な使用や非対話型問い合わせをサポートします。対話的に使用されると、ASCII テーブル形式で結果が与えられます。フィルタとして使用されると、出力はタブで区切られます（これは起動時のオプションで他のものに変更できます）。あなたは以下のように簡単にスクリプトを実行できます:

          shell> mysql database < script.sql > output.tab

     クライアントのメモリが十分でないことによる問題がある場合は、 --quick スイッチを使用してください！ これは結果を取り出すのに mysql_store_result() の代わりに mysql_use_result() を使用するように mysql に強制させます。

mysqlaccess
     ホスト, ユーザそしてデータベースの組合せで権限をチェックするためのスクリプト。

mysqladmin
     管理ユーティリティ。データベースの作成/破棄。reload (新しいユーザの読み込み) と refresh (ディスクへのテーブルのフラッシュ, ログファイルの再オープン)。サーバのバージョンと処理と状態情報も与えます。 See mysqladmin.

mysqlbug
     MySQL バグレポートスクリプト。このスクリプトは MySQL メーリングリストにバグレポートを出す際、常に使用します。

mysqld
     SQL デーモン。これは常に実行されてます。

mysqldump
     MySQL データベースの SQL ステートメントまたはタブで区切られたテキストのファイルにダンプします。Igor Romanenko によって独創的にエンハンスされたフリーウェア。 See mysqldump.

mysqlimport
     一つまたは複数のテキストファイルをそれぞれのテーブルに読み込みます。LOAD DATA INFILE でサポートされる全ての形式を使用できます。 See mysqlimport.

mysqlshow
     データベース, テーブル, 項目そしてインデックスについての情報を表示します。

mysql_install_db
     MySQL 承認テーブルをデフォルトの権限で作成します。これは通常、最初の MySQL リリースを新しいシステム上にインストールする時に一回だけ実行されます。

replace
     msql2mysql で使用されるバイナリ。ファイル内または標準入力上の文字列を変換するユーティリティプログラム。より長い文字列に最初に適合するため有限状態マシンを使用します。文字列を交換するために使用できます。例えば、 a と b を与えられたファイル内で交換します:

          shell> replace a b b a -- file1 file2 ...

safe_mysqld
     mysqld デーモンをいくつかの安全な機能で開始します。エラー時には再起動し、実行時情報をログファイルへ記入します。

コマンドラインツール （ mysql ）
====================

mysql はシンプルな SQL shell です(GNU readline を持っています). これは対話モードと、非対話モードを持っています。 対話モードで使用された場合、クエリの結果は ASCII テーブルのフォーマットで与えられます。非対話モードで使用された場合(例えばフィルターとして)、結果はタブ区切りのフォーマットで返ります。 (出力フォーマットはコマンドラインのオプションで変更できます) 以下のようにしてスクリプトを実行できます：

     shell> mysql database < script.sql > output.tab

もしクライアントでメモリー不足の問題が出た場合、--quick オプションを使用します！ これは mysql に、結果セットを取得する際に、 mysql_store_result() ではなく mysql_use_result() を使用させます。

mysql の使用はとても簡単です： mysql database や mysql --user=user_name --password=your_password d atabase のようにしてはじめます。 SQL 文を入力し、一文を ;, \g or \G で終え、 return/enter を押します。

mysql は以下のオプションをサポートします：

-?, --help
     help を表示して終了

-A, --no-auto-rehash
     自動リハッシュをしない。 テーブルとフィールドの取得には 'rehash' を使用しなくてはなりません。 これは mysql の起動を速くします。

-B, --batch
     結果をタブ区切り、１レコードは１行で出力します。 history ファイルは使用しません。

-C, --compress
     サーバー・クライアント間の通信を圧縮します

-#, --debug[=...]
     デバッグログ。 デフォルトは 'd:t:o,/tmp/mysql.trace'

-D, --database=..
     使用するデータベース。 これは my.cnf ファイルが便利です

-e, --execute=...
     コマンドを実行して終了。 (Output like with --batch)

-E, --vertical
     垂直にレコードを出力します。 このオプションを指定していなくても、 SQL 文を \G で終了した場合、同じように垂直に出力します。

-f, --force
     SQL エラーがおきたとしても、処理を続けます

-i, --ignore-space
     関数名の後ろについたスペースを無視します

-h, --host=...
     指定したホストに接続します

-H, --html
     結果を HTML フォーマットで返します

-L, --skip-line-numbers
     エラーの起きた行の番号を書きません。 これはエラーメッセージを含んだ結果を比較する場合に便利です。

-n, --unbuffered
     それぞれのクエリ毎にバッファをフラッシュします

-N, --skip-column-names
     結果に、フィールド名を書き出しません。

-O, --set-variable var=option
     変数に値をセットします。 --help lists variables

-o, --one-database
     デフォルトのデータベースのみ更新します。 これは update ログファイルを使用して更新する場合、他のデータベースの更新を避けたい時に便利です。

-p[password], --password[=...]
     サーバーに接続する際のパスワード。 もしパスワードがコマンドラインに指定されていなかった場合、tty 上でパスワードが問い合わされます。 -p を使用する場合、このオプションとパスワードの間にはスペースが不要だということに注意してください。

-P  --port=...
     接続に使用する TCP/IP ポート番号

-q, --quick
     結果をキャッシュせず、一レコードづつ出力します。これはもし出力を中止した場合、サーバーを遅くします。ヒストリファイルは使用しません。

-r, --raw
     エスケープ処理をしないで値を書き出します。 --batch とともに使用されます

-s, --silent
     静粛モード

-S  --socket=...
     接続に使用する ソケットファイル

-t  --table
     表の形式で出力します。 これは batch モード以外でのデフォルトです。

-T, --exit-info
     Only used when debugging.  --exit-info=0 will print some usage information one exit.

-u, --user=#
     ログインユーザー名

-U, --safe-updates[=#], --i-am-a-dummy[=#]
     キーを使用する UPDATE and DELETE のみを行います。これは後述します。 このオプションをもし my.cnf に書いている場合は、 --safe-updates=0 でこのオプションをリセットできます。

-v, --verbose
     冗長出力。 (-v -v -v は表形式の出力を与える)

-V, --version
     バージョンを表示して終了

-w, --wait
     もし接続が落ちた場合、中断しないで、待って、再試行します。

もしコマンドラインで 'help' と打った場合、mysql はサポートするコマンドを表示します：

     mysql> help

     MySQL commands:
     help    (\h)    Display this text
     ?       (\h)    Synonym for `help'
     clear   (\c)    Clear command
     connect (\r)    Reconnect to the server. Optional arguments are db and host
     edit    (\e)    Edit command with $EDITOR
     exit    (\q)    Exit mysql. Same as quit
     go      (\g)    Send command to mysql server
     ego     (\G)    Send command to mysql server; Display result vertically
     print   (\p)    Print current command
     quit    (\q)    Quit mysql
     rehash  (\#)    Rebuild completion hash
     source  (\.)    Execute a SQL script file. Takes a file name as an argument
     status  (\s)    Get status information from the server
     use     (\u)    Use another database. Takes database name as argument

status コマンドは、今使用している接続とサーバーについての情報をいくつか表示します。もし --safe-updates モードで使用している場合、 status はあなたのクエリに影響する mysql 変数の値を表示します。

初心者に便利な起動オプション(MySQL 3.23.11 で導入されました)は、 --safe-mode (あるいは --i-am-a-dummy) で、これは DELETE FROM table_name を WHERE 節を忘れて実行しようとした場合のためにあります。このオプションが使用されると、 mysql は接続時に MySQL サーバーに以下のようなコマンドを送ります：

     SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
         SQL_MAX_JOIN_SIZE=#max_join_size#"

ここで #select_limit# と #max_join_size# は変数でこれらは mysql コマンドからセット可能です。 See SET.

この効果は：

  bullet もし WHERE 節でキーを使用していなければ、UPDATE や DELETE は許可されません。 しかし、 LIMIT を使用すれば UPDATE/DELETE を強制実行できます：

          UPDATE table_name SET not_key_column=# WHERE not_key_column=# LIMIT 1;

  bullet 全ての多きな結果は自動的に #select_limit# レコードまでに抑えられます。

  bullet 評価に #max_join_size 以上の行を必要とするであろう SELECT は中断されます。

MySQL サーバーの管理 ( mysqladmin )
============================

管理オペレーションを実行するためのユーティリティ。シンタックスは:

     shell> mysqladmin [OPTIONS] command [command-option] command ...

mysqladmin --help によって、オプションの一覧を手にいれることができます。

現在の mysqladmin は以下のコマンドをサポートします：

create databasename   データベースの作成
drop databasename    データベースとテーブルの全削除。
extended-status   サーバーから拡張ステータスを取得。
flush-hosts   キャッシュされている全ホストをフラッシュ。
flush-logs   全てのログをフラッシュ
flush-tables   全てのテーブルをフラッシュ
flush-privileges   許可テーブルの再読み込み (reload と同じ)
kill id,id,...    mysql スレッドの kill.
password new-password   古いパスワードを new-password に変更
ping   mysqld が生きているかチェック
processlist   現在活動中の mysql スレッドを表示
reload   許可テーブルの再読み込み
refresh   全テーブルをフラッシュし、ログファイルを一度閉じて開きます。
shutdown   サーバーをダウンさせます。
slave-start   Start slave replication thread
slave-stop   Stop slave replication thread
status   サーバーから短いステータスを得ます。
variables   変数の表示
version   サーバーからバージョンを得ます。

全てのコマンドは、ユニークなプレフィックスで省略可能です。例えば：

     shell> mysqladmin proc stat
     +----+-------+-----------+----+-------------+------+-------+------+
     | Id | User  | Host      | db | Command     | Time | State | Info |
     +----+-------+-----------+----+-------------+------+-------+------+
     | 6  | monty | localhost |    | Processlist | 0    |       |      |
     +----+-------+-----------+----+-------------+------+-------+------+
     Uptime: 10077  Threads: 1  Questions: 9  Slow queries: 0  Opens: 6  Flush tables: 1  Open tables: 2  Memory in use: 1092K  Max memory used: 1116K

mysqladmin status コマンドの結果は、以下の項目を持ちます:

Uptime   MySQL サーバーの起動秒数
Threads   稼働中のスレッド数 (clients)
Questions   mysqld が開始してからのクライアントからのクエリ数
Slow queries   long_query_time 秒より時間のかかったクエリの数
Opens   mysqld が開いたテーブル数
Flush tables   flush ..., refresh and reload コマンドの実行回数
Open tables   現在開かれているテーブルの数
Memory in use   mysqld のコードによって直接割り当てられたメモリ (only available when MySQL is compiled with --with-debug)
Max memory used   mysqld のコードによって直接割り当てられる最大メモリー量 (only available when MySQL is compiled with --with-debug)

If you do myslqadmin shutdown on a socket (in other words, on a the computer where mysqld is running), mysqladmin will wait until the MySQL pid-file is removed to ensure that the mysqld server has stopped properly.

MySQL データベースとテーブルから、構造とデータをダンプ ( mysqldump )
============================================

データベース、あるいは、バックアップ、他のSQLサーバーへのデータを移動を目的としたデータのまとまり、これらをダンプするためのユーティリティ。ダンプは、テーブルの作成のための SQL 文を含みます。

     shell> mysqldump [OPTIONS] database [tables]
     OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
     OR     mysqldump [OPTIONS] --all-databases [OPTIONS]

もしテーブルを指定せず、--databases や --all-databases を使用しなかったなら、データベースの全てのテーブルがダンプされます。

mysqldump --help によって、オプションの一覧を手にいれることができます。

もし mysqldump を --quick や --opt なしで実行するならば、 mysqldump は結果を表示する前に、結果をメモリに全てロードすることに注意してください。これは大きなデータベースをダンプする際に問題になるでしょう。

mysqldump は以下のオプションをサポートします：

--add-locks
     テーブルのダンプの前に LOCK TABLES 文を追加し、テーブルのダンプ後に UNLOCK TABLE 文を追加します。 ( あとで MySQL に挿入するときにこれは速くなります ).

--add-drop-table
     テーブルの create 文の前に、drop table 文を追加します。

-A, --all-databases
     Dump all the databases. This will be same as --databases with all databases selected.

-a, --all
     Include all MySQL specific create options.

--allow-keywords
     キーワード(予約語) と同じ名前をもつフィールドの作成を許します。これは、それぞれのフィールドの前に、テーブル名を付け足します。

-c, --complete-insert
     完全な INSERT 文(フィールド名を書いた文) を使用します。

-C, --compress
     もしサーバーとクライアントの双方が圧縮をサポートしているならば、両者の間で行われる通信を全て圧縮します。

-B, --databases
     To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. USE db_name; will be included in the output before each new database.

--delayed
     INSERT DELAYED コマンドを使用してレコードを INSERT します。

-e, --extended-insert
     新しいマルチライン INSERT 構文を使用します。(これはあとで挿入する際、よりコンパクトかつ速くなります。)

-#, --debug[=option_string]
     Trace usage of the program (for debugging).

--help
     Display a help message and exit.

--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--lines-terminated-by=...
     これらのオプションは -T とともに使用され、 LOAD DATA INFILE と同様の意味をなします。 See LOAD DATA.

-F, --flush-logs
     ダンプする前に、 MySQL サーバーのログファイルをフラッシュします。

-f, --force,
     ダンプの途中で SQL エラーが発生しても、ダンプを続けます。

-h, --host=..
     指定されたホストの MySQL サーバーからダンプします。デフォルトのホストは localhost.

-l, --lock-tables.
     ダンプを開始するとき全てのテーブルをロックします。 The tables are locked with READ LOCAL to allow concurrent inserts in the case of MyISAM tables.

-n, --no-create-db
     'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.

-t, --no-create-info
     テーブルの作成情報( CREATE TABLE 文) を書き出しません。

-d, --no-data
     テーブル内のレコードを書き出しません。これはテーブルの構造だけを取り出したいときにとても便利です！

--opt
     --quick --add-drop-table --add-locks --extended-insert --lock-tables と同じ. MySQL サーバーから読み出す時間を最短にしてくれます。

-pyour_pass, --password[=your_pass]
     サーバーに接続する際のパスワードを与えます。もし =your_pass 部分を与えなかった場合は、 mysqldump はパスワードのプロンプトをだします。

-P port_num, --port=port_num
     サーバーに接続する際に使用する TCP/IP ポート番号。 (これは localhost 以外のホストへの接続に使用されます。 localhost の場合は、Unix ソケットが使用されます。)

-q, --quick
     クエリをバッファにため込みません。stdout に直接出します。 mysql_use_result() をこれに使用しています。

-S /path/to/socket, --socket=/path/to/socket
     localhost に接続する際のソケットファイルの指定 (デフォルトは /tmp/mysql.sock )

--tables
     Overrides option --databases (-B).

-T, --tab=path-to-some-directory
     与えられたテーブル毎に、 SQL CREATE 文を含む table_name.sql ファイル、データを含む table_name.txt ファイルを作成します。 NOTE: これは mysqld デーモンが走っているマシン上で mysqldump を実行する場合にだけ、動作します。 .txt ファイルのフォーマットは、 --fields-xxx と --lines--xxx オプションに従います。

-u user_name, --user=user_name
     サーバーに接続する際の MySQL ユーザー名。デフォルトでは、Unix のログイン名になります。

-O var=option, --set-variable var=option
     変数の値をセット。 可能な変数は後で示しします。

-v, --verbose
     冗長モード。 プログラムが何を行っているかより表示します。

-V, --version
     バージョンを示して終了。

-w, --where='where-condition'
     選択されたレコードのみをダンプ： クオートは必須です！

          "--where=user='jimf'" "-wuserid>1" "-wuserid<1"

-O net_buffer_length=#, where # < 24M
     When creating multi-row-insert statements (as with option --extended-insert or --opt), mysqldump will create rows up to net_buffer_length length. If you increase this variable, you should also ensure that the max_allowed_packet variable in the MySQL server is bigger than the net_buffer_length.

mysqldump の普通の使用はデータベースのバックアップでしょう。 See Backup.

     mysqldump --opt database > backup-file.sql

他の MySQL サーバーへデータベースをコピーする場合にも便利です：

     mysqldump --opt database | mysql ---host=remote-host -C database

It is possible to dump several databases with one command:

     mysqldump --databases database1 [database2 database3...] > my_databases.sql

If all the databases are wanted, one can use:

     mysqldump --all-databases > all_databases.sql

テキストファイルからデータを取り込む ( mysqlimport )
==================================

mysqlimport は、LOAD DATA INFILE SQL 構文を、コマンドラインインターフェースで提供します。 mysqlimport のオプションのほとんどが、 LOAD DATA INFILE への同じオプションに対応します。 See LOAD DATA.

mysqlimport の実行は以下のようにします:

     shell> mysqlimport [options] database textfile1 [textfile2....]

mysqlimport は、コマンドラインの引数に与えられたファイル名の拡張子を取り、拡張子を取った後の名前を、ファイルの内容を取り込むテーブルの名前とします。例えば、patient.txt, patient.text, patient というファイルは全て、patient とという名前のテーブルに取り込まれます。

mysqlimport は以下のオプションをサポートします:

-c, --columns=...
     This option takes a comma separated list of field names as an argument. The field list is passed to LOAD DATA INFILE MySQL sql command, which mysqlimport calls MySQL to execute. For more information, please see LOAD DATA INFILE. See LOAD DATA.

-C, --compress
     クライアントとサーバーの両方が圧縮をサポートしているなら、クライアント・サーバー間でやり取りされる全ての情報を圧縮します。

-#, --debug[=option_string]
     プログラムのトレース(デバッグ)

-d, --delete
     テキストファイルを取り込む前にテーブルを空にします。

--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--lines-terminated-by=...
     これらのオプションは、LOAD DATA INFILE の対応する文節と同じ意味になります。 See LOAD DATA.

-f, --force
     エラーを無視します。例えば、テキストファイルを取り込むテーブルがない場合、残りのファイルの処理に移ります。 --force がなければ、テーブルがなければ mysqlimport は終了します。

--help
     ヘルプを表示して終了。

-h host_name, --host=host_name
     名前を指定された MySQL サーバーにデータを取り入れます。デフォルトでは localhost.

-i, --ignore
     --replace オプションの説明を見てください。

-l, --lock-tables
     それぞれのテキストファイルを処理する前に、書き込まれる全てのテーブルをロックします。これは確実に、すべてのテーブルをサーバ上で同期させます。

-L, --local
     クライアントからの入力ファイルを読みます。デフォルトでは、localhost に接続した場合、テキストファイルはサーバー上にあると仮定されます。(localhost はデフォルト値)

-pyour_pass, --password[=your_pass]
     サーバーに接続するときに使用するパスワード。もし =your_pass のところにパスワードを書かなければ、 mysqlimport はパスワードのためのプロンプトをだします。

-P port_num, --port=port_num
     ホストに接続するための TCP/IP ポート番号。 (これは localhost を除くホストへの接続に使用します。 localhost へは、UNIX ソケットを使用します。)

-r, --replace
     --replace と --ignore オプションは、入力されているレコードのユニークキーの値が、既に存在しているレコードのユニークキーの値と同じ場合、その入力されているデータの取り扱いを決定します。もし --replace が指定されているなら、既にあるレコードは新しく読まれたレコードに置き換えられます。もし --ignore が指定されているなら、入力された物は無視されます。どちらのオプションも指定していない場合、キーの値が重なっているとエラーを発し、テキストファイルの残りの部分は無視されます。

-s, --silent
     静粛モード。エラーだけ出力します。

-S /path/to/socket, --socket=/path/to/socket
     localhost への接続時に使用するソケットファイルを指定します。

-u user_name, --user=user_name
     サーバーの接続に使用する MySQL ユーザー名の指定。デフォルトは、Unix のログイン名。

-v, --verbose
     冗長モード。プログラムがしている事について多く出力します。

-V, --version
     バージョンを表示して終了。

Here follows a sample run of using mysqlimport:

     $ mysql --version
     mysql  Ver 9.33 Distrib 3.22.25, for pc-linux-gnu (i686)
     $ uname -a
     Linux xxx.com 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown
     $ mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
     $ ed
     a
     100     Max Sydow
     101     Count Dracula
     .
     w imptest.txt
     32
     q
     $ od -c imptest.txt
     0000000   1   0   0  \t   M   a   x       S   y   d   o   w  \n   1   0
     0000020   1  \t   C   o   u   n   t       D   r   a   c   u   l   a  \n
     0000040
     $ mysqlimport --local test imptest.txt
     test.imptest: Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
     $ mysql -e 'SELECT * FROM imptest' test
     +------+---------------+
     | id   | n             |
     +------+---------------+
     |  100 | Max Sydow     |
     |  101 | Count Dracula |
     +------+---------------+

Showing databases, tables and columns （mysqlshow）
=================================================

mysqlshow can be used to quickly look at which databases exist, their tables, and the table's columns.

With the mysql program you can get the same information with the SHOW commands.  See SHOW.

mysqlshow is invoked like this:

     shell> mysqlshow [OPTIONS] [database [table [column]]]

  * If no database is given, all matching databases are shown.

  * If no table is given, all matching tables in database are shown.

  * If no column is given, all matching columns and column types in table are shown.

Note that in newer MySQL versions you only see those database/tables/columns for which you have some privileges.

If the last argument contains a shell or SQL wildcard (*, ?, % or _) then only what's matched by the wildcard is shown. This may cause some confusion when you try to display the columns for a table with a _ as in this case mysqlshow only shows you the table names that matches the pattern.  This is easily fixed by adding an extra % last on the command line (as a separate argument).

MySQL の圧縮された読み込み専用テーブルジェネレータ ( myisampack ・ pack_isam )
=======================================================

myisampack is used to compress MyISAM tables and pack_isam is used to compress ISAM tables. Because ISAM tables are deprecated, we will only discuss myisampack here.

myisampack は、 1 MySQL ライセンス以上または MySQL サポートを注文した時に得られる特別なユーテリティです。これらはバイナリだけの配布のため、いくつかのプラットフォーム上でだけに有効です。

In the following we only talk about myisampack, but everything is also true for pack_isam.

myisampack はテーブル内の各項目を別々に圧縮するように働きます。展開のための情報は、テーブルがオープンされた時にメモリに読まれます。これは、正確に1レコードだけを展開する必要があるような、個々のレコードへのアクセス時にとても良い性能を与えます。MSDOS 上の Stacker 使用時のように、ディスクブロックはそんなに大きくありません。通常、myisampack はデータファイルを 40〜70% にパックします。

MySQL は圧縮されたテーブルでメモリマップ (mmap()) を使用します。 mmap() が働かない場合は、通常のファイルの読み書きを使用します。

現在 myisampack には2つの制限があります:

  * パック後、テーブルは読み込み専用になります。

  * myisampack can also pack BLOB or TEXT columns. The older pack_isam could not do this.

これらの制限の修正は TODO にありますが、優先度は低いです。

myisampack は以下のようにして起動します:

     shell> myisampack [options] filename ...

それぞれのファイル名はインデックスファイル(.MYI)の名前です。もしデータディレクトリにカレントディレクトリを移動していないなら、ファイルのパスを指定しなくてはなりません。.MYI 拡張子は省略することが可能です。

myisampack は以下のオプションをサポートします:

-b, --backup
     tbl_name.OLD としてバックアップを作成します.

-#, --debug=debug_options
     デバック出力。debug_options は 'd:t:o,filename'.

-f, --force
     一時ファイルが存在していようが、サイズが大きくなろうが、強制的にテーブルをパックします。 myisampack はテーブルを圧縮している間、一時ファイルを tbl_name.TMD という名前で作成します。もし myisampack を途中で kill した場合、 .TMD ファイルが消されていない事があります。通常、myisampack は tbl_name.TMD ファイルが既に存在する場合はエラーで終了します。 --force を使用すると、 myisampack はそのような場合でもテーブルをパックします。

-?, --help
     ヘルプメッセージを出力して終了。

-j big_tbl_name, --join=big_tbl_name
     全てのテーブルをコマンドラインで指定した big_tbl_name 一つにまとめます。結合される全てのテーブル定義は同じでなければなりません (同じ項目名、同じ項目型、同じインデックス、等)

-p #, --packlength=#
     Specify the record length storage size, in bytes.  The value should be 1, 2 or 3.  (myisampack stores all rows with length pointers of 1, 2 or 3 bytes.  In most normal cases, myisampack can determine the right length value before it begins packing the file, but it may notice during the packing process that it could have used a shorter length. In this case, myisampack will print a note that the next time you pack the same file, you could use a shorter record length.)

-s, --silent
     Silent mode.  Write output only when errors occur.

-t, --test
     Don't pack table, only test packing it.

-T dir_name, --tmp_dir=dir_name
     Use the named directory as the location in which to write the temporary table.

-v, --verbose
     Verbose mode.  Write info about progress and packing result.

-V, --version
     Display version information and exit.

-w, --wait
     Wait and retry if table is in use. If the mysqld server was invoked with the --skip-locking option, it is not a good idea to invoke myisampack if the table might be updated during the packing process.

The sequence of commands shown below illustrates a typical table compression session:

     shell> ls -l station.*
     -rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.ISD
     -rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.ISM
     -rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.MYD
     -rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.MYI
     -rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

     shell> myisamchk -dvv station

     MyISAM file:     station
     Isam-version:  2
     Creation time: 1996-03-13 10:08:58
     Recover time:  1997-02-02  3:06:43
     Data records:              1192  Deleted blocks:              0
     Datafile: Parts:           1192  Deleted data:                0
     Datafile pointer (bytes):     2  Keyfile pointer (bytes):     2
     Max datafile length:   54657023  Max keyfile length:   33554431
     Recordlength:               834
     Record format: Fixed length

     table description:
     Key Start Len Index   Type                       Root  Blocksize    Rec/key
     1   2     4   unique  unsigned long              1024       1024          1
     2   32    30  multip. text                      10240       1024          1

     Field Start Length Type
     1     1     1
     2     2     4
     3     6     4
     4     10    1
     5     11    20
     6     31    1
     7     32    30
     8     62    35
     9     97    35
     10    132   35
     11    167   4
     12    171   16
     13    187   35
     14    222   4
     15    226   16
     16    242   20
     17    262   20
     18    282   20
     19    302   30
     20    332   4
     21    336   4
     22    340   1
     23    341   8
     24    349   8
     25    357   8
     26    365   2
     27    367   2
     28    369   4
     29    373   4
     30    377   1
     31    378   2
     32    380   8
     33    388   4
     34    392   4
     35    396   4
     36    400   4
     37    404   1
     38    405   4
     39    409   4
     40    413   4
     41    417   4
     42    421   4
     43    425   4
     44    429   20
     45    449   30
     46    479   1
     47    480   1
     48    481   79
     49    560   79
     50    639   79
     51    718   79
     52    797   8
     53    805   1
     54    806   1
     55    807   20
     56    827   4
     57    831   4

     shell> myisampack station.MYI
     Compressing station.MYI: (1192 records)
     - Calculating statistics

     normal:     20  empty-space:      16  empty-zero:        12  empty-fill:  11
     pre-space:   0  end-space:        12  table-lookups:      5  zero:         7
     Original trees:  57  After join: 17
     - Compressing file
     87.14%

     shell> ls -l station.*
     -rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.ISD
     -rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.ISM
     -rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.MYD
     -rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.MYI
     -rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

     shell> myisamchk -dvv station

     MyISAM file:     station
     Isam-version:  2
     Creation time: 1996-03-13 10:08:58
     Recover time:  1997-04-17 19:04:26
     Data records:              1192  Deleted blocks:              0
     Datafile: Parts:           1192  Deleted data:                0
     Datafilepointer (bytes):      3  Keyfile pointer (bytes):     1
     Max datafile length:   16777215  Max keyfile length:     131071
     Recordlength:               834
     Record format: Compressed

     table description:
     Key Start Len Index   Type                       Root  Blocksize    Rec/key
     1   2     4   unique  unsigned long             10240       1024          1
     2   32    30  multip. text                      54272       1024          1

     Field Start Length Type                         Huff tree  Bits
     1     1     1      constant                             1     0
     2     2     4      zerofill(1)                          2     9
     3     6     4      no zeros, zerofill(1)                2     9
     4     10    1                                           3     9
     5     11    20     table-lookup                         4     0
     6     31    1                                           3     9
     7     32    30     no endspace, not_always              5     9
     8     62    35     no endspace, not_always, no empty    6     9
     9     97    35     no empty                             7     9
     10    132   35     no endspace, not_always, no empty    6     9
     11    167   4      zerofill(1)                          2     9
     12    171   16     no endspace, not_always, no empty    5     9
     13    187   35     no endspace, not_always, no empty    6     9
     14    222   4      zerofill(1)                          2     9
     15    226   16     no endspace, not_always, no empty    5     9
     16    242   20     no endspace, not_always              8     9
     17    262   20     no endspace, no empty                8     9
     18    282   20     no endspace, no empty                5     9
     19    302   30     no endspace, no empty                6     9
     20    332   4      always zero                          2     9
     21    336   4      always zero                          2     9
     22    340   1                                           3     9
     23    341   8      table-lookup                         9     0
     24    349   8      table-lookup                        10     0
     25    357   8      always zero                          2     9
     26    365   2                                           2     9
     27    367   2      no zeros, zerofill(1)                2     9
     28    369   4      no zeros, zerofill(1)                2     9
     29    373   4      table-lookup                        11     0
     30    377   1                                           3     9
     31    378   2      no zeros, zerofill(1)                2     9
     32    380   8      no zeros                             2     9
     33    388   4      always zero                          2     9
     34    392   4      table-lookup                        12     0
     35    396   4      no zeros, zerofill(1)               13     9
     36    400   4      no zeros, zerofill(1)                2     9
     37    404   1                                           2     9
     38    405   4      no zeros                             2     9
     39    409   4      always zero                          2     9
     40    413   4      no zeros                             2     9
     41    417   4      always zero                          2     9
     42    421   4      no zeros                             2     9
     43    425   4      always zero                          2     9
     44    429   20     no empty                             3     9
     45    449   30     no empty                             3     9
     46    479   1                                          14     4
     47    480   1                                          14     4
     48    481   79     no endspace, no empty               15     9
     49    560   79     no empty                             2     9
     50    639   79     no empty                             2     9
     51    718   79     no endspace                         16     9
     52    797   8      no empty                             2     9
     53    805   1                                          17     1
     54    806   1                                           3     9
     55    807   20     no empty                             3     9
     56    827   4      no zeros, zerofill(2)                2     9
     57    831   4      no zeros, zerofill(1)                2     9

The information printed by myisampack is described below:

normal
     The number of columns for which no extra packing is used.

empty-space
     The number of columns containing values that are only spaces; these will occupy 1 bit.

empty-zero
     The number of columns containing values that are only binary 0's; these will occupy 1 bit.

empty-fill
     The number of integer columns that don't occupy the full byte range of their type; these are changed to a smaller type (for example, an INTEGER column may be changed to MEDIUMINT).

pre-space
     The number of decimal columns that are stored with leading space. In this case, each value will contain a count for the number of leading spaces.

end-space
     The number of columns that have a lot of trailing space.  In this case, each value will contain a count for the number of trailing spaces.

table-lookup
     The column had only a small number of different values, and that were converted to an ENUM before Huffman compression.

zero
     The number of columns for which all values are zero.

Original trees
     The initial number of Huffman trees.

After join
     The number of distinct Huffman trees left after joining trees to save some header space.

After a table has been compressed, myisamchk -dvv prints additional information about each field:

Type
     The field type may contain the following descriptors:

     constant
          All rows have the same value.

     no endspace
          Don't store endspace.

     no endspace, not_always
          Don't store endspace and don't do end space compression for all values.

     no endspace, no empty
          Don't store endspace. Don't store empty values.

     table-lookup
          The column was converted to an ENUM.

     zerofill(n)
          The most significant n bytes in the value are always 0 and are not stored.

     no zeros
          Don't store zeros.

     always zero
          0 values are stored in 1 bit.

Huff tree
     The Huffman tree associated with the field.

Bits
     The number of bits used in the Huffman tree.

After you have run pack_isam/myisampack you must run isamchk/myisamchk to recreate the index.  At this time you can also sort the index blocks and create statistics that is needed for the MySQL optimizer to work more efficiently.

     myisamchk -rq --analyze --sort-index table_name.MYI
     isamchk   -rq --analyze --sort-index table_name.ISM

After you have installed the packed table into the MySQL database directory you should do mysqladmin flush-tables to force mysqld to start using the new table.

Maintaining a MySQL installation
********************************

テーブルのメンテナンス、クラッシュからの修復のための myisamchk 使用
=======================================

Starting with MySQL 3.23.13, you can check tables MyISAM with the CHECK TABLE command. See CHECK TABLE.  You can repair tables with the REPAIR TABLE command. See REPAIR TABLE.

MyISAM テーブル (.MYI and .MYD) の検査・修復には myisamchk を使用します。 ISAM テーブル (.ISM and .ISD) の検査・修復には isamchk を使用します。 See Table types.

以下の文は myisamchk について述べていますが、isamchk にもすべて当てはまります。

myisamchk ユーティリティは、データベースのテーブルの情報を得たり、チェックしたり、テーブルの修復や最適化に使用します。以下のセクションでは、 myisamchk の起動方法(オプションの説明も含む)、テーブルの保守スケジュールのたて方、 myisamchk の色々な機能の使い方を述べます。

もし mysqld を --skip-locking で走らせているなら、 (これは Linux など、いくつかのシステムでデフォルトです)、 mysqld があるテーブルを使用しているとき、あなたは同じテーブルに対して myisamchk で確実に検査できません。もし myisamchk 中に、だれも mysqld を通してそのテーブルをアクセスしないのが確実なら、テーブルを検査する前に mysqladmin flush-tables を行うべきです。そうでない場合、テーブルの検査中は mysqld を落とすべきです。もし mysqld がテーブルを更新中に myisamchk を実行した場合、テーブルが変更された旨のワーニングがでるでしょう。

もし --skip-locking を使用していないなら、いつでも myisamchk は使用できます。これを実行している間、全てのテーブルを更新するクライアントは myisamchk が準備できるまで待ちます。

もし myisamchk をテーブルの修復、最適化に使用するなら、その最中に、 mysqld がそのテーブルを絶対に使用しないようにしなければなりません。これは --skip-locking を使用している場合に起こりえます。もし mysqld をダウンさせていないなら、最低 myisamchk 実行前に、 mysqladmin flush-tables を実行すべきです。

テーブルの修復と最適化のために、ほとんどの場合、 OPTIMIZE TABLES コマンドが使用できます。しかしこれは myisamchk に比べて、遅くて確実でもありません。(fatal error発生時の場合)。これはその反面、使用方法が簡単でテーブルのフラッシュを気にかける必要がありません。 See OPTIMIZE TABLE.

myisamchk 起動構文
==============

myisamchk は以下のようにして起動します:

     shell> myisamchk [options] tbl_name

options に、あなたが myisamchk にさせたいことを指定します。その説明は後述します。(myisamchk --help と実行すれば、オプションの一覧が取れます)。オプションがなければ、 myisamchk は単にテーブルを検査するだけです。より多くの情報を得たい、あるいは、 myisamchk に誤り訂正の行動を取らせる事については、後述します。

tbl_name は検査したいテーブル名です。もしどこか違うディレクトリにあるデータベースに対して myisamchk を走らせたいなら、 myisamchk にはファイルがどこにあるかわからないので、ファイルのパスを指定しなければなりません。実際、 myisamchk はあなたが使用しているファイルがデータベースのディレクトリにあるかどうかは考慮しません；ほかの場所にデータベーステーブルのファイルをコピーし、そのコピーしたファイルに対して回復操作を実行することができます。

myisamchk コマンドラインには、複数のテーブル名が指定できます。また、インデックスファイル名(.MYI 接尾語のついたファイル)も指定でき、さらに *.MYI とすれば、ディレクトリ内の全てのテーブルが指定できます。例えば、現在のカレントディレクトリがデーターベースディレクトリならば、そのディレクトリ内の全てのテーブルは、以下のようにして検査できます：

     shell> myisamchk *.MYI

データベースディレクトリに入っていない場合、パスを指定することにより全てのテーブルが検査できます：

     shell> myisamchk /path/to/database_dir/*.MYI

MySQL データディレクトリのパスにワイルドカードを使用することにより、データベースの全てのテーブルも検査できます：

     shell> myisamchk /path/to/datadir/*/*.MYI

myisamchk は以下のオプションを持ちます:

-a, --analyze
     キーの分布(配置)を分析します。これは MySQL のいくつかの結合を速くします。

-#, --debug=debug_options
     デバッグログの出力。 debug_options はよく 'd:t:o,filename' とされます。

-d, --description
     テーブルに関するいくらかの情報を表示します

-e, --extend-check
     テーブルを非常に徹底的に検査します。極端な場合にだけで必要とされます。通常 myisamchk は、このオプションなしで全てのエラーを見つけるはずです。

-f, --force
     古い一時的なファイルを上書きします。 myisamchk を -r なしで走らせてテーブルを検査しているときに、 -f を使用するならば、 myisamchk はチャックでエラーが出たテーブルに対して、自動的に -r を伴って、検査を再開します。

--help
     ヘルプを表示して終了。

-i, --information
     検査されたテーブルの統計情報を表示。

-k #, --keys-used=#
     -r と共に使用します。 NISAM テーブルハンドラーに最初の # インデックスだけを更新するように指示します。 If you are using MyISAM tells which keys to use, where each binary bit stands for one key (First key is bit 0). これはインサートを速くします！非アクティブになったインデックスは、myisamchk -r を使用すれば再びアクティブになります。

-l, --no-symlinks
     修復時にシンボリックリンクを追いません。通常、myisamchk はシンボリックリンクが指し示すテーブルも修復します。

-q, --quick
     -r と共に使用され、修復を早く行います。通常、オリジナルのデータファイルは検査されません；二回 -q を指定すると、強制的にオリジナルのデータファイルも使用します。

-r, --recover
     修復モード。 Can fix almost anything except unique keys that aren't unique (which is a extremely unlikely error with ISAM/MyISAM tables). If you want to recover a table, this is the option to try first. Only if myisamchk reports that the table can't be recovered by -r, you should then try -o.  (Note that in the unlikely case that -r fails, the data file is still intact).

-o, --safe-recover
     修復モード。古い修復方法を使用します (reads through all rows in order and updates all index trees based on the found rows)；これは -r よりも遅いですが、 -r が扱えないものも扱えます。 Normally one should always first repair with -r and only if this fails use -o.

-O var=option, --set-variable var=option
     変数に値を入れます。可能な変数は後述します。

-s, --silent
     静粛モード。エラーのみを出力します。二度 -s を指定すると(-ss)、myisamchk はほとんど出力をしなくなります。

-S, --sort-index
     インデックスブロックのソート。これは、アプリケーションでの ``read-next'' を速くします。

-R index_num, --sort-records=index_num
     インデックスに従ってソート。これはあなたのデータをよりよく配置し、このインデックスへの SELECT, ORDER BY オペレーションを速くします。 (この操作の最初のソートは非常に遅くなるかもしれません！) テーブルのインデックスの番号をみつけるには SHOW INDEX を使用しますが、これは myisamchk がテーブルのインデックスを見つけるのと同じ順序で行います。インデックス番号は 1 から始まります。

-u, --unpack
     pack_isam でパックされたテーブルをアンパックします。

-U, --update-status
     Store in the .MYI file when the table was checked and if the table was crashed.  This should be used to get full benefit of the --fast option, but you shouldn't use this if option if the mysqld server is using the table and you are running mysqld with --skip-locking.

-v, --verbose
     冗長モード。より多く情報を出力します。 -d と -e オプションと共に使用できます。 -v を複数指定すると(-vv, -vvv)、もっと出力が多くなります！

-V, --version
     myisamchk バージョンを表示して終了。

-w, --wait
     テーブルがロックされていたら待ちます。

--set-variable (-O) オプションで可能な変数：

     key_buffer_size       current value: 16776192
     read_buffer_size      current value: 262136
     write_buffer_size     current value: 262136
     sort_buffer_size      current value: 2097144
     sort_key_blocks       current value: 16
     decode_bits           current value: 9

key_buffer_size is only used when you check the table with -e or repair it with -o. sort_buffer_size is used when you repair the table with -r.

If you want a faster repair, set the above variables to about 1/4 of your available memory.  You can set both variables to big values as only one of the above buffers will be used at at time.

myisamchk メモリ使用
===============

myisamchk を走らす上でメモリーの配分は重要です。 myisamchk は -O オプションで定義した以上のメモリは使用しません。とても大きなファイルのたいして myisamchk をかけたいなら、メモリーをどれくらい使用するかを最初に決めなくてはなりません。デフォルトは固定で約 3M だけを使用します。大きな値を使用することで、 myisamchk をより速く動作できます。例えば、32MBytesのRAMがあるなら、以下のように指定できます (他のオプションも指定して):

     shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

-O sort=16M の使用は多くの場合おそらく十分でしょう。

しかし、myisamchk は TMPDIR 内に一時ファイルを使用します。 TMPDIR がメモリファイルシステムを指している場合は、簡単に out of memory エラーを得るでしょう。 If this happens, set TMPDIR to point at some directory with more space and restart myisamchk

テーブルの保守体制の設定
============

問題が発生するまで待つより、定期的にテーブルを検査する方がよりよい考えです。保守目的には、myisamchk -s でテーブルを検査するのがよいでしょう。 -s オプションはサイレントモードなので、エラーが起きた場合にだけメッセージを出力します。

サーバーを開始するときにテーブルを検査するのもよい考えです。例えば、更新最中にマシンがリブートされたなら、全てのテーブルに関してその影響がないか検査する必要があります。（これは``expected crashed table''です）リブート後にもし古い .pid ファイル(プロセスID) があるならば、 24時間以内に変更されたテーブルに対して myisamchk を走らせて検査させるように、 safe_mysqld にテストを追加しても構いません。 (.pid ファイルは mysqld 起動時に作られ、通常修了時に消されます。スタート時に .pid ファイルが存在するなら mysqld が異常終了したことを示します。)

良いテストは、.pid ファイルの作成時間以降に変更された全てのテーブルを検査するテストです。

通常のシステム運用中にもテーブルを検査すべきです。 TcX では、週に一度、 cron を使用して重要なテーブルを検査しています。 crontab ファイルには以下のように記述します：

     35 0 * * 0 /path/to/myisamchk -s /path/to/datadir/*/*.MYI

これは壊れたテーブルの情報を出力しますので、必要とあらば検査、修復が行えるわけです。

予想外の事故で壊れたテーブル(ハードウェアのトラブルが原因で崩壊)を除き、 2,3年間、テーブルは壊れたことはありません(これは本当に本当です)。ので、一週間に一度のチェックでも十分です。

24時間以内に変更された全てのテーブルに対して、 myisamchk -s を毎晩実行する事を勧めます。そうすれば、あなたは我々と同じぐらいに MySQL を信頼することになります。

テーブル情報取得
========

テーブルから詳細/統計を得るためには、次の方法を使用します。後でさらに詳細な情報をいくつか説明します。

myisamchk -d tbl_name
     myisamchk を ``describe mode'' で実行し、テーブルの説明記述を作ります。 --skip-locking を指定して MySQL サーバーを起動した場合、 myisamchk は myisamchk 実行中に更新されたテーブルについてエラーを報告します. しかし myisamchk は describe mode ではテーブルを変えないので、データを破壊する危険性はありません。

myisamchk -d -v tbl_name
     myisamchk がしていることに関する、より多くの情報を作り出すには、 -v をつけて冗長モードで走らせるようにします。

myisamchk -eis tbl_name
     テーブルから最も重要な情報だけを示します。テーブル全体を読まなければならないので、遅いです。

myisamchk -eiv tbl_name
     -eis と似ているが、何を行っているかを表示します。

myisamchk -d 出力の例:

     ISAM file:     company.MYI
     Data records:           1403698  Deleted blocks:         0
     Recordlength:               226
     Record format: Fixed length

     table description:
     Key Start Len Index   Type
     1   2     8   unique  double
     2   15    10  multip. text packed stripped
     3   219   8   multip. double
     4   63    10  multip. text packed stripped
     5   167   2   multip. unsigned short
     6   177   4   multip. unsigned long
     7   155   4   multip. text
     8   138   4   multip. unsigned long
     9   177   4   multip. unsigned long
         193   1           text

myisamchk -d -v 出力の例:

     ISAM file:     company.MYI
     Isam-version:  2
     Creation time: 1996-08-28 11:44:22
     Recover time:  1997-01-12 18:35:29
     Data records:           1403698  Deleted blocks:              0
     Datafile: Parts:        1403698  Deleted data:                0
     Datafilepointer (bytes):      3  Keyfile pointer (bytes):     3
     Max datafile length: 3791650815  Max keyfile length: 4294967294
     Recordlength:               226
     Record format: Fixed length

     table description:
     Key Start Len Index   Type                      Root Blocksize Rec/key
     1   2     8   unique  double                15845376      1024       1
     2   15    10  multip. text packed stripped  25062400      1024       2
     3   219   8   multip. double                40907776      1024      73
     4   63    10  multip. text packed stripped  48097280      1024       5
     5   167   2   multip. unsigned short        55200768      1024    4840
     6   177   4   multip. unsigned long         65145856      1024    1346
     7   155   4   multip. text                  75090944      1024    4995
     8   138   4   multip. unsigned long         85036032      1024      87
     9   177   4   multip. unsigned long         96481280      1024     178
         193   1           text

myisamchk -eis 出力の例:

     Checking ISAM file: company.MYI
     Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
     Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
     Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
     Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
     Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
     Total:    Keyblocks used:  98%  Packed:   17%

     Records:          1403698    M.recordlength:     226   Packed:             0%
     Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
     Recordblocks:     1403698    Deleteblocks:         0
     Recorddata:     317235748    Deleted data:         0
     Lost space:             0    Linkdata:             0

     User time 1626.51, System time 232.36
     Maximum resident set size 0, Integral resident set size 0
     Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
     Blocks in 0 out 0, Messages in 0 out 0, Signals 0
     Voluntary context switches 639, Involuntary context switches 28966

myisamchk -eiv 出力の例:

     Checking ISAM file: company.MYI
     Data records: 1403698   Deleted blocks:       0
     - check file-size
     - check delete-chain
     index  1:
     index  2:
     index  3:
     index  4:
     index  5:
     index  6:
     index  7:
     index  8:
     index  9:
     No recordlinks
     - check index reference
     - check data record references index: 1
     Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
     - check data record references index: 2
     Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
     - check data record references index: 3
     Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
     - check data record references index: 4
     Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
     - check data record references index: 5
     Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     - check data record references index: 6
     Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     - check data record references index: 7
     Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     - check data record references index: 8
     Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
     - check data record references index: 9
     Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
     Total:    Keyblocks used:   9%  Packed:   17%

     - check records and index references
     [LOTS OF ROW NUMBERS DELETED]

     Records:          1403698    M.recordlength:     226   Packed:             0%
     Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
     Recordblocks:     1403698    Deleteblocks:         0
     Recorddata:     317235748    Deleted data:         0
     Lost space:             0    Linkdata:             0

     User time 1639.63, System time 251.61
     Maximum resident set size 0, Integral resident set size 0
     Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
     Blocks in 4 out 0, Messages in 0 out 0, Signals 0
     Voluntary context switches 10604, Involuntary context switches 122798

上で使用されたテーブルのデータファイルサイズをここに示します:

     -rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.ISD
     -rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.ISM
     -rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
     -rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYI

myisamchk が生成する情報の説明を以下に示します。 ``keyfile'' はインデックスファイルです。 ``Record'' と ``row'' は同義です。

ISAM file
     ISAM (index) ファイルの名前

Isam-version
     ISAM 形式のバージョン。現在は常に 2 。

Creation time
     データファイルが生成された時。

Recover time
     インデックス/データファイルが最後に再構築された時。

Data records
     レコード/行の数。

Deleted blocks
     予約された領域をまだ持っている削除ブロック数。このスペースを最小にするために自分のテーブルを最適化することができます。 See Optimization.

Datafile: Parts
     動的なレコード形式にいくつのデータブロックがあるかを表示します。分割なしで最適化されたテーブルでは Data records と同じです。

Deleted data
     改善されていない削除データのバイト数。このスペースを最小にするために自分のテーブルを最適化することができます。 See Optimization.

Datafile pointer
     データファイルポインタの大きさ(バイト数)。これは普通 2, 3, 4 または 5 バイトです。多くのテーブルは 2 バイトで管理されますが、これはまだ MySQL から制御できません。固定テーブルではこれはレコードアドレスです。動的テーブルではこれはバイトアドレスです。

Keyfile pointer
     データファイルポインタのバイト数。これは普通 1, 2 または 3 バイトです。多くのテーブルは 2 バイトで管理されますが、これは MySQL では自動的に計算されます。これは常にブロックアドレスです。

Max datafile length
     テーブルのデータファイル (.MYD ファイル) が獲得できる長さ (バイト数)。

Max keyfile length
     テーブルのキーファイル (.MYI ファイル) が獲得できる長さ (バイト数)。

Recordlength
     各レコード/行が使用する領域の大きさ(バイト数)。

Record format
     各テーブルの行が持つ形式。この例では Fixed length を使用します。他の値で可能な物は圧縮、パックします。

table description
     テーブル内の全てのキーのリスト。各キーについて、いくつかの低レベル情報が提供されます:

     Key
          このキー番号。

     Start
          このインデックス部が開始するレコード/行内の位置。

     Len
          インデックス部の長さ。パックされた数値では、これは常に項目の完全な長さになります。

          文字型においては、文字型の項目の頭の部分にインデックスがつく事になりますので、インデックス項目の最大長さよりもこの値は短くなるでしょう。

     Index
          unique or multip. (multiple). このインデックス内では1つの値が複数回存在し得ます。

     Type
          このインデックス部が持つデータ型。これは NISAM データ型で、 packed, stripped か empty オプションを持ちます。

     Root
          ルートインデックスブロックのアドレス。

     Blocksize
          各インデックスブロックのサイズ。これはデフォルトでは 1024 ですが、コンパイル時に変更できます。

     Rec/key
          これはオプティマイザによって使用される統計値です。このキーの値ごとのレコード数を知らせます。ユニークキーは常に1の値を持ちます。これはテーブルがロードされた(または大きく変更された)後に myisamchk -a で更新されます。これが全く更新されない場合はデフォルト値の 30 が与えられます。

     上の最初の例では、9番目のキーは2つの部分をもったマルチパートキーです。

Keyblocks used
     使用されたキーブロックのパーセンテージ。このテーブルは myisamchk で再配置されるため、値はとても高くなります (理論的な最大にとても近くなります)。

Packed
     MySQL は一般の接尾辞でキーのパックを試みます。これは CHAR/VARCHAR/DECIMAL キーでだけ使用できます。名前のような長い文字列では、これは使用領域を顕著に減らします。上の三番目の例では4番目のキーが10文字長で、領域の60%の減少を得ます。

Max levels
     このキーの Btree の深さ。長いキーを持つ大きなテーブルは高い値を得ます。

Records
     テーブルが持っている行数。

M.recordlength
     平均の行長。固定テーブルでは、これはレコード長です。

Packed
     MySQL は文字列の最後から空白を除きます。これによって節約されたパーセンテージを Packed は示します。

Recordspace used
     データファイルが使用されたパーセンテージ。

Empty space
     データファイルが使用されていないパーセンテージ。

Blocks/Record
     レコード毎のブロック数 (i.e., 断片化レコードの構成数)。これは固定形式テーブルでは常に1です。この値は可能な限り 1.0 に留まります。これが大きすぎる場合は、myisamchk でテーブルを再配置できます。 See Optimization.

Recordblocks
     使用されたブロック (links) 数。固定型式ではこれはレコード数と同じです。

Deleteblocks
     削除されたブロック (links) 数。

Recorddata
     データファイル中にある実際のユーザデータのバイト数。

Deleted data
     データファイル中にある削除された(unused)データのバイト数。

Lost space
     レコードがより短い長さに更新された場合、いくつかの領域が失われます。これはそのような消失の全ての合計です。in bytes.

Linkdata
     動的形式の使用時、ブロックはポインタ(4〜7バイト)にリンクされます。Linkdataはそのポインタの全ての合計です。

テーブルが pack_isam で圧縮されているなら、myisamchk -d はそれぞれのテーブルコラムに関する追加情報を出力します。 myisampack. を参照してください。この情報例と説明記述の意味があります。

Using myisamchk for crash recovery
==================================

MySQL がデータ格納に使用するファイル形式は、広範囲にわたってテストされました。が、データベースのテーブルが破壊されるかもしれない外的状況があります:

  * mysqld プロセスが書き込み再中に killed された場合

  * 予期せぬコンピュータの停止(例えば電源が切られた場合)

  * ハードウェアエラー

本節では、MySQL のデータの扱い方、検査の方法を述べます。もしテーブルがたくさんダメになるのであれば、あなたは、この理由を見つけるよう試みるべきです! See Debugging server.

破壊からの修復をする場合、”データベース内のそれぞれのテーブル tbl_name は、データベースディレクトリ内にある三つのファイルに一致する”、これを理解する事はとても重要です：

File   Purpose
tbl_name.frm   Table definition (form) file
tbl_name.MYD   Data file
tbl_name.MYI   Index file

これら三つのファイルは様々な方法で破壊を受ける事がありますが、この場合最も問題が起こりやすいのは、データファイルとインデックスファイルです。

myisamchk は .MYD ファイル(データ)のコピーを一行一行おこないます。この修理過程の最後に、古い .MYD ファイルを消し、新しいファイルをオリジナルの名前に変更します。もし --quick オプションを使用したなら、myisamchk は .MYD ファイルの一時ファイルを作りません。そのかわり、.MYD ファイルが正しいと仮定して新しいインデックスファイルだけを作ります。この時 .MYD ファイルはいじりません。この場合、myisamchk は自動で .MYD ファイルの間違いを検出して修復を中止するので、安全です。

myisamchk に二つ --quick オプションを指定することもできます。この場合、myisamchk はいくつかのエラー(キーの重複とか)では中止はしません。かわりに .MYD ファイルを変更します。

通常の修理を実行するためにディスクのスペースの空きが少ししか無い場合に限って、 --quick の二回指定が役に立ちます。この場合,あなたは myisamchk を走らせる前にバックアップを少なくともとるべきです。

テーブルのエラーチェック方法
--------------

テーブルをチェックするには,以下のコマンドを使用してください:

myisamchk tbl_name
     これはすべての誤りの99.99%を見つけます。これが見つけることができない物は、データファイルの破壊だけです (これは非常にまれ)。もしテーブルをチェックしたいなら、オプションなしで myisamchk を走らすか、-s or --silent オプションをつけます。

myisamchk -m tbl_name
     This finds 99.999% of all errors. It checks first all index for errors and then it reads through all rows. It calculates a checksum for all keys in the rows and verifies that they checksum matches the checksum for the keys in the index tree.

myisamchk -e tbl_name
     これは全てのデータを完璧に徹底的にチェックします。 (-e は ``extended check'' の意)。全てのキーについて、それらがさす行が正しいかを確認するために、読み込みチェックを行います。これはたくさんのキーがある大きなテーブルでは、凄く時間がかかります。 myisamchk は通常、最初のエラーが見つかった時点で止まります。もしより情報が得たいなら、--verbose (-v) オプションを加えます。これは myisamchk をエラーが20個出るまで動作させ続けます。普通に使用する場合は、myisamchk だけで十分です。(テーブル名以外の引数は一切無し)

myisamchk -e -i tbl_name
     前のコマンドと似ていますが、 -i オプションは myisamchk にいくらかの統計情報を出させるようにします。

テーブルの修復方法
---------

テーブル破壊の兆しとして、クエリが予期せず中断したり、以下のようなエラーが出たりします：

  * tbl_name.frm is locked against change

  * Can't find file tbl_name.MYI (Errcode: ###)

  * Got error ### from table handler (Error 135 is an exception in this case)

  * Unexpected end of file

  * Record file is crashed

これらの場合、あなたは自分のテーブルを修理しなければなりません。 myisamchk はほとんどの問題を見つけ出し修正します。

修復過程は以下で記述する最大4つの段階を踏みます。これを始める前に、あなたはデータベースディレクトリに cd してテーブルファイルのパーミッションを確認すべきです。これらファイルは mysqld を実行しているUnixユーザーが読み込み可能であるようにしてください(検査のするのにあなたにファイルのアクセス権も必要)。もしファイルの変更をする必要があるならば、ファイルへの書き込み許可も必要です。

If you are using MySQL 3.23.16 and above you can (and should) use the CHECK and REPAIR commands to check and repair MyISAM tables. See CHECK TABLE. See REPAIR TABLE.

The manual section about table maintenence includes the options to isamchk/myisamchk. See Table maintenance.

The following section is for the cases where the above command fails or if you want to use the extended features that isamchk/myisamchk provides.

If you are going to repair a table from the command line, you must first take down the mysqld server. Note that when you do mysqladmin shutdown on a remote server, the mysqld server will still be alive for a while after mysqladmin returns until all queries are stopped and all keys have been flushed to disk.

Stage 1: テーブルをチェックする

myisamchk *.MYI (時間がかかってもよいなら myisamchk -e *.MYI) を実行します。 -s (silent) オプションは不要な情報の出力をおさえます。

If the mysqld server is done you should use the --update option to tell myisamchk to mark the table as 'checked'.

myisamchk がエラーを返した場合にだけ、テーブルを修復する必要があります。この場合、Stage 2 へ進みます。

チェック時に奇妙なエラー(out of memory エラーのような) が起きた場合、あるいは myisamchk が落ちた場合、Stage 3 に進んでください。

Stage 2: 簡単で安全な修復

まず最初に myisamchk -r -q tbl_name を試みてください (-r -q は ``quick recovery mode''の意)。これはデータファイルに触れないでインデックスファイルの修理を試みます。もしデータファイルが全てとデータファイル中の正しい場所での削除リンクポイントを含んでいるなら、これは動作してテーブルを修復します。成功後、次のテーブルの修復に進んでください。失敗した場合は、以下の手順で試みてください：

 1. 続ける前にデータファイルをバックアップしてください。

 2. myisamchk -r tbl_name を使用します(-r は ``recovery mode''の意)。これは不正なレコードと削除されたレコードをデータファイルから消去し、インデックスファイル(.MYI)を再構築します。

 3. 上記が失敗した場合、myisamchk --safe-recover tbl_name を使用して下さい。 Safe recovery モードは古い方法を使用して修復します。これは普通の修復モードでは行わない操作をいくつかもっています。(遅いですが)

チェックまたは修復時に、メモリ不足のような妙なエラーがでた場合、または myisamchk がクラッシュした場合は、Stage 3 に進んでください。

Stage 3: 難しい修復

インデックスファイル(.MYI)の最初の 16K ブロックが破壊された場合、または不正な情報を含む場合、またはインデックスファイルがない場合にだけ、本修復段階を経ます。この場合、新しいインデックスファイルファイルを作成する必要があります。次のようにしてください:

 1. データファイル .MYD ファイルをどこか安全場所に移動します。

 2. 新しい空のデータとインデックスファイルを作るために、テーブルディスクリプタファイルを使用します：

          shell> mysql db_name
          mysql> DELETE FROM tbl_name;
          mysql> quit

 3. 古いデータファイルを新しく作ったデータファイルにコピーします。 (古いデータファイルを move してはいけません；なんら頭の問題が起きます)

Stage 2 に戻ってください。 myisamchk -r -q は既に動作します。 (これは無限ループにはなりません).

Stage 4: とても難しい修復

これは、ディスクリプタファイル(.frm)もクラッシュした場合にだけ発生します。これは発生することはありません。なぜならディスクリプタファイルはテーブルが生成された後に書かれることはないからです。

 1. ディスクリプタファイルをバックアップからリストアして、Stage 3 に戻ってください。インデックスファイルのリストアもできます。そして Stage 2 に戻ってください。後者の場合、myisamchk -r で開始すべきです。

 2. バックアップを持っていなくても、テーブルがどのように作成されたかを正確に知っていれば、他のデータベース内にテーブルのコピーを生成します。新しいデータファイルを削除し、先ほど作ったデータベースの中のディスクリプタファイルとインデックスファイルを、壊れたデータベース内に移動します。これは新しいディスクリプタファイルとインデックスファイルを与えることになりますが、データファイルはそのまま残っています。 Stage 2 に進み、インデックスファイルの修復を行ってください。

テーブルの最適化
--------

断片化されたレコードの結合と、レコードの削除と更新から生じる無駄なスペースの排除、これら行うには、修復モード(recovery mode)で myisamchk を実行します：

     shell> myisamchk -r tbl_name

SQL OPTIMIZE TABLE でも同様にテーブルを最適化できます。 OPTIMIZE TABLE は簡単ですが、 myisamchk の方が速いです。

myisamchk には、あなたがテーブルの性能を向上させるのに使用することができる他の多くのオプションがあります:

-S, --sort-index
     インデックスツリーブロックのソート。降順にソートします。これはシーク(seek)を最適化し、キーを使用したテーブルの走査(scan)を速くします。

-R index_num, --sort-records=index_num
     インデックスによるソート。これはあなたのデータをより良く配置し、このインデックスを使用した SELECT , ORDER BY 操作を速くします。 (最初にこれを実行してソートするときは時間がとてもかかります！) テーブルのインデックス番号を見つけるために、 SHOW INDEX を使用します。これは myisamchk が行うのと同様の順でテーブルのインデックスを表示します。インデックス番号は 1 から開始されます。

-a, --analyze
     テーブル内のキー配置の分析。このテーブルからレコードを取得する際に、結合(join)のパフォーマンスを向上させます。

For a full description of the option see myisamchk syntax.

Log file maintenance
====================

MySQL をログファイルとともに使用する場合、あなたは、時々古いログファイルを リムーブ/バックアップ し、 MySQL に新しいファイルにログを取るように指示したいと思うことでしょう。 See Update log.

Redhat Linux においては、mysql-log-rotate スクリプトをこれに使用できます。 もし RPM ディストリビューションの MySQL をインストールしたなら、このスクリプトは自動でインストールされているはずです。

他のシステムでは、自分自身で短いスクリプトをインストールします。 cron でログファイルを扱うようにします。

mysqladmin flush-logs コマンドか FLUSH LOGS SQL文で、 MySQL に新しいログファイルを使用させることが出来ます。もしあなたが MySQL 3.21 を使用しているなら、 mysqladmin refresh を使用しなくてはなりません。

上記のコマンドは、以下のように動作します：

  * もし通常のログ (--log) が使用されているならば、このログファイルを一度閉じてから再び開きます。 (mysql.log がデフォルトのログファイル).

  * もし更新ログ (--log-update) を使用しているなら、更新ログを閉じ、新しいログファイルを開きます。そのさい、ログファイルについている番号は増えます。

もし更新ログだけを使用しているなら、あなたは、ログを flush するだけでよくて、その時、バックアップのため古い更新ログファイルを移動します。もし普通のログを使っていれば、あなたは以下のようにすることができます:

     shell> cd mysql-data-directory
     shell> mv mysql.log mysql.old
     shell> mysqladmin flush-tables

こうしておいて、mysql.old をバックアップし削除します。.

MySQL への新しい関数の追加
****************

MySQLに新しい関数を追加するには2つの方法があります:

  * ユーザ定義関数(UDF:user-definable function)インタフェースを通して関数を追加できます。ユーザ定義関数は、CREATE FUNCTION と DROP FUNCTION ステートメントを使用して、動的に追加、削除されます。 See CREATE FUNCTION.

  * ネイティブ(ビルトイン) MySQL 関数として関数を追加できます。ネイティブ関数は mysqld サーバに統合され、恒久的に有効になります。

それぞれの方法には、有利な点と不利な点があります:

  * ユーザ定義関数を書く場合、サーバ自身に追加するオブジェクトファイルをインストールする必要があります。関数をサーバに統合する場合あそれを行なう必要はありません。

  * UDF をバイナリ MySQL 配布に追加することができます。ネイティブ関数はソース配布の変更が必要です。

  * MySQL 配布をアップグレードする場合、前にインストールされた UDF の使用を継続できます。ネイティブ関数では、アップグレードの度に変更を繰り返す必要があります。

新しい関数を追加するためにどちらの方法を使用しても、ABS() や SOUNDEX() のようなネイティブ関数と同じように使用することができます。

新しいユーザ定義関数の追加
=============

UDF 機構が動作するためには、関数は C か C++ で書かれる必要があり、OS が動的ローディングをサポートする必要があります。MySQL ソース配布は sql/udf_example.cc を含んでいて、これは５つの新しい関数を定義しています。UDF の呼び出し方法がどのように働くかはこのファイルを参考にしてください。

SQL ステートメントで使用したいそれぞれの関数について、対応する C (または C++) 関数を定義すべきです。下の説明では、名前 ``xxx'' がサンプル関数名として使用されています。SQL と C/C++ 使用法を distinquish するために、 XXX() (大文字) は SQL 関数呼び出しを表わし、xxx() (小文字) は C/C++ 関数呼び出しを表わします。

XXX() のインタフェースを実装するために書く C/C++ 関数は:

xxx() (必要)
     メイン関数。これは関数結果が計算されるところです。SQL 型と C/C++ 関数の戻り値型の対応は次に示します:

     SQL 型   C/C++ 型
     STRING       char *
     INTEGER      long long
     REAL         double

xxx_init() (オプション)
     xxx() の初期化関数。これは次のように使用されます:

       * XXX() の引数の数のチェック

       * 引数が要求される型かどうかのチェック、また、メイン関数が呼ばれる時に望む型に引数を強制するように MySQL に伝える

       * メイン関数が必要とするメモリの割り当て

       * 結果の最大長の指定

       * (REAL 関数では) 小数部の最大桁数の指定

       * 結果が NULL になり得るかどうかの指定

xxx_deinit() (オプション)
     xxx() の終了関数(deinitialization function)。これは初期化関数によって割り当てられたメモリを解放すべきです。

SQL ステートメントが XXX() を呼び出すとき、MySQL は引数チェックやメモリ割り当てのように、必要なセットアップを行なわせるために、初期化関数 xxx_init() を呼び出します。xxx_init() がエラーを返す場合、SQL ステートメントはエラーメッセージと共に異常終了し、メイン関数と終了関数は呼び出されません。そうでなければ、メイン関数 xxx() が各行毎に呼び出されます。全ての行が処理された後、終了関数 xxx_deinit() が、必要な掃除を行なうために、呼び出されます。

全ての関数はスレッド安全でなくてはいけません(メイン関数だけでなく、初期化関数と終了関数も同様です)。これは変更されうるグローバル変数や静的変数を割り当てることは許されないことを意味します！ メモリが必要な場合は、 xxx_init() で割り当て、xxx_deinit() でそれを解放すべきです。

UDF 呼び出しシーケンス
-------------

メイン関数は下に示すように宣言されるべきです。戻り値型と引数は、 CREATE FUNCTION ステートメントで、SQL 関数 XXX() の戻り値をSTRING, INTEGER, REAL のどれに宣言するかに依存して異なることに注意してください:

STRING 関数では:

     char *xxx(UDF_INIT *initid, UDF_ARGS *args,
                   char *result, unsigned long *length,
                   char *is_null, char *error);

INTEGER 関数では:

     long long xxx(UDF_INIT *initid, UDF_ARGS *args,
                   char *is_null, char *error);

REAL 関数では:

     double xxx(UDF_INIT *initid, UDF_ARGS *args,
                   char *is_null, char *error);

初期化と終了関数は次のように宣言します:

     my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

     void xxx_deinit(UDF_INIT *initid);

initid 引数は３つの関数全てに渡されます。これは UDF_INIT 構造体を示し、関数間で情報を伝達するために使用されます。UDF_INIT 構造体のメンバは下に一覧します。初期化関数は変更したい全てのメンバを埋めるべきです。(メンバにデフォルトを使用するには、未変更のままにしてください。)

my_bool maybe_null
     xxx() が NULL を返す場合、xxx_init() は maybe_null を 1 に設定すべきです。デフォルト値は、引数のいずれかが maybe_null として宣言された場合、1 です。

unsigned int decimals
     小数部の桁数。デフォルト値はメイン関数に渡される引数の小数部の最大桁数です。(例えば、関数に 1.34, 1.345, 1.3 が渡された場合、デフォルトは 3 です。1.345 が 3 桁の小数部を持つためです。)

unsigned int max_length
     文字列結果の最大長。デフォルト値は関数の戻り値型に依存して異なります。文字列関数では、デフォルトは最も長い引数の長さです。整数関数では、デフォルトは 21 桁です。実数関数では、デフォルトは 13 に initid->decimals で示される小数部の桁数を加えたものです。(数値関数では、長さは符号と小数点文字を含みます。)

char *ptr
     それ自身の目的のために関数が使用できるポインタです。例えば、関数は割り当てたメモリを関数間で伝達するために、initid->ptr を使用できます。 xxx_init() では、メモリを獲得し、このポインタに割り当てます:

          initid->ptr = allocated_memory;

     xxx() と xxx_deinit() では、initid->ptr を参照して、メモリを使用または解放します。

引数処理
----

args 引数は次に示すメンバを持つ UDF_ARGS 構造体へのポインタです:

unsigned int arg_count
     引数の数。関数が特定の引数の数で呼び出されることを期待する場合は、初期化関数でこの値をチェックしてください。例えば:

          if (args->arg_count != 2)
          {
              strcpy(message,"XXX() requires two arguments");
              return 1;
          }

enum Item_result *arg_type
     引数の型。可能な型の値は STRING_RESULT, INT_RESULT, REAL_RESULT です。

     引数が与えられた型であることと、そうでない場合エラーを返すことを確実にするために、初期化関数で arg_type 配列をチェックしてください。例えば:

          if (args->arg_type[0] != STRING_RESULT
                && args->arg_type[1] != INT_RESULT)
          {
              strcpy(message,"XXX() requires a string and an integer");
              return 1;
          }

     関数の引数が特定の型を要求するための代案として、初期化関数を使用して、 arg_type 要素を求める型に設定できます。これは MySQL に xxx() の各呼び出しにこれらの型を引数に強制するようにさせます。例えば、最初の２つの引数に文字列と整数を強制するように指定するには、 xxx_init() で次を行なってください:

          args->arg_type[0] = STRING_RESULT;
          args->arg_type[1] = INT_RESULT;

char **args
     args->args は、関数が呼ばれる時の引数の一般的な特性について、情報を初期化関数に伝達します。定数引数 i について、 args->args[i] は引数値のをポイントします。(値への正しいアクセス方法については後述。)非定数引数について、args->args[i] は 0 です。定数引数は定数だけを使用する表現で、3, 4*7-2, SIN(3.14) などです。非定数引数は行から行に変更される値を参照する表現で、項目名や非定数引数で呼び出される関数などです。

     メイン関数のそれぞれの呼び出しについて、args->args は現在処理されている行に渡される実際の引数を含んでいます。

     関数は次のように引数 i を参照できます:

       * STRING_RESULT 型の引数は、バイナリデータまたは任意の長さのデータの処理を許すため、文字列ポインタ＋長さとして与えられます。文字列内容は args->args[i] として有効で、文字列長は args->lengths[i] です。文字列は NULL 終端とみなすべきではありません。

       * INT_RESULT 型の引数について、args->args[i] を long long 値にキャストする必要があります:

               long long int_val;
               int_val = *((long long*) args->args[i]);

       * REAL_RESULT 型の引数について、args->args[i] を double 値にキャストする必要があります:

               double    real_val;
               real_val = *((double*) args->args[i]);

unsigned long *lengths
     初期化関数では、lengths 配列は各引数についての最大文字列長を示します。メイン関数の各呼び出しについては、lengths は、現在処理されている行に渡される任意の文字列引数の実際の長さを含んでいます。 INT_RESULT, REAL_RESULT 型の引数については、lengths はまだ引数の最大長を含んでいます(初期化関数については)。

戻り値とエラー処理
---------

初期化関数は、エラーが無い場合は 0 を、そうでなければ 1 を返すべきです。エラーが発生する場合は、xxx_init() は NULL 終端エラーメッセージを message パラメータに格納すべきです。このメッセージはクライアントに返されます。メッセージバッファは MYSQL_ERRMSG_SIZE 文字長ですが、80 文字より小さく保つように試みるべきです。標準的な端末画面の幅にフィットするようにです。

メイン関数 xxx() の返す値は long long と double 関数については関数値です。文字列関数については、result と length 引数で文字列が返されます。result は少なくとも 255 バイト長のバッファです。これらに内容と戻り値の長さを設定してください。例えば:

     memcpy(result, "result string", 13);
     *length = 13;

文字列関数は通常は結果をポイントする値を返します。

メイン関数で NULL 値の戻り値を示すには、is_null を 1 に設定してください:

     *is_null = 1;

メイン関数でエラーの戻り値を示すには、error パラメータを 1 に設定します:

     *error = 1;

xxx() が任意の行について *error に 1 を設定する場合、関数値は現在の行についてと、その後の XXX() が呼び出されるステートメントによって処理される任意の行について NULL です。(xxx() は続く行については呼び出しさえされません。) 注意: 3.22.10 より前の MySQL バージョンでは、*error と *is_null の両方に設定すべきです:

     *error = 1;
     *is_null = 1;

ユーザ定義関数のコンパイルとインストール
--------------------

UDF を実装するファイルはサーバが動作するホスト上でコンパイルされインストールされないければなりません。この処理はサンプル UDF ファイル udf_example.cc について次に説明します。これは MySQL ソース配布に含まれています。このファイルは次の関数を含みます:

  * metaphon() は文字列引数の metaphon 文字列を返します。これは時には soundex 文字列ですが、さらに英語用に調整されています。

  * myfunc_double() は引数の文字の ASCII 値の合計を引数の長さの合計で割った値を返します。

  * myfunc_int() は引数の長さの合計を返します。

  * lookup() はホスト名の IP 番号を返します。

  * reverse_lookup() は IP 番号のホスト名を返します。この関数は文字列 "xxx.xxx.xxx.xxx" または４つの数値とともに呼ばれます。

動的ロード可能ファイルは、次のような何らかのコマンドを使用して、共有オブジェクトファイルとしてコンパイルされるべきです:

     shell> gcc -shared -o udf_example.so myfunc.cc

MySQL ソースツリーの sql ディレクトリ内で次のコマンドを実行することにより、システムのコンパイラオプションを簡単に正しく見つけ出すことができます:

     shell> make udf_example.o

make が表示するものに似たコンパイルコマンドを実行すべきですが、行末近くの -c オプションを取り除いて、-o udf_example.so を行末につけてください。(いくつかのシステムでは、コマンドに -c を残す必要があります。)

UDF を含む共有オブジェクトをコンパイルすると、それをインストールしてそのことを MySQL に知らせる必要があります。udf_example.cc からの共有オブジェクトのコンパイルは、udf_example.so のような何かのファイル名を提供します(実際の名前はプラットフォームによって変わります)。このファイルを /usr/lib のような ld が探すどこかのディレクトリにコピーしてください。多くのシステムでは、LD_LIBRARY または LD_LIBRARY_PATH 環境変数を設定して、UDF 関数ファイルがあるディレクトリを示すことができます。dlopen マニュアルページはシステム上で使用すべき変数を教えてくれます。これを mysql.server または safe_mysqld に設定し、mysqld を再起動すべきです。

ライブラリがインストールされた後、mysqld に新しい関数について次のコマンドで通知すべきです:

     mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so";
     mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so";
     mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so";
     mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
     mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";

関数は DROP FUNCTION を使用して削除できます:

     mysql> DROP FUNCTION metaphon;
     mysql> DROP FUNCTION myfunc_double;
     mysql> DROP FUNCTION myfunc_int;
     mysql> DROP FUNCTION lookup;
     mysql> DROP FUNCTION reverse_lookup;

CREATE FUNCTION と DROP FUNCTION ステートメントは mysql データベース内のシステムテーブル func を更新します。関数の名前、型、共有ライブラリ名はテーブルに保存されます。作成と破棄機能のためには、mysql データベースに insert と delete 権限を持つ必要があります。

既に生成してある関数を追加するために CREATE FUNCTION を使用すべきではありません。関数の再インストールが必要な場合は、DROP FUNCTION でそれを削除し、それから CREATE FUNCTION で再インストールすべきです。例えば、関数の新しいバージョンの再コンパイルをした場合、 mysqld が新しいバージョンを得るために、これを行なう必要があるでしょう。そうでなければ、サーバは古いバージョンの使用を継続します。

mysqld を --skip-grant-tables オプションで起動しなくても、有効な関数はサーバの開始毎に再読み込みされます。この場合、UDF 初期化は飛ばされ、UDF が無効になります。(有効な関数は CREATE FUNCTION でロードされているもので、DROP FUNCTION で削除されていないものです。)

新しいネイティブ関数の追加
=============

ネイティブ関数を追加するためのプロシジャを以下に示します。バイナリ配布にはネイティブ関数を追加できないことに注意してください。プロシジャは MySQL ソースコードの変更を必要とするためです。MySQL をソース配布から自分でコンパイルする必要があります。また、MySQL の他のバージョンに移行する場合(例えば、新しいバージョンがリリースされた時)、新しいバージョンでこのプロシジャを繰り返す必要があります。

新しいネイティブ MySQL 関数を追加するためには、次のステップに従ってください:

 1. sql_functions[] 配列内で関数名を定義している lex.h に１行追加してください。

 2. sql_yacc.yy に２行追加してください。一つは、yacc が定義すべきプリプロセッサシンボルを指示します(これはファイルの先頭に追加すべきです)。それから関数パラメータを定義し、これらのパラメータとともに ``item'' を simple_expr パース規則に追加します。例えば、これがどのように動作するかを見るには、sql_yacc.yy 内の SOUNDEX の全ての出来事をチェックしてください。

 3. item_func.h 内で、関数が数値または文字列のどちらを返すかに依存して、Item_num_func または Item_str_func から継承するクラスを宣言してください。

 4. item_func.cc 内で、数値または文字列のどちらの関数を定義するかに依存して、次の宣言の一つを追加してください:

          double   Item_func_newname::val()
          longlong Item_func_newname::val_int()
          String  *Item_func_newname::Str(String *str)

 5. おそらく次の関数も定義すべきです:

          void Item_func_newname::fix_length_and_dec()

     この関数は与えられた引数に基づいて少なくとも max_length を計算すべきです。max_length は関数が返し得る文字の最大数です。この関数は、メイン関数が NULL 値を返すことがない場合は、maybe_null = 0 も設定すべきです。関数は、引数の maybe_null 変数をチェックすることで、関数の任意の引数が NULL を返しうるかどうかをチェックできます。

全ての関数はスレッド安全である必要があります。

文字列関数については、次のいくつかの追加検討事項があります:

  * String *str 引数は、結果を保持するために使用される文字列バッファを提供します。

  * 関数は結果を保持する文字列を返すべきです。

  * 全ての現在の文字列関数は、絶対に必要でない限り、メモリ割り当てを避けるように試みてください！

Adding new procedures to MySQL
******************************

In MySQL, you can define a procedure in C++ that can access and modify the data in a query before it is sent to the client.  The modification can be done on row by row or GROUP BY level.

We have created an example procedure in MySQL 3.23 to show you what can be done.

Procedure analyse
=================

analyse([max elements,[max memory]])

This procedure is defined in the sql/sql_analyse.cc.  This examines the result from your query and returns an analysis of the results.

  * max elements (default 256) is the maximum number of distinct values analyse will notice per column.  This is used by analyse to check if the optimal column type should be of type ENUM.

  * max memory (default 8192) is the maximum memory analyse should allocate per column while trying to find all distinct values.

     SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])

Writing a procedure.
====================

For the moment, the only documentation for this is the source. :(

You can find all information about procedures by examining the following files:

  * sql/sql_analyse.cc

  * sql/procedure.h

  * sql/procedure.cc

  * sql/sql_select.cc

MySQL ODBC Support
******************

MySQL は MyODBC プログラムで ODBC 機能を提供します。

Operating systems supported by MyODBC
=====================================

MyODBC は 32-bit ODBC (2.50) level 0 driver で、 ODBC 化されたアプリケーションが MySQL に接続する場合に使用します。 MyODBC は、Windows95, Windows98, NT とほとんどの Unix で動きます。

通常、MyODBC は Windows マシンにだけ、インストールします。、あなたのプログラムが ColdFusion のようにデータベースへの接続に ODBC だけを使用する場合に限り、UNIX に MyODBC が必要です。

MyODBC はパブリック・ドメインで、最新の物は以下にあります： http://www.mysql.com/download_myodbc.html.

日本語文字コードに対応させた物は： http://www.SoftAgency.co.jp/.

もし、UNIX に MyODBC をインストールしたいなら、 ODBC マネージャーも必要でしょう。 MyODBC は UNIX の ODBC マネージャーでも動作することが知られています。 MySQL useful links page の ODBC-related links 節に、見つけることができます。 See Useful Links.

Windows/NT の場合、MyODBC をインストール時にいかのようなエラーになるかもしれません:

     An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart Windows
     and try installing again (before running any applications which use ODBC)

The problem in this case is that some other program is using ODBC and because of how windows is designed, one cannot in this case install new ODBC drivers with Microsoft's ODBC setup program. :( これを解決するには、一度 ’セーフモード’でコンピュータを立ち上げ直し、 (windows リブート時に、F8キーを押すことで、セーフモードの選択が可能です) MyODBC をインストールして、リブートします。

  * Windows マシンから UNIX に ODBC アプリケーションを使用して接続するには、まず最初に Windows マシンに MyODBC をインストールしなくてはなりません。

  * UNIX 上の MySQL サーバーに対して、ユーザーと Windows マシンのアクセス許可を与えます。 これは、 GRANT コマンドで可能です。 See GRANT.

  * ODBC DSN を以下のようにして作成しなくてはなりません：

       * Windows マシンのコントロールパネルを開く

       * ODBC アイコンをダブルクリック

       * "ユーサーDSN" をクリック

       * "追加..." ボタンをクリック

       * 新しいデータソース の画面から、MySQL を選び、完了ボタンをクリック。

       * TCX MySQL Driver のデフォルト設定が現れます。 See ODBC administrator.

  * アプリケーションを起動し、コントロールパネルで設定した ODBC DSN を選びます

MyODBC の設定画面には、MySQL 接続時のオプションがいくつか設定できるようになっています。もし問題がある場合は、これらを試します。

ODBC 管理プログラムの各種項目を埋めるには？
========================

Windows95 上のサーバ名の記述には3つの可能性があります:

  * サーバの IP アドレスの使用

  * ファイル \windows\lmhosts への次の情報の追加:

          ip hostname

     例えば：

          194.216.84.21 my

  * DNS を使用するように設定します。

ODBC setup を埋める方法の例:

     Windows DSN name:   test
     Description:        This is my test database
     MySql Database:     test
     Server:             194.216.84.21
     User:               monty
     Password:           my_password
     Port:

Windows DSN name 項目の値は、あなたのwindows ODBC setup における一意の名前です。

ODBC setup 画面で、Server, User, Password, Port フィールドを設定する必要はありません。しかし、ここで設定をすると、後でサーバーに接続する際に、設定した値がデフォルト値として使用されます。使用時に値を変更するオプションはあります。

ポート番号が設定されていないなら、デフォルトポート (default_port) が使用されます。

もしオプションを Read options from C:\my.cnf にすると, client と odbc グループは C:\my.cnf ファイルから読まれます。 mysql_options() で使用できる全てのオプションが利用可能です。 See mysql_options.

MyODBCでの問題をどのように報告すべきか？
=======================

MyODBC は以下でテストされました： Access, Admndemo.exe, C++-Builder, Borland Builder 4, Centura Team Developer (formerly Gupta SQL/Windows), ColdFusion (on Solaris and NT with svc pack 5), Crystal Reports, DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes 4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32 bit, VC++ and Visual Basic.

MyODBC で動作する他のアプリケーションについても知っているなら、 myodbc@lists.mysql.com までメールをください！

With some programs you may get an error like: Another user has modifies the record that you have modified. In most cases this can be solved by doing one of the following things:

  * Add a primary key for the table if there isn't one already.

  * Add a timestamp column if there isn't one already.

  * Only use double float fields. Some programs may fails when they comparing single floats.

If the above doesn't help, you should do a MyODBC trace file and from this try to figure out why things goes wrong.

MyODBCで動作することが知られているプログラム
=========================

多くのプログラムが  MyODBC で動作します。これらは我々自身がテストしたか、または何人かの他のユーザから動作するという確証を得たものです:

Program
     Comment

Access
     Access を動作させるには:

       * テーブルにプライマリキーを設定しなければなりません。

       * 更新可能なテーブルの全てに、timestamp を持たせなければなりません。

       * ダブルフロート型だけが(実数に)使用できます。Accessではシングルフロートと比較は失敗します。

       * MySQL に接続する際は、'Return matching rows' オプションをセットします。

       * NT 上の Access は BLOB フィールドを OLE OBJECTS と認識します。もし MEMO フィールドを代わりに使用したいなら、 ALTER TABLE を使って、 TEXT 型にフィールドを変更しなくてはなりません。

       * Access は DATE フィールドをいつも正しく扱うことが出来ません。もしこれらの問題があった場合、フィールド型を DATETIME に変えてください。

     アクセスは、MySQL が理解できない間違った SQL クエリを作成するかもしれません。 これはアクセスのメニューから "Query|SQLSpecific|Pass-Through" を選択すれば直すことが可能です。

Borland Builder 4
     When you start a query you can use the property Active or use the method Open.  Note that Active will start by automatically issue a SELECT * FROM ... query that may not be a good thing if your tables are big!

ColdFusion (On Unix)
     The following information is taken from the ColdFusion documentation:

     Use the following information to configure ColdFusion Server for Linux to use the unixODBC driver with MyODBC for MySQL data sources.  Allaire has verified that MyODBC version 2.50.26 works with MySQL version 3.22.27 and ColdFusion for Linux. (Any newer version should also work). You can download MyODBC at http://www.mysql.com/download_myodbc.html

     ColdFusion 4.5.1 allows you to us the ColdFusion Administrator to add the MySQL data source. However, the driver is not included with ColdFusion 4.5.1. Before the MySQL driver will appear in the ODBC datasources drop-down list, you must build and copy the MyODBC driver to /opt/coldfusion/lib/libmyodbc.so.

DataJunction
     You have to change it to output VARCHAR rather than ENUM, as it exports the latter in a manner that causes MySQL grief.

Excel
     動作。Some tips:

       * 日付に問題が起きた場合、CONCAT() 関数を使用し、文字として SELECT してみてください。例えば：

               select CONCAT(rise_time), CONCAT(set_time)
                   from sunrise_sunset;

          この方法で文字として返ってきた値を、Excel97 で時間として扱うようにすべきです。

          この例の CONCAT() の目的は、フィールドの型が文字列であると ODBC をだますことです。 CONCAT() がなければ、ODBC はフィールドの型が日付とわかるので、 Excel が今度はそれを理解できなくなります。

          これは Excel のバグです。なぜなら文字を自動で日付に直すのですから。これは単にテキストファイルの情報を扱う場合ならばいいのですが、各項目の型を知らせる ODBC 接続の情報を扱う場合は、とても愚かな方法です。

odbcadmin
     ODBC のテストプログラム.

Delphi
     DBE 3.2 以上を必ず使用してください。 MySQL に接続する際には、'Don't optimize column width' オプションをセットします。

     ODBCエントリとBDEエントリの両方をセットアップするおりに役に立つであろう Delphi のコード例を示します ( BDE は Delphi Super Page から無償で得られる BDE Alias Editor が必要です)。 :  (Thanks to Bryan Brunton bryan@flesherfab.com for this)

          fReg:= TRegistry.Create;
            fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
            fReg.WriteString('Database', 'Documents');
            fReg.WriteString('Description', ' ');
            fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
            fReg.WriteString('Flag', '1');
            fReg.WriteString('Password', '');
            fReg.WriteString('Port', ' ');
            fReg.WriteString('Server', 'xmark');
            fReg.WriteString('User', 'winuser');
            fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
            fReg.WriteString('DocumentsFab', 'MySQL');
            fReg.CloseKey;
            fReg.Free;

            Memo1.Lines.Add('DATABASE NAME=');
            Memo1.Lines.Add('USER NAME=');
            Memo1.Lines.Add('ODBC DSN=DocumentsFab');
            Memo1.Lines.Add('OPEN MODE=READ/WRITE');
            Memo1.Lines.Add('BATCH COUNT=200');
            Memo1.Lines.Add('LANGDRIVER=');
            Memo1.Lines.Add('MAX ROWS=-1');
            Memo1.Lines.Add('SCHEMA CACHE DIR=');
            Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
            Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
            Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
            Memo1.Lines.Add('SQLQRYMODE=');
            Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
            Memo1.Lines.Add('ENABLE BCD=FALSE');
            Memo1.Lines.Add('ROWSET SIZE=20');
            Memo1.Lines.Add('BLOBS TO CACHE=64');
            Memo1.Lines.Add('BLOB SIZE=32');

            AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);

C++Builder
     BDE 3.0で,テストされました。唯一の知られた問題は、テーブルスキーマが変化する時、クエリフィールドが更新されないことです。 BDE は、index PRIMARY だけを認識し、プライマリーキーは認識していないように思えます。これはさほど問題ではないですが。

Visual Basic
     テーブルの更新を可能にするため、テーブルにプライマリーキーを作成しなくてはなりません。

     Visual Basic with ADO can't handle big integers;  This means that some queries like SHOW PROCESSLIST will not work properly.  The fix is to set add the option OPTION=16834 in the ODBC connect string or set the Change BIGINT columns to INT option in the MyODBC connect screen.

AUTO_INCREMENT フィールドの値を ODBC で得る方法
==================================

共通の問題は、INSERT で自動的に生成されるIDの値を得ることです。 ODBCでは、以下のようにします( 例中の auto が AUTO_INCREMENT フィールドです)：

     INSERT INTO foo (auto,text) VALUES(NULL,'text');
     SELECT LAST_INSERT_ID();

もしくは、他のテーブルにIDを挿入するだけなら以下のようにします：

     INSERT INTO foo (auto,text) VALUES(NULL,'text');
     INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text');

いくつかのODBCアプリケーション(少なくともDelphiとAccess)は、新しく挿入された行を見つけるのに、以下のクエリが使用できます：

     SELECT * FROM tbl_name WHERE auto IS NULL;

Reporting problems with MyODBC
==============================

もし MyODBC 使用時に難しい問題にあたった場合、 ODBC マネージャのログファイル (ODBCADMIN からリクエストしたときのログ) と MyODBC のログを取り始めるべきです。これはいかなる問題にも解決の糸口になるはずです。 MyODBC ログを取るには、 MyODBC connect/configure 画面の 'Trace MyODBC' オプションをチェックします。ログは C:\myodbc.log に書き出されます。このオプションを使用するに当たり、 MYSQL2.DLL ではなく、 MYSQL.DLL を使用しなくてはなりません！

MyODBC が MySQL サーバーに送っているクエリを確認します；これは myodbc.log ファイル中に、>mysql_real_query という文字列が含まれている行です。

また、MyODBC か MySQL のエラーを見つけるためには、同じコマンドを、mysql コマンドや admndemo でも試すべきです。

もし、問題を発見したなら、関係する行を（最大40行） myodbc@lists.mysql.com に送ってください。 MyODBC や ODBC のログファイル全てを送らないようにしてください！

もし問題を見つけることが出来なかった場合、MyODBC ログファイル、 ODBC ログファイル、問題の説明する README ファイルを含んだアーカイブ(tar か zip) を作成します。これを ftp://www.mysql.com/pub/mysql/secret. に送ります。 TCX だけが、アップロードされたファイルにアクセスできます。

もし問題を見るためのプログラムも作っているなら、それも同時に送ります。

もしそのプログラムが他の SQL サーバーで動くなら、他の SQL サーバーで同じことをした場合の ODBC ログファイルを作成すべきです。

多くの情報をあなたが提供すれば、我々は問題を解決しやすくなることを念頭においてください。

いくつかの一般的なプログラムでの MySQL の使用
**************************

Apache での MySQL の使用
===================

Contrib には、 MySQL データベースに登録しているユーザーで認証が出来るようになるプログラムと、ログを MySQL テーブルに書き込むプログラムが含まれています。 See Contrib.

以下のように Apache の設定ファイルに記述すれば、 Apache のログのフォーマットを、MySQL に読みやすい物に変更できます：

     LogFormat \
             "\"%h\",%{%Y%m%d%H%M%S}t,%>s,\"%b\",\"%{Content-Type}o\",  \
             \"%U\",\"%{Referer}i\",\"%{User-Agent}i\""

こうすれば、MySQL で、以下のようにできます：

     LOAD DATA INFILE '/local/access_log' INTO TABLE table_name
     FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'

問題とよくあるエラー
**********

How to determinate what is causing problems
===========================================

When you run into problems, the first thing you should do is to find out which program / piece of equipment is causing problems.

  * If you have one of the following symptoms, then it is probably a hardware (like memory, motherboard, CPU, or harddisk) or kernel problem:

       * The keyboard doesn't work.  This can normally be checked by pressing Caps Lock;  If the Caps Lock light doesn't change you have to replace your keyboard.  (Before doing this, you should however try to reboot your computer and check all cables to the keyboard :)

       * The mouse pointer doesn't move.

       * The machine doesn't answer to a remote machine's pings.

       * Different, unrelated programs don't behave correctly.

       * If your system rebooted unexpectedly (a faulty user level program should NEVER be able to take down your system).

     In this case you should start by checking all your cables and run some diagnostic tool to check your hardware! You should also check if there are any patches, updates or service packs for your operating system that could likely solve your problems. Check also that all your libraries (like glibc) are up to date.

     It's always good to use a machine with ECC memory to discover memory problems early!

  * If your keyboard is locked up, you may be able to fix this by logging into your machine from another machine and execute kbd_mode -a on it.

  * Please examine your system log file, (/var/log/messages or similar) for reasons for your problems.  If you think the problem is in MySQL then you should also examine MySQL's log files. See Update log.

  * If you don't think you have hardware problems, you should try to find out which program is causing problems.

     Try using top, ps, taskmanager or some similar program, to check which program is taking all CPU, or is locking the machine.

  * Check with top, df or a similar programs if you are out of memory, disk space, open files or some other critical resource.

  * If the problem is some runaway process, you can always try to kill if. If it doesn't want to die, this is probably a bug in the operating system.

If after you have examined all other possibilities and you have concluded that its the MySQL server or a MySQL client that is causing the problem, it's time to do a bug report for our mailing list or our support team.  In the bug report, try to describe very detailed how the system is behaving and what you think is happening. You should also state why you think it's MySQL that is causing the problems.  Take in consideration all the situations in this chapter. State any problems exactly how they appear when you examine your system.. Use the 'cut and paste' method for any output and/or error messages from programs and/or log files!

Try to describe very detailed which program is not working and all symptoms you see!  We have in the past got many bug reports that just states "the system doesn't work".  This doesn't provide us with any information of what could be the problem.

If a program fails, it's always useful to know:

  * Has the program in question made a segmentation fault (core dumped)?

  * Is the program taking the whole CPU? Check with top. Let the program run for a while, it may be evaluating something heavy.

  * If it's the mysqld server that is causing problems; Can you do mysqladmin -u root ping, or mysqladmin -u root processlist?

  * What does a client program say (try with mysql for example) when you try to connect to the MySQL server? Does the client jam?  Do you get any output from the program?

When send a bug report, you should of course follow the outlines described in this manual. See Asking questions.

MySQL がクラッシュする場合に行うこと
---------------------

全ての MySQL バージョンはリリースの前に多くのプラットフォームでテストされます。 これは MySQL にいかなるバグもないということを意味しますが、発見するのが困難で、わずかなバグがあるかもしれません。もし問題があった場合、何がシステムをクラッシュしているかを見つけようとする事は、問題を早く修正するためのより良い機会でもあります。

まず最初に, その問題で mysqld デーモンが死ななければならないかどうかか, またはその問題がクライアントで処理しなければならないかどうかを調べるべきです。 mysqladmin version を実行することにより、 mysqld サーバーがどれぐらい稼働していたかわかります。 もし mysqld が死んでいたなら、を実行することによってあるのかをチェックすることができます. mysqldが死んだなら、その原因を mysql-data-directory/'hostname'.err で見つけれるかもしれません。

Many crashes of MySQL is caused by corrupted index / data files.  MySQL will update the data on disk, with the write() system call, after every SQL statement and before the client is notified about the result (this is not true if you are running with delayed_key_writes, in which case only the data is written). This means that the data is safe even if mysqld crashes as the OS will ensure that the not flushed data is written to disk. You can force MySQL to sync everything to disk by starting mysqld with --flush.

The above means that normally you shouldn't get corrupted tables unless:

  * Someone/something killed mysqld or the machine in the middle of an update.

  * You have found a bug in mysqld that caused it to die in the middle of an update.

  * Someone is manipulating the data/index files outside of mysqld without locking the table properly.

  * If you are running many mysqld servers on the same data on a system that doesn't support good file system locks (normally handled by the lockd deamon.) or if you are running multiple servers with --skip-locking

  * You have a crashed index/data file that contains very wrong data that got mysqld confused.

  * You have found a bug in the data storage code. This isn't that likely, but it's at least possible.  In this case you can try to change the file type to another database handler by using ALTER TABLE on a repaired copy of the table!

何かがクラッシュする理由を知るのは非常に難しいので、まず、他の人で動くものがあなたでクラッシュするのかどうかをチェックしてください。次のことを行ってください。

  * mysqld デーモンを mysqladmin shutdown で停止し, 全てのテーブルで myisamchk --silent --force */*.MYI を実行し、そして mysqld デーモンを再起動します.  これはきれいな状態から開始することになります。 See Maintenance.

  * mysqld --log を使用し、ログの情報から特定のクエリがサーバーをキルしているかを見つけ出してください。 95% のバグは特定のクエリに関係があります！通常これは、 MySQL が再起動される前の、ログファイルの最後のクエリの一つです。

     これを、以下の手順で確認することも出来ます：

       * MySQL デーモンを ( mysqladmin shutdown で) 停止。

       * MySQL データベースディレクトリをバックアップ。 (As the server is stopped, you can just copy the files to some other directory)

       * 全てのテーブルが正しいのかを、myisamchk -s */*.MYI でチェック。もしテーブルが壊れているようなら、 myisamchk -r path-to-table.MYI でそれを修正。 You should take the backup before checking the tables as the problem could be related to corrupted tables.

       * ログファイルを MySQL データディレクトリから削除 (か 移動)。

       * safe_mysqld --log-update か safe_mysql --log --log-update でサーバー起動。

       * If mysqld now dies, you have two options:

            * First take a backup of your backup database. (Just copy the file(s) somewhere again). This is because we want to keep the original start situation untouched. Start a mysqld process on the other backup database (you can do this with option --datadir=/path/to/backup/).

            * Just restore the backup on your original database and restart mysqld. You will not any lose information, because you have the log-update file.

       * Now you can test if the problem is a specific update statement by executing mysql database_name < path-to-log-update-file.

          You can also use the script mysql_find_rows to just execute some of the update statements if you want to narrow down the problem.

          If mysqld now crashes, then you have something repeatable available. Please mail bugs@lists.mysql.com, or developers@mysql.com, or (if you are a support customer) to support@mysql.com about the problem and the MySQL team will fix it as soon as possible.

  * ベンチマークを試しましたか？ これは MySQL をより良くテストします。あなたのアプリケーションをシミュレートするコードを追加することもできます。ベンチマークはソース配布では MySQL インストールディレクトリ配下の bench ディレクトリに、バイナリ配布では sql-bench ディレクトリに見つけられます。

  * fork_test.pl と fork2_test.pl を試します。

  * エラーがないか、mysql-data-directory/'hostname'.err ファイルを確認します。

  * デバッグ用に MySQL をコンフィグすると、何かが悪くなる場合にエラーを見つけ出すのがより簡単になります。configure に --with-debug オプションをつけて MySQL を再コンフィグし、再コンパイルしてください。See Debugging server.

  * デバッグ用に MySQL をコンフィグすると、いくつかのエラーを検出できる安全なメモリ割り当てを含めます。これは何が起きているかについての多くの出力も提供します。

  * あなたの OS の最新のパッチを適用しましたか？

  * --skip-locking オプションを mysqld に使用してください。いくつかのシステム上では、lockd ロックマネージャは正しく動きません; --skip-locking オプションは mysqld に外部ロッキングを使用しないように伝えます。(これは同じデータ上で2つの mysqld サーバを動すことができず、myisamchk の使用時に注意しなければいけないことを意味します。しかし、テストとしてこのオプションを試すことは指示できます。)

  * mysqld が動いているのに応答がないように見えた時 mysqladmin -u root processlist を試しましたか？ 時々 mysqld はそう思えても死んでいません。問題は全ての接続が使用中であることか、いくつかの内部ロック問題があることです。mysqladmin processlist は通常これらの場合でも接続を作ることができ、現在の接続数とそれらの状態についての有用な情報を提供できます。

  * 別のウィンドウで、統計出力のためにコマンド mysqladmin -i 5 status をクエリ中、行ってください。

  * 次を試してください:

      1. gdb (または他のデバッガ) から mysqld を開始してください。

      2. あなたのテストスクリプトを実行してください。

      3. Print the backtrace and the local variables at the 3 lowest levels. In gdb you can do this with the following commands when mysqld has crashed inside gdb:

               backtrace
               info local
               up
               info local
               up
               info local

          With gdb you can also examine which threads there exists with info threads and switch to a specific thread with thread #, where # is the thread id.

  * MySQL にクラッシュまたは間違った振る舞いをさせるあなたのアプリケーションのシミュレートを Perl スクリプトで試みてください。

  * または通常のバグレポートを送ってください。See Bug reports。しかし通常よりもさらに詳細にしてください。MySQL は多くの人のために働いているため、クラッシュはあなたのコンピュータだけに存在する何か(例えば、あなたの特別なシステムライブラリに関連したエラー)から生じていると思われます。

  * もし可変長のレコードを扱うテーブルで問題があった場合、もし、BLOB/TEXT フィールドは使用しておらず、VARCHAR フィールドだけ使用しているなら、全ての VARCHAR フィールドを ALTER TABLE で CHAR に変更してみてください。これは MySQL に固定長レコードを使用させるようにします。固定長レコードは少し余分な領域をとりますが、よりエラーに対して強くなります。

     現在の可変長のレコードのコードは TCX で少なくとも３年以上問題なく使用されています。 しかし可変長のレコードはよりエラーの傾向があり、上記の事柄を試すことは良いアイデアです！

MySQL使用時のよくあるいくつかのエラー
=====================

MySQL server has gone away エラー
------------------------------

このセクションは Lost connection to server during query エラーに関することもカバーします。

MySQL server has gone away エラーのもっとも一般的な理由は、サーバがタイムアウトで接続をクローズしたことです。デフォルトでは、何も起きない場合、サーバは 8 時間後に接続をクローズします。この時間は mysqld 起動時の wait_timeout 変数に与えることにより、変更できます。

mysqladmin version を実行することで MySQL が死んでいるかどうか、また uptime はどれぐらいか、チェックできます。

スクリプトの場合は、自動的に再接続するためにクライアントからクエリを再発行する必要があります。

この場合、通常これらのエラーコードを得ます: (OS 依存です):

CR_SERVER_GONE_ERROR   クライアントがサーバーに問い合わせを送ることができなかった
CR_SERVER_LOST    クライアントがサーバーに書き込みを行ったときにはエラーは無かったけれども、問い合わせに対して完全に回答が返ってこない

間違っているか大きすぎるクエリをサーバに送った場合にもこのエラーが発生します。mysqld が間違ったブロックを得た場合、クライアントの何かが間違ったと見なし、接続をクローズします。大きなクエリが必要な場合、例えば大きな BLOB で働かせる場合は、mysqld をオプション -O max_query_size=# (デフォルト 1M) で起動することでクエリ制限を増加できます。拡張メモリは要求によって割り当てられます。そのため、mysqld は大きなクエリを発行した時や大きな結果行を返す必要のある時だけ、多くのメモリを使用します！

Can't connect to [local] MySQL server エラー
-----------------------------------------

UNIX 上の MySQL クライアントは  mysqld サーバに2つの異なる方法で接続できます: Unix ソケット, これはファイルシステム上のファイル(デフォルト /tmp/mysql.sock)を通して接続します。または TCP/IP, これはポート番号を通して接続します。Unix ソケットは TCP/IP よりも速いですが、サーバと同じコンピュータから接続する時しか使えません。Unix ソケットは、ホスト名を指定しない場合か、特別なホスト名 localhost を指定した場合に使用されます。

On Windows you can connect only with TCP/IP if the mysqld server is running on Win95/Win98. If it's running on NT, you can also connect with named pipes.  The name of the named pipe is MySQL.  If you don't give a hostname when connecting to mysqld, a MySQL client will first try to connect to the named pipe and if this doesn't work it will connect to the TCP/IP port.  You can force the use of named pipes on Windows by using . as the hostname.

(2002) Can't connect to ... エラーは、通常、MySQL サーバーがシステム上に走っていないか、あなたが、間違ったソケットファイルや TCP/IP ポートを使用して mysqld に接続しようとする場合におきます。

Start by check サーバー上に mysqld というプロセスが走っているか ( ps を使用して。 Windows の場合はタスクマネージャでみて) 確認することから開始してください！ See Starting server.

mysqld プロセスが走っているなら、違う接続を試すことでサーバーを確認することができます（もちろん、ポート番号とソケットのパスはあなたがセットアップしたものとは違うでしょう）：

     shell> mysqladmin version
     shell> mysqladmin variables
     shell> mysqladmin -h `hostname` version variables
     shell> mysqladmin -h `hostname` --port=3306 version
     shell> mysqladmin -h 'ip for your host' version
     shell> mysqladmin --socket=/tmp/mysql.sock version

hostname コマンドはフォワードクオートでなくバッククオテーションで囲んでいることに注意してください； これは ホスト名 (カレントのホスト名) を mysqladmin コマンドに与えます。

Can't connect to local MySQL server エラーが起こりうる理由として：

  * mysqld is not running.

  * MIT-pthreads を使用するシステム上で実行している。ネイティブスレッドを持たないシステム上で実行している場合 mysqld は  MIT-pthreads パッケージを使用します。 See Which OS. MIT-pthreads スレッドはソケットをサポートしません。そのため、サーバに接続する時は常にホスト名を与える必要があります。サーバーへの接続をチェックするために、以下を試してください：

          shell> mysqladmin -h `hostname` version

  * 誰かが mysqld が使用する unix ソケット を削除した (default /tmp/mysqld.sock). だれかが cron で MySQL ソケットを削除しているかもしれません。(例えば /tmp ディレクトリから古いファイルを削除するようなクローンで)。いつでも mysqladmin version を実行して mysqladmin が使用するソケットが本当に存在するかをチェックできます。この場合の修正は、mysqld.sock を消さないように cron を変更するか、またはソケットをどこか他の場所に移すことです。

     MySQL を ./configure する場合にソケットを指定するには以下のようにします:

          shell> ./configure --with-unix-socket-path=/path/to/socket

     また、safe_mysqld を --socket=/path/to/socket オプションを指定して起動しても構いませんし、 MYSQL_UNIX_PORT 環境変数をセットして MySQL クライアントを実行してもかまいません。

  * --socket=/path/to/socket オプションで mysqld サーバーを起動できます。もしサーバーのソケットのパスを変えた場合、MySQL クライアントに、新しいパスを教えなければなりません。この場合、 MYSQL_UNIX_PORT 環境変数に設定することにより可能です。ソケットのテストをする場合、以下のようにします：

          shell> mysqladmin --socket=/path/to/socket version

  * Linux を使用していてスレッドが一つ死んだとき（コアダンプした）。この場合、他の mysqld スレッドをキルしなければなりません。たとえば、mysql_zap スクリプトを、新しく MySQL サーバーを起動する前に実行します。 See Crashing.

もし Can't connect to MySQL server on some_hostname エラーの場合, 何が問題なのかを見つけるために、以下の手順を踏みます：

  * もし telnet your-host-name tcp-ip-port-number を実行するとサーバーがアップするなら、 RETURN を何回かたたいてください。もしこのポートで MySQL サーバーが走っているなら、走っている MySQL サーバーのバージョンナンバーを含んだレスポンスが得られるはずです。もし telnet: Unable to connect to remote host: Connection refused のようなエラーになったならば、このポートを使用しているサーバーはありません。

  * ローカルのマシンの mysqld デーモンに接続してみてください。 mysqld が使用するように指定された TCP/IP ポートをチェックしてください。（mysqladmin variables で得られる port 変数）

  * mysqld サーバーが --skip-networking オプションで起動されていないか確認してください。

Host '...' is blocked エラー
-------------------------

以下のエラーの場合：

     Host 'hostname' is blocked because of many connection errors.
     Unblock with 'mysqladmin flush-hosts'

これは mysqld が多くの 'hostname' ホストからの接続エラー(max_connect_errors) を受けた場合に発生します。この max_connect_errors 大量発生後、mysqld は何か(クラッカーによるサーバーへのアタックなど)が起こったと判断し、このホストからの接続をいっさい拒否するようにします。これを解除するには、mysqladmin flush-hosts コマンドを実行します。

デフォルトでは、10回の接続エラーが発生した場合に、mysqld はそのホストを拒否します。この値は以下のようにして簡単に変更できます：

     shell> safe_mysqld -O max_connect_errors=10000 &

もしこのエラーがあるホストに対して発生するならば、まず最初にそのホストからの TCP/IP 接続に不具合がないかチェックしてください。もし TCP/IP 接続が動作していないようなら、 max_connect_errors 値を増やすことはよくないことです！

Too many connections エラー
------------------------

もし MySQL に接続しようとして Too many connections となった場合、これは既に max_connections 分、クライアントから mysqld サーバーへの接続が行われています。

もしデフォルトの100よりも多い接続を必要とするならば、 max_connections 変数に多くの値を与えて、mysqld をリスタートしなくてはなりません。

実際は、mysqld は (max_connections+1) 個のクライアントからの接続を許しています。最後の１個は、 process 権限をもつユーザーのために取ってあります。 By not giving this privilege to normal users (they shouldn't need this), an administrator with this privilege can login and use SHOW PROCESSLIST to find out what could be wrong. See SHOW.

Out of memory エラー
-----------------

クエリを行って、次のエラーのようなものを得た場合:

     mysql: Out of memory at line 42, 'malloc.c'
     mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
     ERROR 2008: MySQL client ran out of memory

エラーは MySQL クライアント mysql に関係することに注意してください。エラーの理由は単純で、クライアントが結果全体を格納するのに十分なメモリを持っていないことです。

この問題を解決するにあたり、まず最初にクエリーが正しいか確認してください。そのクエリーは大量の結果を返すものでしょうか？もしそうなら、mysql --quick を使用してください。これは結果を取り出すために mysql_use_result() を使用します。これはクライアントのロード不足を補います(サーバーより多い領域は取れません)。

Packet too large エラー
--------------------

MySQL クライアントが max_allowed_packet よりも大きなブロックを mysqld サーバーから得た時、Packet too large エラーを発します。

mysql クライアントを使用する場合、mysql --set-variable=max_allowed_packet=8M でクライアントを開始することで、バッファを大きく設定できます。

もし(DBI のように)最大パケットサイズを指定できないクライアントを使用している場合、パケットサイズを指定してサーバーを立ち上げ直します。これは mysqld のオプションの max_allowed_packet に大きな値を設定することで行います。例えば、 BLOB 型の許容範囲いっぱいのデータをテーブルに入れる場合、 --set-variable=max_allowed_packet=24M オプションを指定してサーバーを起動する必要があります。

The table is full エラー
---------------------

このエラーは、古い MySQL バージョンにおいて、メモリ内一時テーブルが tmp_table_size よりも大きくなった時に発生します。この問題を回避するために、mysqld のオプション -O tmp_table_size=# で増加、または、SQL オプション SQL_BIG_TABLES を問題のクエリの前に使用できます。See SET OPTION.

mysqld を --big-tables オプション指定して起動します。これは全てのクエリーに対して SQL_BIG_TABLES を使用するのと同じです。

In MySQL 3.23 in-memory temporary tables will automaticly be converted to a disk based MyISAM table after the table size gets bigger than tmp_table_size.

Commands out of sync error in client
------------------------------------

Commands out of sync; You can't run this command now をクライアントコード中で得た場合、クライアント関数を間違った順番で呼び出しました！

これは例えば、mysql_use_result() を使用していて、mysql_free_result() を行う前に新しいクエリの実行を試みた場合に発生します。これはまた、データを返す２つのクエリの実行を、間に mysql_use_result() や mysql_store_result() 無しで試みた場合にも発生します。

Ignoring user エラー
-----------------

以下のエラーの場合：

Found wrong password for user: 'some_user@some_host'; Ignoring user

これは mysqld の開始または 'reload' 時に user テーブル内に正しいパスワードを持たないエントリを見つけたことを意味します。これは単にエントリが許可システムに拒否されているだけです。

起こり得ることとその解決:

  * 新しいバージョンの mysqld を、古いバージョン用の user テーブルで走らせているのかもしれません。 mysqlshow mysql user を行うことによってこれを検証できます。パスワードフィールドが 16 文字よりも短いかどうかをチェックしてください。もしそうなら、これを修正するために、scripts/add_long_password スクリプトを実行してください。

  * ユーザーが古いパスワード(最大8文字) を使用していて、mysqld を --old-protocol オプションで起動していないのかもしれません。新しいパスワードで user テーブル内のユーザを更新するか、--old-protocol 付きで mysqld を再起動してください。

  * user テーブルのパスワードを、PASSWORD() 関数を使用しないで登録したのかもしれません。この場合、user テーブルのパスワードを、mysql を使用して更新します。 PASSWORD() 関数は以下のようにして使用します：

          mysql> update user set password=PASSWORD('your password')
                     where user='XXX';

Table 'xxx' doesn't exist error
-------------------------------

もし Table 'xxx' doesn't exist か Can't find file: 'xxx' (errno: 2) エラーが出た場合、使用しているデータベースに  xxx という名前のテーブルが見付からなかったことを示します

データベースとテーブルの保存に、MySQL はディレクトリとファイルを使用し、データベースとテーブルの名前はケース依存です! (Win32 ではデータベースとテーブル名はケース非依存です。クエリ中のテーブルに対する問い合わせは全て、同じケースで書かなくてはなりません！)

SHOW TABLES を使用してデータベースのテーブルを確認できます. See SHOW.

MySQL はフルディスクをどのように扱うか？
=======================

ディスクフルが起きた場合 MySQL は次のことを行います:

  * 現在の行を書くのに十分な領域があるかどうかを1分毎に1回チェックします。十分なディスクがある場合は、何も起きなかったように継続します。

  * 6分毎にログファイルにディスクフルを警告するエントリを書き出します。

この問題の場合、以下のようにします：

  * 継続するためには、全てのレコードを挿入するのに十分な領域を解放する必要があります。

  * スレッドをアボートするためには、mysqladmin kill をスレッドに送る必要があります。スレッドは次に(1分)ディスクをチェックした時にアボートします。

  * 他のスレッドが ``disk full'' が発生したテーブルで待たされることに注意してください。多くの ``locked'' スレッドがある場合、disk full を待つ一つのスレッドを kill することで、他のスレッドの継続を許します。

テキストファイルから SQL コマンドを実行
======================

mysql クライアントは以下のようにして対話的に使用します：

     shell> mysql database

しかし SQL コマンドをファイルに書いておき、それを mysql に読み込ませることができます。テキストファイル text_file に実行したいコマンドを書いておき、以下のようにして mysql を起動します：

     shell> mysql database < text_file

テキストファイルの先頭に USE db_name 構文を書くこともできます。この場合、データベース名をコマンドラインに与える必要は無く、以下のようにできます：

     shell> mysql < text_file

See Programs.

MySQL が一時ファイルを格納する場所
====================

MySQL は一時ファイルを格納する場所として TMPDIR 環境変数の値を使用します。TMPDIR を設定していなければ、MySQL はシステムのデフォルトを使用します。通常は /tmp または /usr/tmp です。TMPDIR が小さすぎる場合、safe_mysqld を編集して、十分な領域がある他のディレクトリを指すように TMPDIR を設定すべきです！ --tmpdir オプションを mysqld に与えることで、一時ファイルディレクトリを指定することも可能です。

MySQL は全ての一時ファイルを ``隠しファイル'' として生成します。これは mysqld が終了した場合に、一時ファイルが削除されないことを確実にします。隠しファイルを使用する '悪い' 側面は、小さすぎる一時ディスクを一杯にする大きな一時ファイルを見つけられないことです。

ソート時 (ORDER BY または GROUP BY)、MySQL は通常一つまたは二つの一時ファイルを使用します。必要な最大のディスク容量は:

     (length of what is sorted + sizeof(database pointer))
     * number of matched rows
     * 2

sizeof(database_pointer) は通常４ですが、将来本当に大きなテーブルのために大きくなることもあります。

いくつかの SELECT クエリは一時的な SQL テーブルも生成します。これらは隠しファイルではなく、SQL_* という名前です。

ALTER TABLE , OPTIMIZE TABLE は一時テーブルをオリジナルテーブルと同じディレクトリ内に生成します。

/tmp/mysql.sock を削除から守る方法
=========================

もし誰かに MySQL のソケットファイル /tmp/mysql.sock が消されるなら、ほとんどの Unix がそうであるように、 /tmp に sticky ビットをたてて保護します。 root でログインして、以下のようにします：

     shell> chmod +t /tmp

これはファイルのオーナーとスーパーユーザー(root) のみが、 /tmp のファイルを消すことができます。

sticky ビットが立っているか確認するには、 ls -ld /tmp を行います。パーミッションの最後のビットが t ならば、セットされています。

Access denied エラー
=================

See Privileges.　See Access denied.

一般ユーザで MySQL を動かす方法
===================

mysqld (MySQL サーバ) は誰でも開始し実行することができます。 mysqld をユーザ user_name で実行するように変更するためには、次を行なう必要があります:

 1. サーバーを止めます (use mysqladmin shutdown).

 2. user_name が読み書きできるように、データベースディレクトリとその中のファイルのパーミッションを変更します。(これは Unix root ユーザーで実行する必要があるでしょう)：

          shell> chown -R user_name /path/to/mysql/datadir

     MySQL データベースディレクトリのディレクトリーやファイルがシンボリックリンクの場合、これらリンクの先のディレクトリとファイルも変更します。chown -R はシンボリックリンク先を変更してくれません。

 3. ユーザ user_name でサーバを起動します。または MySQL 3.22 以降を使用する場合は、mysqld を Unix root で起動し --user=user_name スイッチを使用します。 mysqld は、接続を許可する前に、与えられた Unix user user_name で実行するように切り替えます。

 4. システム再起動時、 mysql.server を使用して mysqld を起動する場合、ユーザ user_name への su を行なうようにまたは --user スイッチを使用して mysqld を起動するように mysql.server を 変更すべきです。 (No changes to safe_mysqld are necessary.)

この時点で、あなたの mysqld プロセスは Unix user user_name で正常に動作します。

一つのことは変わりません。それは権限許可テーブルです。デフォルト (パーミッションテーブルインストールスクリプトmysql_install_db実行後の権限) では、mysqlデータベースへのアクセスやデータベースの作成、破棄はユーザ MySQL user root だけです。これを変更しないと、それはそのままです。 root 以外のUnix userでログインしている時でも、あなたは MySQL root user としてアクセスは可能です - ただプログラムに -u root をクライアントプログラムにオプション指定するだけです。

MySQL に root としてアクセスするには、コマンドラインで -u root を使用するだけでいいことに注意してください。 Unix root user や MySQL を走らせている Unix ユーザーである必要はないことに注意してください。 MySQL のアクセスパーミッションとMySQL のユーザは、 UNIX ユーザとは完全に別のものです。UNIX ユーザに関係するのは、クライアントに -u オプションを使用しない場合だけです。この場合、クライアントは MySQL へのログインを、あなたの UNIX ログイン名で試みます。

あなたの UNIX マシンそれ自身が安全でない場合は、少なくとも MySQL アクセステーブルの MySQL root ユーザにはパスワードを設定すべきです。どこかの誰かが mysql -u root db_name を行ない、彼が望むことの全てを実行できてしまうからです。

忘れたパスワードをリセットする
===============

もし MySQL の root ユーザーのパスワードを忘れた場合、これを以下のようにして入れ直すことが可能です。

 1. mysqld サーバーを kill で落とす。 (kill -9 ではありません！) PID 番号は通常 MySQL データディレクトリに .pid ファイルとして書かれています：

          kill `cat /mysql-data-directory/hostname.pid`

     これを、 UNIX root ユーザーか、MySQL サーバーを実行したユーザーで行います。

 2. mysqld を --skip-grant-tables オプションで起動。

 3. mysql -h hostname mysql でmysqld サーバーに接続し、 GRANT コマンドでパスワードを変更します。 See GRANT. mysqladmin -h hostname -u user password 'new password' でも変更可能です。

 4. 許可テーブルを読み込みます： mysqladmin -h hostname flush-privileges か、SQL 文の FLUSH PRIVILEGES を実行します。

ファイルパーミッションの問題
==============

ファイルパーミッションの問題がある場合、例えば、テーブルの生成時に mysql が次を出力する場合:

     ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)

これは UMASK 環境変数が mysqld 起動時に間違ってセットされていると考えられます。デフォルトの umask は 0660 です. これは以下のようにして safe_mysqld 立ち上げ時に変更できます:

     shell> UMASK=384  # = 600 in octal
     shell> export UMASK
     shell> /path/to/safe_mysqld &

By default MySQL will create database and RAID directories with permission type 0700.  You can modify this behaviour by setting the the UMASK_DIR variable. If you set this, new directories are created with the combined UMASK and UMASK_DIR. For example, if you want to give group access to all new directories, you can do:

     shell> UMASK_DIR=504  # = 770 in octal
     shell> export UMASK_DIR
     shell> /path/to/safe_mysqld &

See Environment variables.

File not found
==============

ERROR '...' not found (Errcode: 23), Can't open file: ... (errno: 24) や errcode 23 errno 24 のエラーを MySQL から得た場合、これは MySQL に十分なファイル記述子が割り当てられなかったことを意味します。 perror # はさらに読みやすい形式のエラーメッセージを与えます:

     shell> perror 23
     File table overflow
     shell> perror 24
     Too many open files

これは mysqld が多くのファイルを開こうとしたことに起因します。 mysqld に一度に開くファイル数を多く開かないようしたり、あるいは、 mysqld が扱えるファイル記述子の数を与えたりできます。

mysqld が一度に開くファイルの数を少なくするには、-O table_cache=32 オプション(デフォルトは64)を safe_mysqld に与えることで可能です。また、max_connections の値(デフォルトは90)を少なくするならば、開くファイル数も少なくできます。

mysqld が取り扱えるファイル記述子の数を変更するには、 safe_mysqld を編集します。この中に ulimit -n 256 がコメントアウトされています。このコメントをはずし('#'文字を消す)、256 を mysqld が扱う数に変更してください。

ulimit はオペレーティングシステムの制限内でしかファイル記述子の数を指定できません。もし OS の制限以上にファイル記述子のオープン数を増やしたい場合、お使いのオペレーティングシステムのドキュメントを見て対処してください。

tcsh を使用している場合は ulimit は動かないことに注意してください！ tcsh は現在の制限をあなたが問い合わせても、違った値を報告するでしょう。この場合、safe_mysqld は sh で起動すべきです！

DATE フィールド使用時の問題
================

日付 DATE の形式は 'YYYY-MM-DD' です。ANSI SQL に従って実際には他のは許されません。更新または SELECT 文中の WHERE 節内ではこの形式を使用すべきです。すなわち:

     mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';

利便のため MySQL は、日付が数値の文脈で使用されると、日付を自動的に数値に変換します。これにより、更新と TIMESTAMP, DATE または DATETIME フィールドでの WHERE 時に、わりと自由に日付を指定することができます。 (この記述を許すため、句読記号を日付のセパレーターとして使用します。例えば、'1998-08-15' と '1998#08#15' は同一です.) もしろんセパレーターのない記述(例：'19980815')も日付として変換してくれます。

特別な日付 '0000-00-00' は '0000-00-00' として格納され取り出されます。 MyODBC を通して '0000-00-00' 日付を使用する時、MyODBC 2.50.12 以上では自動的に NULL に変換されます。ODBC はこの日付の種類を扱えないためです。

これは次が動くことを意味します:

     mysql> INSERT INTO tbl_name (idate) VALUES (19970505);
     mysql> INSERT INTO tbl_name (idate) VALUES ('19970505');
     mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05');
     mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05');
     mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05');
     mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00');

     mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05';
     mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
     mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
     mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505';

次は動きません:

     mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;

STRCMP() は文字列関数で、idate を文字に変換して、文字比較を行います。 '19970505' は日付には変換してくれず、日付の比較も行いません。

MySQL は日付が正しいかどうかをチェックしないことに注意してください。間違った日付(例えば '1998-2-31')を格納すると、その間違った日付が格納されます。日付が全体的に不可能な場合、0 が DATE フィールドに格納されます。これは主に速度の問題で、日付のチェックはサーバではなくアプリケーションでと我々は考えています。

Timezone problems
=================

もし SELECT NOW() があなたのローカル時間ではなく GMT を返すなら、 TZ 環境変数をローカルのTimezone に設定しなくてはなりません。環境変数の設定は、サーバーを実行する前に行われなくてはなりません。たとえば、safe_mysqld や mysql.server スクリプトで行います。

検索時のケース依存
=========

デフォルトでは MySQL フィールドはケース非依存です (しかし、ケース非依存にならないいくつかの文字セットはありますsuch as czech)。これは、col_name LIKE 'a%' で検索した場合、A または a で始まる全てのフィールドを得ることを意味します。検索をケース依存にしたいのなら、始まりをチェックするには INDEX(column, "A")=0 のようなことを、また、文字列全体が同じかどうかには STRCMP(column, "A") = 0 を使用してください。

単純な比較操作 >=, >, =, <, <=、ソートそしてグループ化は、文字 ``sort value'' 上で行われます。同じソート値の文字 (like E, e and é)は同じ文字として扱われます！

LIKE 比較は各文字の大文字で行われます (E == e but E <> é)

column をいつでもケース依存で扱いたい場合は、それを BINARY として宣言してください。See CREATE TABLE.

big5 エンコーディングと呼ばれる中国語データを使用している場合は、全ての文字項目を BINARY にしてください。これは、big5 エンコーディング文字のソート順が ascii コードが基になっているため、機能します。

NULL 値での問題
==========

SQL の初心者のありがちな混乱は、NULL 値が空文字列  '' と同じ物だと考えることです。これは正しくありません！ 例えば、次のステートメントは全く別のものです:

     mysql> INSERT INTO my_table (phone) VALUES (NULL);
     mysql> INSERT INTO my_table (phone) VALUES ("");

両方の文とも phone フィールドに値を挿入していますが、初めのは NULL 値を挿入し、二番目のは空文字列を挿入しています。初めのは ``電話番号を知らない'' と見なされ、二番目のは ``彼女は電話を持っていない'' と見なされます。

SQL では、  NULL は他の全ての値(たとえ  NULL でも)と比較した時に、常に偽になる値です。 NULL を含む式は、特に断りがなければ、常に  NULL 値を生成します。次の項目は全て  NULL を返します:

     mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL);

NULL 値がセットされている項目を検索する場合、 =NULL テストを行わないでください。これは expr = NULL が FALSE なので、なんの行も返しません。例えば以下の例：

     mysql> SELECT * FROM my_table WHERE phone = NULL;

NULL 値を持つフィールドを検索したい場合は、IS NULL テストを使用しなくてはいけません。次は NULL 電話番号と空の電話番号を見つける方法を示しています:

     mysql> SELECT * FROM my_table WHERE phone IS NULL;
     mysql> SELECT * FROM my_table WHERE phone = "";

MySQL では、他の多くの SQL サーバのように、NULL 値を持つインデックスフィールドを持てません。これらのフィールドは NOT NULL と宣言しなくてはいけません。インデックスフィールドには、NULL を設定することはできません。

LOAD DATA INFILE でデータを読み込むときは、空のフィールドは '' で更新されます。項目を NULL 値にしたい場合は、テキストファイル中に \N を使用すべきです。リテラルとしての 'NULL' 語が、ある状況下で使用されています。 See LOAD DATA.

ORDER BY 使用時, NULL 値は最初に提示されます. DESC を使用して降順にソートする時、NULL 値は最後になります。 GROUP BY 使用時, 全ての NULL 値は等しいと見なされます。

NULL 処理を手助けするため、次の関数を使用できます: IS NULL, IS NOT NULL, IFNULL().

いくつかの項目型では、NULL 値はハンドルとして扱われます。もしテーブル内の最初の TIMESTAMP 項に NULL を挿入するなら、現在の日付と時刻が挿入されます。もし AUTO_INCREMENT 項にNULL 値を挿入するなら、次のシーケンス番号が挿入されます。

alias の問題
=========

GROUP BY, ORDER BY, HAVING 節において項目を参照するに当たりエイリアスが使用できます。エイリアスは項目としてより良い名称を与えるのに使用されます：

     SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0;
     SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0;
     SELECT id AS "Customer identity" FROM table_name;

ANSI SQL が WHERE 節内でエイリアスを参照することを許可していないことに注意してください。これは WHERE が実行される時点で項目の値がまだ決定されていないからです。例えば、以下のクエリは あやまりです：

     SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;

どの行が GROUP BY に含まれるかを決めるために WHERE 構文が実行される一方で、得られた結果のどの行を使うか確定するために HAVING が使用されます。

Deleting rows from related tables
=================================

MySQL は現在 sub-select は未サポートで、また DELETE 構文で複数のテーブルを扱う事もサポートしていません。したがって、２つのテーブルに関連するレコードを消すには、以下のようにして行います：

 1. いくつかの WHERE 条件を使用して、基本となるテーブルから行を SELECT

 2. 同じ条件下で、基本となるテーブルに含まれる行を DELETE

 3. DELETE FROM related_table WHERE related_column IN (selected_rows)

related_column のクエリの合計文字数が、1,048,576 (デフォルトは max_allowed_packet の値) をこえる場合、それをいくつかに分割して、複数の DELETE 構文にしなくてはなりません。

related_column がインデックスで、100-1000 のrelated_columnだけを消す場合、よりはやく DELETE できます。もし related_column がインデックスでない場合、その速度は IN 節の引数の数に無関係になります。

Solving problems with no matching rows
======================================

複雑なクエリーを行って、もしなんの結果も返さなければ、そのクエリーの何が悪いかを見つけるため、以下の手続きを行います：

 1. EXPLAIN を使用してクエリーをテストし、明白な間違いを見つけます。 See EXPLAIN.

 2. WHERE 節で使用されているフィールドだけを Select してみます

 3. 結果が返ってくるまで、一つ一つクエリーからテーブルを取り除いていきます。テーブルが大きい場合、LIMIT 10 をクエリーで使用することは良くありません。

 4. 行にマッチすべきであろう項を SELECT してみます。その場合、select するのは、上記で最後に取り除いたテーブルに対して行います。

 5. もし FLOAT か DOUBLE 型のものを数字と比較するなら、 = は使用しないでください！これはほとんどのコンピュータ言語において、浮動小数点の値はぴったりの値にならないからです。

          mysql> SELECT * FROM table_name WHERE float_column=3.5;
             ->
          mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;

     In most cases, changing the FLOAT to a DOUBLE will fix this!

 6. もしなにも悪いところを見つけることができなかった場合、小さなテストをつくって mysql test < query.sql を行ってみてください。 mysqldump --quick database tables > query.sql でテストファイルを作成できます。このファイルをエディターで編集し、いくつかのinsert行を(多すぎるなら)消します。そしてファイルの最後にselect構文を付け足します。

     テストを行うには：

          shell> mysqladmin create test2
          shell> mysql test2 < query.sql

     mysqlbug を使用して mysql@lists.mysql.com にテストを投稿してください。

Problems with ALTER TABLE.
==========================

もし ALTER TABLE が以下のようなエラーで死んだ場合：

     Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)

これは以前の ALTER TABLE で MySQL がクラッシュしており、 A-something か B-something という名前の、誤った情報を流している古いテーブルが存在しています。この場合、MySQL データディレクトリに入り、A- や B- で始まる名前を持つファイルを全て消します。 (消す代わりにどこかに移動しても構いません。)

ALTER TABLE は以下のように動作します:

  * 変更要求のあった A-xxx という名前の新しいテーブルを作成。

  * 元のテーブル内の全ての行を A-xxx にコピー。

  * 元のテーブルを B-xxx に名称変更。

  * A-xxx は元のテーブル名に名称変更される。

  * B-xxx は消去される。

もし名称変更の際に問題があると、MySQL は変更を取り消すように動きます。致命的な問題が起きた場合(ありえませんが)、MySQL は元の古いテーブルを B-xxx という名前のままにしておきます。単に名称変更すればデータは戻ります。

How to change the order of columns in a table
=============================================

The whole point of SQL is to abstract the application from the data storage format.  You should always specify the order in wish you wish to retrieve your data.  For example:

     SELECT col_name1, col_name2, col_name3 FROM tbl_name;

will return columns in the order col_name1, col_name2, col_name3, whereas:

     SELECT col_name1, col_name3, col_name2 FROM tbl_name;

will return columns in the order col_name1, col_name3, col_name2.

You should NEVER, in an application, use SELECT * and retrieve the columns based on their position, because the order in which columns are returned CANNOT be guaranteed over time; A simple change to your database may cause your application to fail rather dramatically.

If you want to change the order of columns anyway, you can do it as follows:

 1. Create a new table with the columns in the right order.

 2. Execute INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table.

 3. Drop or rename old_table

 4. ALTER TABLE new_table RENAME old_table

Solving some common problems with MySQL
***************************************

更新ログを使用したデータベースの複製
==================

Now that master-slave internal replication is available starting in 3.23.15, this is the recommended way. However, it is still possible to replicate a database by using the update log. See Update log. これは、一つのデータベースがマスター(主)として動作ふるまっており (全てのデータ変更がここで行われます)、かつ、一つ以上の他のサーバーがスレーブ(従)として動作していることを要求します。スレーブを更新するには mysql < update_log を実行するだけです。スレーブデータベースのホスト、ユーザー、パスワードをコマンドのオプションに与え、マスターから取得した更新ログを入力に使用します。

もし、テーブルからなにも削除しない場合、 TIMESTAMP フィールドを使用すれば、最後の複製時以後に、新規に挿入されたものや変更されたものだけをミラーサーバーにコピーできます。(最後の複製を行った時間と比較すれば抽出できます)

更新ログ(削除のため)とタイムスタンプ(両側で)の両方を使用する2つの方法の更新システムを作ることができます。しかしこの場合は、同じデータが両側で変更された時に、あなたが衝突を操作できなければなりません。あなたはおそらく何が更新されたかを決定するのを助けるために、古いバージョンを保持したいでしょう。

この時行う複製には SQL ステートメントで行われるため、データベースを更新するステートメント中で次の関数は使ってはいけません。これらは他のコピー元のサーバとは違う値を返すからです:

  * DATABASE()

  * GET_LOCK() and RELEASE_LOCK()

  * RAND()

  * USER(), SYSTEM_USER() or SESSION_USER()

  * VERSION(), CONNECT_ID()

全ての時刻関数は、必要な場合にミラーにタイムスタンプを送るようにして、安全に使用できます。LAST_INSERT_ID() も安全に使用できます。

データベースのバックアップ
=============

MySQL テーブルはファイルとして格納されるため、バックアップを行うのは簡単です。矛盾のないバックアップを得るためには、LOCK TABLES を関連するテーブルで行ってください。See LOCK TABLES. 読み込みロックだけが必要なので、そのテーブルでデータベースディレクトリのファイルのコピーが行われている間も、他のスレッドはクエリを継続できます。もしくは、テーブルを SQL レベルでバックアップしたいのであれば、SELECT INTO OUTFILE を使用できます。

他の方法は mysqldump プログラムを使用することです:

 1. フルバックアップをとるには：

          shell> mysqldump --tab=/path/to/some/dir --opt --full

     若しサーバーがいっさいデータの変更をしないのであれば、単に全てのテーブルファイル(*.frm, *.MYD, *.MYI files)をコピーするだけでも構いません。 The script mysqlhotcopy does use this method.

 2. mysqld を止め、そして --log-update[=file_name] オプションをつけて起動します。 See Update log.  ログファイルは、 mysqldump 実行後に行われたデータベースの変更を複製するための情報を与えてくれます。

もしリストアをしなければならない場合、まず最初に myisamchk -r を実行してテーブルの修復を試みてください。ほとんどの場合、99.9% 修復はできるはずです。もし myisamchk が失敗した場合、以下のようにします： (This will only work if you have started MySQL with --log-update. See Update log.)

 1. オリジナルの mysqldump バックアップデータをリストアします。

 2. 以下のコマンドのようにして、更新ログに記録されている変更を適用します。

          shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql

ls は、全ての更新ログファイルを正しい順で得るために行われます。

SELECT * INTO OUTFILE 'file_name' FROM tbl_name での選択的バックアップと LOAD DATA FROM INFILE 'file_name' REPLACE ... でのリストアを行うこともできます。重複レコードを避けるためには、テーブル内に PRIMARY KEY or a UNIQUE が必要です。REPLACE は、'重複インデックス' 衝突があった場合、新しいレコードを挿入する時に古いレコードが新しいものに置き換えられることを意味します。

更新ログ
====

--log-update=file_nameオプションを使用してmysqldを起動すると、データを更新した全てのSQLコマンドをログファイルに書きます。もし file_name が与えられなかった場合は、ホスト名がデフォルトで使用されます。もし file_name にディレクトリパスが含まれなかった場合は、このファイルはデータディレクトリに書かれます。もし file_name が拡張を持たなかったなら、mysqld は file_name.# という形でログファイルを作成します。このログファイルはデータディレクトリにかかれ、その名前は file_name.# という形式の名前になっています。

# は mysqladmin refresh か mysqladmin flush-logs を実行する度に、あるいは FLUSH LOGS 構文を実行したり、サーバーをリスタートする度に自動的に増える数字です。

もし --log か -l オプションを使用した場合、ログファイルの名前は mysqld は全部のログを hostname.log に書き出します。この場合、リスタートやりフレッシュを行っても新しくログファイルを作りません。 (一度クローズして再度オープンしますが。) デフォルトでは、mysql.server スクリプトは -l オプションを付加して MySQL サーバーを起動します。もし MySQL のパフォーマンスをあげて本番環境などで使用したい場合、 mysql.server スクリプトから -l オプションを外してください。

更新ログは、実際に更新されたデータのステートメントだけを書くため、きびきびと動作します。 WHERE を使用した UPDATE か DELETE で結果が得られなかった場合、ログは書き出されません。すでにセットされている値に、もう一度項目を更新するような UPDATE もスキップされます。

ログファイルの更新に従ってデータベースを更新したい場合は、次を行います (更新ログファイル名を file_name.# と仮定します):

     shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql

ls は全てのログファイルを正しく並べるために使用しています。

これは、クラッシュ後にバックアップした状態まで戻りたい、あるいは、バックアップした後からクラッシュするまでの間のデータの更新を行いたい、そんな場合に使えます。

ログは違うホストのデータベースのミラーやマスターデータベースの複製を作る場合にも利用できます。 See Replication.

同一マシン上に複数の MySQL サーバーを走らせる
==========================

同じマシン上で複数のサーバーを走らせたい場合があります。例えば、すでに存在しているサーバーはそのままにしておいて、新しい MySQL をテストしたい場合や、あるいは、インターネットプロバイダーを営んでいて、MySQL をそれぞれの顧客用に提供したい場合など。

複数のサーバーをたちあげる場合、簡単な方法として、 TCP/IP ポート、ソケットファイルを変えて、サーバーをコンパイルする方法があります。

そでに走っているサーバーがデフォルトのポート番号とソケットファイルで動作しているとします。新しくサーバーを作るには、以下のように configure します：

     shell> ./configure  --with-tcp-port=port_number \
                  --with-unix-socket=file_name \
                  --prefix=/usr/local/mysql-3.22.9

port_number と file_name には、デフォルトのポート番号、ソケットファイルとは違うものを指定します。そして --prefix を、すでに走っている MySQL のインストール先とは違うディレクトリーに指定します。

現在走っている MySQL サーバーのソケットとポートを知るには、以下のようにします：

     shell> mysqladmin -h hostname --port=port_number variables

あなたが使用しているポートに MySQL サーバーが走っていれば、これは変更可能な MySQL 変数を(ソケットファイルの名前も含んで)出力します。

立ち上げスクリプト(おそらく mysql.server ファイル)を編集して複数の MySQL サーバーを立ちあげても構いません。

この場合、 MySQL サーバーを再コンパイルする必要はありません。 safe_mysqld のオプションを指定してサーバーを起動すれば、ポートとソケットを変更できます：

     shell> /path/to/safe_mysqld --socket=file-name --port=port_number

もし、他のサーバーがロギングを行っているディレクトリと同じデータベースディレクトリを、新しいサーバーで使用するのであれば、ログファイルの名前を指定すべきです。 ( safe_mysqld に --log と --log-update を指定する) そうしないと、両方のサーバーが同じログファイルに書き込もうとするからです。

Warning: 通常、二つサーバーに同じデータベースを操作させてはいけません！もし使用している OS が fault-free system locking をサポートしていないと、これは悲惨なことになるでしょう！

もし二つ目のサーバーに違うデータベースディレクトリを使用させたい場合、 safe_mysqld に --datadir=path オプションを指定します。

     shell> /path/to/safe_mysqld --datadir=/new/path/to/datadir \
                     --socket=file-name --port=file-name

もし違うポートで走っている MySQL サーバーに、これまた違うポートを使用するように作られたクライアントから接続したい場合、以下のようにします：

  * クライアントを --host 'hostname' --port=port_numer か [--host localhost] --socket=file_name オプションで起動します。

  * C あるいは Perl プログラムの場合、ポートとソケットを与えることができます：

  * MYSQL_UNIX_PORT と MYSQL_TCP_PORT 環境変数に UNIX ソケットファイルと TCP/IP のポート番号とセットし、クライアントを立ちあげます。もし、このポート番号やソケットファイルを常に使用するのであれば、 .login ファイルかなにかに環境変数をセットするように書いておけばよいでしょう。 See Environment variables. See Programs.

  * あなたのホームディレクトリの .my.cnf ファイルに、通常使用するポート番号とソケットファイルを書くこともできます。 See Option files.

MySQL クライアントツールと API
********************

MySQL C API
===========

C API コードは MySQL とともに配布されます。これは libmysqlclient ライブラリに含まれ、C プログラムからデータベースへのアクセスを許します。

MySQL ソースディストリビューション内のクライアントの多くは C で書かれています。C API の使用法を示す例を探すなら、これらのクライアントを調べてください。

他のクライアント API の多く(Java を除く全て)は、MySQL サーバとの通信にこのライブラリを使用します。そのため、例えば、他のクライアントプログラムで使用されるのと同じ環境変数の多くの利点を得ることができます。それらはライブラリから参照されるからです。これらの変数のリストについては Programs を参照して下さい。

クライアントは最大通信バッファサイズを持ちます。最初に割り当てられるバッファのサイズ(16K バイト)は自動的に最大サイズ(デフォルトは 24M)まで増加します。バッファサイズは必要に応じて増加するため、単純にデフォルトの最大制限を増加しても、さらに内部で資源を使用することはありません。このサイズチェックは主に間違ったクエリと通信パケットのためのチェックです。

通信バッファは一つの SQL ステートメント(クライアントからサーバへの通信)と、返されるデータ(サーバからクライアントへの通信)の１レコードを含むのに十分大きくなくてはいけません。各スレッドの通信バッファは、任意のレコードやクエリを処理するために、指定された制限まで動的に増大します。例えば、最大 16M のデータを含む BLOB 値がある場合、少なくとも 16M を通信バッファ制限として持つ必要があります(サーバとクライアントの両方で)。クライアントのデフォルトの最大値は 24M ですが、サーバの最大値のデフォルトは 1M です。これはサーバ起動時に、max_allowed_packet パラメータの値を変更することにより、増やすことが出来ます。 See Server parameters.

MySQL サーバは、各クエリ後に各通信バッファを net_buffer_length バイトに縮小します。クライアントでは、接続に割り当てられたバッファのサイズは、接続が閉じられるまで減少しません。クライアントメモリは接続がクローズされた時に調整されます。

スレッドプログラミングを行なう場合は、MySQL C API を --with-thread-safe-client 付きでコンパイルすべきです。これは C API を接続毎のスレッド安全にします。次の場合に限り、２つのスレッドは同じ接続を共有できます:

     ２つのスレッドが同じ接続上で同時に MySQL にクエリを送信することはできません。特に mysql_query() と mysql_store_result() の間で、他のスレッドが同じ接続を使用しないことを確実にする必要があります。

     多くのスレッドが mysql_store_result() で取り出された別々の結果セットにアクセスできます。

     mysql_use_result を使用する場合、結果セットがクローズされるまで、他のスレッドが同じ接続上で何も尋ねないことを確実にする必要があります。

C API データ型
==========

MYSQL
     この構造体は一つのデータベース接続のハンドルを表わします。これはほとんど全ての MySQL 関数に使用されます。

MYSQL_RES
     この構造体はレコードを返すクエリ(SELECT, SHOW, DESCRIBE, EXPLAIN)の結果を表わします。クエリから返される情報は、この節の残りでは結果セットと呼ばれます。

MYSQL_ROW
     これはデータの１レコードの安全な型表現です。これは現在バイト文字列の配列として実装されています。(フィールド値がバイナリデータを含むことがある場合、これを NULL 終端文字列として扱うことはできません。そのような値は内部に NULL バイトを含むことがあるからです。) mysql_fetch_row() の呼び出しによりレコードが獲得されます。

MYSQL_FIELD
     この構造体はフィールドについての情報、つまりフィールドの名前、型、サイズ等を含んでいます。このメンバは後でさらに詳細に説明されています。 mysql_fetch_field() を繰り返し呼び出すことにより、各フィールドの MYSQL_FIELD 構造体を得ることができます。フィールド値はこの構造体の一部ではありません; それは MYSQL_ROW 構造体に含まれています。

MYSQL_FIELD_OFFSET
     これは、MySQL フィールドリストへのオフセットの安全な型表現です。 (mysql_field_seek() で使用されます。)オフセットはレコード内のフィールド番号で、0 から始まります。

my_ulonglong
     レコード数と mysql_affected_rows(), mysql_num_rows() そして mysql_insert_id() に使用される型です。この型は 0 から 1.84e19 の範囲を与えます。

     システムによっては、my_ulonglong 型の値を表示しようとしても、動作しないことがあります。この値を表示するには、unsigned long に変換し、%lu 出力書式を使用してください。例:

          printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));

MYSQL_FIELD 構造体は次のメンバを含みます:

char * name
     フィールドの名前。null終端文字列。

char * table
     このフィールドを含むテーブルの名前。計算されたフィールドでない場合のみ有効です。計算されたフィールドでは、table 値は空文字列です。

char * def
     このフィールドのデフォルト値。null終端文字列。これは mysql_list_fields() 使用時にだけ設定されます。

enum enum_field_types type
     フィールドの型。 type 値は次の一つです:

     型の値                       型の意味
     FIELD_TYPE_TINY              TINYINT フィールド
     FIELD_TYPE_SHORT             SMALLINT フィールド
     FIELD_TYPE_LONG              INTEGER フィールド
     FIELD_TYPE_INT24             MEDIUMINT フィールド
     FIELD_TYPE_LONGLONG          BIGINT フィールド
     FIELD_TYPE_DECIMAL           DECIMAL または NUMERIC フィールド
     FIELD_TYPE_FLOAT             FLOAT フィールド
     FIELD_TYPE_DOUBLE            DOUBLE または REAL フィールド
     FIELD_TYPE_TIMESTAMP         TIMESTAMP フィールド
     FIELD_TYPE_DATE              DATE フィールド
     FIELD_TYPE_TIME              TIME フィールド
     FIELD_TYPE_DATETIME          DATETIME フィールド
     FIELD_TYPE_YEAR              YEAR フィールド
     FIELD_TYPE_STRING            文字列 (CHAR または VARCHAR) フィールド
     FIELD_TYPE_BLOB              BLOB または TEXT フィールド (最大長を確定するには max_length を使用して下さい)
     FIELD_TYPE_SET               SET フィールド
     FIELD_TYPE_ENUM              ENUM フィールド
     FIELD_TYPE_NULL              NULL型 フィールド
     FIELD_TYPE_CHAR              非推奨; FIELD_TYPE_TINY を代わりに使用してください

     IS_NUM() マクロで、フィールドが数値タイプかどうかをテストできます。フィールドが数値の場合、type メンバを IS_NUM() に渡すと TRUE と評価します:

          if (IS_NUM(field->type))
              printf("Field is numeric\n");

unsigned int length
     フィールドの幅。これはテーブル定義で指定されたものです。

unsigned int max_length
     結果セットのフィールドの最大幅(実際の結果セットの中のレコードの最長フィールド値の長さ)。mysql_store_result() または mysql_list_fields() を使用する場合は、これはフィールドの最大幅になります。 mysql_use_result() を使用する場合は、この変数の値は 0 になります。

unsigned int flags
     フィールドの種々のビットフラグ。flags 値は 0 または次のビットの一つ以上の組み合わせです:

     フラグの値            フラグの意味
     NOT_NULL_FLAG         フィールドは NULL にできない
     PRI_KEY_FLAG          フィールドはプライマリキーの一部である
     UNIQUE_KEY_FLAG       フィールドはユニークキーの一部である
     MULTIPLE_KEY_FLAG     フィールドは非ユニークキーの一部である
     UNSIGNED_FLAG         フィールドは UNSIGNED 属性を持っている
     ZEROFILL_FLAG         フィールドは ZEROFILL 属性を持っている
     BINARY_FLAG           フィールドは BINARY 属性を持っている
     AUTO_INCREMENT_FLAG   フィールドは AUTO_INCREMENT 属性を持っている
     ENUM_FLAG             フィールドは ENUM である (非推奨)
     BLOB_FLAG             フィールドは BLOB または TEXT である (非推奨)
     TIMESTAMP_FLAG        フィールドは TIMESTAMP である (非推奨)

     BLOB_FLAG, ENUM_FLAG, TIMESTAMP_FLAG の使用は推奨されません。これらは型の属性ではなくフィールドの型を示すからです。代わりに field->type を FIELD_TYPE_BLOB, FIELD_TYPE_ENUM, FIELD_TYPE_TIMESTAMP に対してテストする方をお勧めします。

     次の例は flags 値の典型的な使用を示しています:

          if (field->flags & NOT_NULL_FLAG)
              printf("Field can't be null\n");

     flags 値の真偽状態を調べるために、次の便利なマクロを使用できます:

     IS_NOT_NULL(flags)   このフィールドが NOT NULL として定義されていれば真
     IS_PRI_KEY(flags)    このフィールドがプライマリキーならば真
     IS_BLOB(flags)       このフィールドが BLOB または TEXT ならば真 (非推奨; 代わりに field->type をテストして下さい)

unsigned int decimals
     数値フィールドの小数部桁数。

C API 関数概要
==========

C API には次に一覧された関数が存在します。これらの関数は次の節でかなり詳細に説明されています。 See C API functions。

mysql_affected_rows()
最後の UPDATE, DELETE, INSERT クエリによって影響さ
れたレコード数を返します。

mysql_close()
サーバ接続をクローズします。

mysql_connect()
MySQL サーバに接続します。この関数は推奨されません; 代わりに
mysql_real_connect() を使用してください。

mysql_change_user()
接続中ののユーザとデータベースを変更します。

mysql_create_db()
データベースを生成します。この関数は推奨されません; 代わりに SQL コマン
ド CREATE DATABASE を使用してください。

mysql_data_seek()
クエリ結果セット中の任意のレコードにシークします。

mysql_debug()
与えられた文字列で DBUG_PUSH を行ないます。

mysql_drop_db()
データベースを破棄します。この関数は推奨されません; 代わりに SQL コマン
ド DROP DATABASE を使用してください。

mysql_dump_debug_info()
サーバに、デバッグ情報をログに書き出させます。

mysql_eof()
結果セットの最後のレコードが読まれたかどうかを判定します。この関数は推奨されませ
ん; 代わりに mysql_errno() または mysql_error() を使用して下
さい。

mysql_errno()
最後の MySQL 関数からのエラー番号を返します。

mysql_error()
最後の MySQL 関数からのエラーメッセージを返します。

mysql_real_escape_string()
Escapes special characters in a string for use in a SQL statement taking
into account the current charset of the connection.

mysql_escape_string()
SQL ステートメント内で使用するために文字列中の特殊文字をエスケープします。

mysql_fetch_field()
テーブルの次のフィールドの型を返します。

mysql_fetch_field_direct()
テーブルの、番号で指定されたフィールドの型を返します。

mysql_fetch_fields()
全てのフィールド構造体の配列を返します。

mysql_fetch_lengths()
現在のレコード中の全てのフィールドの長さを返します。

mysql_fetch_row()
結果セットから次のレコードを取り出します。

mysql_field_seek()
指定されたフィールド上にフィールドカーソルを置きます。

mysql_field_count()
最後のクエリの結果のフィールドの数を返します。

mysql_field_tell()
最後の mysql_fetch_field() で使用されたフィールドカーソルの位置を返
します。

mysql_free_result()
結果セットによって使用されたメモリを解放します。

mysql_get_client_info()
クライアントバージョン情報を返します。

mysql_get_host_info()
接続を説明する文字列を返します。

mysql_get_proto_info()
接続に使用されるプロトコルバージョンを返します。

mysql_get_server_info()
サーバのバージョン番号を返します。

mysql_info()
最後に実行されたクエリについての情報を返します。

mysql_init()
MYSQL 構造体を獲得または初期化します。

mysql_insert_id()
AUTO_INCREMENT フィールドに最後に生成された ID を返します。

mysql_kill()
指定されたスレッドを殺します。

mysql_list_dbs()
簡易正規表現に適合するデータベース名を返します。

mysql_list_fields()
簡易正規表現に適合するフィールド名を返します。

mysql_list_processes()
現在のサーバスレッドのリストを返します。

mysql_list_tables()
簡易正規表現に適合するテーブル名を返します。

mysql_num_fields()
結果セット中のフィールド数を返します。

mysql_num_rows()
結果セット中のレコード数を返します。

mysql_options()
mysql_connect() のための接続オプションを設定します。

mysql_ping()
サーバへの接続が動作しているかどうかをチェックします。
必要であれば再接続します。

mysql_query()
NULL 終端文字列として記述された SQL クエリを実行します。

mysql_real_connect()
MySQL サーバに接続します。

mysql_real_query()
数えられた文字列として記述された SQL クエリを実行します。

mysql_reload()
権限テーブルを再読み込みするようにサーバに指示します。

mysql_row_seek()
結果セット内のあるレコードへシークします。mysql_row_tell() から返される値を
使用します。

mysql_row_tell()
レコードカーソルの位置を返します。

mysql_select_db()
データベースを選択します。

mysql_shutdown()
データベースサーバをシャットダウンします。

mysql_start_slave()
Starts slave replication thread

mysql_stat()
文字列でサーバ状態を返します。

mysql_store_result()
クライアントに完全な結果セットを取り出します。

mysql_stop_slave()
Stops slave replication thread

mysql_thread_id()
現在のスレッド ID を返します。

mysql_thread_save()
Returns 1 if the clients are compiled as threadsafe.

mysql_use_result()
各レコードの動的結果セットを初期化します。

サーバへ接続するには、接続ハンドラを初期化するために mysql_init() を呼びだし、それから mysql_real_connect() をそのハンドラで呼びだします (ホスト名、ユーザ名、パスワードのような他の情報に加えて)。 Upon connection, mysql_real_connect() sets the reconnect flag (part of the MYSQL structure) to a value of 1. This flag indicates, in the event that a query cannot be performed because of a lost connection, to try reconnecting to the server before giving up. その接続での処理が終了した時は、接続を終了させるために mysql_close() を呼びだします。

接続が有効な間は、クライアントは mysql_query() または mysql_real_query() を使用して SQL クエリをサーバに送信できます。この２つの違いは、mysql_query() は NULL終端文字列としてクエリが記述されることを期待するのに対し、mysql_real_query() は数えられた文字列を期待することです。文字列がバイナリデータ(NULバイトを含みことがある)を含む場合は、mysql_real_query() を使用する必要があります。

非SELECT クエリ(例えば、INSERT, UPDATE, DELETE)では、どれくらいのレコードが影響(変更)されたかを mysql_affected_rows() を呼び出すことで見つけ出すことができます。

SELECT クエリでは、選択されたレコードを結果セットとして取り出します。 (注意: いくつかのステートメントは、レコードを返すという点で SELECTに似ています。それは SHOW, DESCRIBE, EXPLAIN です。これらは SELECT ステートメントと同じ方法で扱われるべきです。)

クライアントが結果セットを処理するには２つの方法があります。一つ目は、 mysql_store_result() を呼び出すことで、結果セット全体を一度にすべて取り出すことです。この関数はサーバからクエリによって返されるすべてのレコードを取得し、それをクライアントに格納します。二つ目は、 mysql_use_result() を呼び出すことで、レコードごとの結果セット取り出しを初期化することです。この関数は取り出しを初期化しますが、実際にはサーバから何のレコードも得ません。

どちらの場合でも、mysql_fetch_row() を呼び出してレコードにアクセスします。mysql_store_result() では、mysql_fetch_row() は既にサーバから取得してあるレコードにアクセスします。 mysql_use_result() では、mysql_fetch_row() は実際にサーバからレコードを取り出します。各レコードのデータ値のサイズについての情報は mysql_fetch_lengths() を呼び出すことで得られます。

結果セットでの処理が終った後は、mysql_free_result() を呼び出し、それが使用していたメモリを解放して下さい。

この２つの取り出し機構は相補的なものです。クライアントプログラムは、必要によってもっとも適切なアプローチを選択すべきです。慣例的に、クライアントは一般に mysql_store_result() を使用する傾向にあります。

mysql_store_result() の利点は、すべてのレコードをクライアントに取って来るため、連続してレコードをアクセスできるだけでなく、結果セット中の現在のレコード位置を変更するために、mysql_data_seek() や mysql_row_seek() を使用して、結果セットの中を後や前に移動することができます。また、mysql_num_rows() を呼び出すことで、レコード数を見つけることもできます。一方、mysql_store_result() の必要メモリは、大きな結果セットではとても高く、out-of-memory 状態に遭遇する可能性が高くなります。

mysql_use_result() の利点は、一度に一つのレコードだけを保持するため、クライアントが結果セットに要求するメモリが少ないことです（そして、割当のオーバーヘッドも少ないので、mysql_use_result() はより速くなります）。不利な点は、サーバの拘束を避けるため、各レコードを素早く処理する必要があること、結果セット中でレコードのランダムアクセスができないこと（レコードを順番にアクセスすることしかできません）、そして、すべてのレコードを取り出さない限り、結果セット中にいくつのレコードがあるかを知ることができないことです。さらに、あなたが探している情報を、検索の途中で見つけることができて、問題が解決したとしても、すべてのレコードを取り出さなければなりません。

API はクライアントがクエリが SELECT であるかどうかを知ることなしに、（必要時だけレコードを取り出す）クエリに適切に応答できるようにします。それぞれの mysql_query()（または mysql_real_query()）の後で、 mysql_store_result() を呼び出すことで、これが可能です。結果セットの呼び出しが成功すると、クエリは SELECT であり、レコードを読むことができます。結果セット呼び出しが失敗した場合は、結果が実際に期待されたものであるかどうかを確定するために、mysql_field_count() を呼び出してください。mysql_field_count() が 0 を返す場合は、クエリはデータを返しません（クエリが INSERT, UPDATE, DELETE 等であることを示します）。つまりレコードが返ることを期待できません。 mysql_field_count() が 0 でない場合は、クエリはレコードを返すべきなのに、返さなかったということです。これはクエリが SELECT で失敗したということを示します。これをどのように行なうことができるかの例は、 mysql_field_count() の説明を参照してください。

mysql_store_result() と mysql_use_result() はどちらも、結果セットを作るフィールドについての情報（フィールドの数、その名前や型など）を獲得することができます。mysql_fetch_field() を繰り返し呼び出すことで順番に、または、mysql_fetch_field_direct() を呼び出すことでレコード内のフィールド番号で、レコード内のフィールド情報にアクセスすることができます。現在のフィールドカーソル位置は mysql_field_seek() を呼び出すことで変更できます。フィールドカーソルの設定は、その後の mysql_fetch_field() 呼び出しに影響します。 mysql_fetch_fields() を呼び出すことで、一度にすべてのフィールドの情報を得ることもできます。

エラーの検出、報告については、mysql_errno() と mysql_error() 関数の方法によって、MySQL はエラー情報へのアクセスを提供します。これらは、最後に呼び出された成功または失敗し得る関数についてのエラーコードとエラーメッセージを返し、エラーがいつ何で発生したかを確定することができます。

C API 関数説明
==========

以下の説明では、NULL の引数または戻り値は C プログラミング言語での NULL を意味します。MySQL NULL 値ではありません。

関数は通常ポインタか整数の値を返します。しかし関数説明に記述がある場合、ポインタを返す関数は、成功を示すために非 NULL 値を返し、エラーを示すために NULL を返します。整数を返す関数は、成功を示すために 0 を返し、エラーを示すために非0を返します。``非0'' は関数説明が他に述べていない限り、その意味になることに注意してください; 関数説明が他に述べている場合、これらに対して 0 以外の固有の値をテストしないでください:

     if (result)                   /* 正しい */
         ... error ...

     if (result < 0)               /* 間違い */
         ... error ...

     if (result == -1)             /* 間違い */
         ... error ...

関数がエラーを返すとき、関数説明の エラー 節が起り得るエラーの種類を一覧しています。mysql_errno() の呼び出しによってどれが発生したかを見つけ出すことができます。エラーを表現する文字列は mysql_error() の呼び出しによって得られます。

mysql_affected_rows()
---------------------

my_ulonglong mysql_affected_rows(MYSQL *mysql)

説明
..

最後の UPDATE, DELETE, INSERT クエリによって影響された(変更された)行数を返します。UPDATE, DELETE, INSERT ステートメントでの mysql_query() 直後に呼び出します。SELECT ステートメントでは、これは mysql_num_rows() に似た動きをします。

mysql_affected_rows() は現在マクロとして実装されています。

戻り値
...

0 より大きい整数は影響された行数または取り出された行数を示します。クエリの WHERE 節に適合したレコードがない場合またはクエリがまだ実行されていない場合は 0 です。クエリがエラーを返したか、SELECT クエリについて mysql_store_result() が呼ばれる前に mysql_affected_rows() が呼ばれた場合は -1 です。

エラー
...

無し。

例
.

     mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
     printf("%d products updated",mysql_affected_rows(&mysql));

mysql_close()
-------------

void mysql_close(MYSQL *mysql)

説明
..

前にオープンされた接続をクローズします。ハンドルが mysql_init() または mysql_connect() で自動的に割り当てられた場合、 mysql_close() は mysql で示される接続ハンドルの解放も行ないます。

戻り値
...

無し。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_connect()
---------------

MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)

説明
..

この関数は推奨されません。代わりに mysql_real_connect() の使用をお勧めします。

mysql_connect() は host 上で動作している MySQL データベースエンジンへの接続の確立を試みます。mysql_get_client_info() を除く他のすべての API 関数を実行する前にmysql_connect() が成功終了している必要があります。

パラメータの意味は mysql_real_connect() の対応するパラメータと同じですが、接続パラメータは NULL にできることが異なります。この場合 C API は接続構造体に自動的にメモリを割り当て、mysql_close() 呼び出し時にそれを解放します。このアプローチの不利な点は接続が失敗した場合にエラーメッセージを取り出すことができないことです。（mysql_errno() または mysql_error() からエラー情報を得るには、正しい MYSQL ポインタを提供する必要があります。）

戻り値
...

mysql_real_connect() と同じ

エラー
...

mysql_real_connect() と同じ

mysql_change_user()
-------------------

my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)

説明
..

ユーザを変更し、mysql で示された接続上で、db で示されたデータベースがデフォルト（現在の）データベースになります。その後のクエリでは、明示的なデータベースの指定を含んでいないテーブル参照について、このデータベースがデフォルトになります。

この関数は MySQL 3.23.3 で導入されました。

mysql_change_user() は接続されたユーザが認証されない場合、またはデータベースを使用する権限を持っていない場合に失敗します。この場合、ユーザとデータベースは変更されません。

デフォルトデータベースを持ちたくない場合、db パラメータを NULL に設定できます。

戻り値
...

成功時 0。エラーが発生した場合は非0。

エラー
...

mysql_real_connect() から得られるものと同じです。

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

ER_UNKNOWN_COM_ERROR
     MySQL サーバはこのコマンドを実装していない（おそらく古いサーバ）。

ER_ACCESS_DENIED_ERROR
     ユーザまたはパスワードが間違っている。

ER_BAD_DB_ERROR
     データベースが存在しない。

ER_DBACCESS_DENIED_ERROR
     ユーザがデータベースへのアクセス権を持っていない。

ER_WRONG_DB_NAME
     データベース名が長過ぎる。

例
.

     if (mysql_change_user(&mysql, "user", "password", "new_database"))
     {
        fprintf(stderr, "Failed to change user.  Error: %s\n",
                mysql_error(&mysql));
     }

mysql_create_db()
-----------------

int mysql_create_db(MYSQL *mysql, const char *db)

説明
..

db 引数によって指定されたデータベースを作成します。

この関数は推奨されません。代わりに mysql_query() を使って、SQL CREATE DATABASE ステートメントを発行することをお勧めします。

戻り値
...

データベースの作成が成功した場合は0。エラーが発生した場合は非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

例
.

     if(mysql_create_db(&mysql, "my_database"))
     {
        fprintf(stderr, "Failed to create new database.  Error: %s\n",
                mysql_error(&mysql));
     }

mysql_data_seek()
-----------------

void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)

説明
..

クエリ結果セット中の任意のレコードにシークします。これは、結果セット構造体がクエリのすべての結果を持っていることを要求します。そのため、 mysql_data_seek() は mysql_store_result() と共にだけ使用され、 mysql_use_result() と共には使用できません。

オフセットの値は 0 から mysql_num_rows(result)-1 でなくてはなりません。

戻り値
...

無し。

エラー
...

無し。

mysql_debug()
-------------

void mysql_debug(char *debug)

説明
..

与えられた文字列で DBUG_PUSH を行ないます。mysql_debug() は Fred Fish が作成した debug library を使用します。この関数を使用するためには、デバッグをサポートするように、クライアントライブラリをコンパイルする必要があります。 See Debugging server. See Debugging client.

戻り値
...

無し。

エラー
...

無し。

例
.

次に示した呼び出しは、クライアントライブラリが、クライアントマシン上の /tmp/client.trace にトレースファイルを生成します:

     mysql_debug("d:t:O,/tmp/client.trace");

mysql_drop_db()
---------------

int mysql_drop_db(MYSQL *mysql, const char *db)

説明
..

db 引数によって指定されたデータベースを破棄します。

この関数は推奨されません。代わりに mysql_query() を使って、SQL DROP DATABASE ステートメントを発行することをお勧めします。

戻り値
...

データベースの破棄が成功した場合は0。エラーが発生した場合は非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

例
.

     if(mysql_drop_db(&mysql, "my_database"))
       fprintf(stderr, "Failed to drop the database: Error: %s\n",
               mysql_error(&mysql));

mysql_dump_debug_info()
-----------------------

int mysql_dump_debug_info(MYSQL *mysql)

説明
..

いくつかのデバッグ情報をログにダンプするようにサーバに指示します。この動作をするためには、接続されたユーザが process 権を持っていなければなりません。

戻り値
...

コマンドが成功した場合は0。コマンドが失敗した場合は非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_eof()
-----------

my_bool mysql_eof(MYSQL_RES *result)

説明
..

この関数は推奨されません。mysql_errno() か mysql_error() が代わりに使用できます。

mysql_eof() は結果セットの最後のレコードが読まれたかどうかを調べます。

mysql_store_result() の呼び出しが成功して、結果セットを入手した場合、クライアントは一つのオペレーションですべてのセットを受け取ります。この場合、 mysql_fetch_row() から返される NULL は、常に結果セットの終端に達したことを意味し、mysql_eof() を呼ぶ必要はありません。

一方、結果セット取り出しの初期化のために mysql_use_result() を使用する場合、セットのレコードは mysql_fetch_row() を繰り返し呼ぶことにより、ひとつずつサーバから獲得されます。この処理中に接続上でエラーが発生し得るため、mysql_fetch_row() からの戻り値 NULL は、通常必ずしも結果セットの終端に達したことを意味しません。この場合 mysql_eof() を使用して、何が起こったかを検出できます。結果セットの終端に達した場合は mysql_eof() は非0値を返し、エラーが発生した場合は 0 を返します。

歴史的に mysql_eof() は標準 MySQL エラー関数 mysql_errno() と mysql_error() 以前に遡ります。これらのエラー関数は同じ情報を提供するので、これらの使用が mysql_eof() よりも好まれます。mysql_eof() は現在推奨されません。（実際、これらは多くの情報を提供します。エラー関数はエラーが発生した時のエラーの理由を示しますが、 mysql_eof() は真偽値だけを返します。）

戻り値
...

エラーが発生しなかった場合は0。結果セットの終端に達した場合は非0。

エラー
...

無し。

例
.

次の例は mysql_eof の使用方法を示します:

     mysql_query(&mysql,"SELECT * FROM some_table");
     result = mysql_use_result(&mysql);
     while((row = mysql_fetch_row(result)))
     {
         // do something with data
     }
     if(!mysql_eof(result))  // mysql_fetch_row() failed due to an error
     {
         fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
     }

しかし、標準 MySQL エラー関数で同じ効果を得ることができます:

     mysql_query(&mysql,"SELECT * FROM some_table");
     result = mysql_use_result(&mysql);
     while((row = mysql_fetch_row(result)))
     {
         // do something with data
     }
     if(mysql_errno(&mysql))  // mysql_fetch_row() failed due to an error
     {
         fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
     }

mysql_errno()
-------------

unsigned int mysql_errno(MYSQL *mysql)

説明
..

mysql によって指定された接続上で、最後に呼び出された API 関数の成否のエラーコードを返します。戻り値0はエラーが発生しなかったことを意味します。クライアントエラーメッセージ番号は errmsg.h にリストされています。サーバエラーメッセージ番号は mysqld_error.h にリストされています。

戻り値:
....

エラーコード値。エラーが発生していない場合は0。

エラー
...

無し。

mysql_error()
-------------

char *mysql_error(MYSQL *mysql)

説明
..

mysql によって指定された接続上で、 mysql_error() は最後に呼び出された API 関数の成否を、エラーメッセージとして返します。エラー発生しなかった場合は空文字列 ("") が返されます。これは次の２つのテストが同じであることを意味します:

     if(mysql_errno(&mysql))
     {
         // an error occurred
     }

     if(mysql_error(&mysql)[0] != '\0')
     {
         // an error occurred
     }

クライアントエラーメッセージの言語は MySQL クライアントライブラリの再コンパイルで変更できます。現在はいくつかの言語で書かれたクライアントエラーメッセージを選択できます。 See Languages.

戻り値
...

エラーを表わす文字列。エラーが発生していない場合は空文字列。

エラー
...

無し。

mysql_escape_string()
---------------------

You should use mysql_real_escape_string() instead!

This is identical to mysql_real_escape_string() except that it takes the connection as the first argument. mysql_real_escape_string() will escape the string according to the current character set while mysql_escape_string() does not respect the current charset setting.

mysql_fetch_field()
-------------------

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

説明
..

結果セットの一つのフィールドの定義を MYSQL_FIELD 構造体として返します。結果セット内の全てのフィールドについて情報を取り出すには、この関数を繰り返し呼んでください。mysql_fetch_field() はフィールドが残っていないと NULL を返します。

mysql_fetch_field() は、新しい SELECT クエリを実行するたびに、最初のフィールドについての情報を返すようにリセットされます。 mysql_fetch_field() で返されるフィールドは mysql_field_seek() の呼び出しにも影響をうけます。

テーブルを SELECT するために mysql_query() を呼び、しかしまだ mysql_store_result() を呼んでいない場合、 mysql_fetch_field() を BLOB フィールドの長さの問い合わせに使用すると、MySQL はデフォルトの blob 長 (8K bytes) を返します。 (8K サイズになるのは、MySQL は BLOB の最大長を知らないからです。これはいつかコンフィグ可能になるべきです。) 一度結果セットを取り出せば、field->max_length は指定したクエリ内でのこのフィールドの最大値の長さを含みます。

戻り値
...

現在のフィールドの MYSQL_FIELD 構造体。フィールドが残っていない場合は NULL。

エラー
...

無し。

例
.

     MYSQL_FIELD *field;

     while((field = mysql_fetch_field(result)))
     {
         printf("field name %s\n", field->name);
     }

mysql_fetch_fields()
--------------------

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

説明
..

結果セットのすべての MYSQL_FIELD 構造体の配列を返します。各構造体は結果セットの一つのフィールドのフィールド定義を提供します。

戻り値
...

結果セットの全ての項目の MYSQL_FIELD 構造体の配列。

エラー
...

無し。

例
.

     unsigned int num_fields;
     unsigned int i;
     MYSQL_FIELD *fields;

     num_fields = mysql_num_fields(result);
     fields = mysql_fetch_fields(result);
     for(i = 0; i < num_fields; i++)
     {
        printf("Field %u is %s\n", i, fields[i].name);
     }

mysql_fetch_field_direct()
--------------------------

MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)

説明
..

結果セット中のフィールドを示すフィールド番号 fieldnr が与えられ、そのフィールドのフィールド定義を MYSQL_FIELD 構造体として返します。この関数は任意のフィールドについての定義を取り出すことに使用できます。 fieldnr の値は 0 から mysql_num_fields(result)-1 の範囲にすべきです。

戻り値
...

指定されたフィールドの MYSQL_FIELD 構造体。

エラー
...

無し。

例
.

     unsigned int num_fields;
     unsigned int i;
     MYSQL_FIELD *field;

     num_fields = mysql_num_fields(result);
     for(i = 0; i < num_fields; i++)
     {
         field = mysql_fetch_field_direct(result, i);
         printf("Field %u is %s\n", i, field->name);
     }

mysql_fetch_lengths()
---------------------

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

説明
..

結果セット中の現在のレコードのフィールドの長さを返します。フィールドの値をコピーする場合、この長さ情報は最適化にも有用です。strlen() の呼び出しを回避できるためです。さらに、結果セットがバイナリデータを持つ場合は、データのサイズを特定するためにこの関数を使わなければなりません。なぜなら strlen() は NULL 文字を含むフィールドについての結果を正しく返さないからです。

空フィールドの長さと NULL 値を含むフィールドの長さは 0 です。この２つのケースを区別する方法については、mysql_fetch_row() の説明を参照して下さい。

戻り値
...

各フィールドのサイズ (終端 NUL 文字は含みません)を提供する unsigned long 整数の配列。エラーが発生した場合は NULL。

エラー
...

mysql_fetch_lengths() は結果セットの現在のレコードについてだけ有効です。mysql_fetch_row() を呼び出す前、または結果の全てのレコードを取り出した後にこれを呼んだ場合、NULL が返されます。

例
.

     MYSQL_ROW row;
     unsigned long *lengths;
     unsigned int num_fields;
     unsigned int i;

     row = mysql_fetch_row(result);
     if (row)
     {
         num_fields = mysql_num_fields(result);
         lengths = mysql_fetch_lengths(result);
         for(i = 0; i < num_fields; i++)
         {
              printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
         }
     }

mysql_fetch_row()
-----------------

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

説明
..

結果セットの次のレコードを取り出します。mysql_store_result() の後に使用すると、これ以上取り出すレコードがない時は、NULL を返します。 mysql_use_result() の後に使用するなら、これ以上取り出すレコードがない場合やエラーが発生した場合に NULL を返します。

レコード内の値の数は mysql_num_fields(result) によって与えられます。 row が mysql_fetch_row() の呼び出しからの戻り値を保持する場合、値へのポインタは row[0] から row[mysql_num_fields(result)-1 としてアクセスされます。レコード内の NULL 値はNULL ポインタによって示されます。

レコードのフィールド値の長さは、mysql_fetch_lengths() の呼び出しで獲得できます。空フィールドと NULL を含むフィールドはどちらも長さ 0 を持ちます; フィールド値のポインタをチェックすることで、これらを区別できます。ポインタが NULL の場合、フィールドは NULL です; そうでなければフィールドは空です。

戻り値
...

次のレコードの MYSQL_ROW 構造体、エラーが発生したか、もう取り出すレコードがない場合は NULL。

エラー
...

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

例
.

     MYSQL_ROW row;
     unsigned int num_fields;
     unsigned int i;

     num_fields = mysql_num_fields(result);
     while ((row = mysql_fetch_row(result)))
     {
        unsigned long *lengths;
        lengths = mysql_fetch_lengths(result);
        for(i = 0; i < num_fields; i++)
        {
            printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
        }
        printf("\n");
     }

mysql_field_count()
-------------------

unsigned int mysql_field_count(MYSQL *mysql)

3.22.24 より前の MySQL バージョンを使用している場合、 unsigned int mysql_num_fields(MYSQL *mysql) を代わりに使用すべきです。

説明
..

接続上の最後のクエリのフィールド数を返します。

この関数は通常 mysql_store_result() が NULL を返した時（そしてこのように結果セットポインタを持っていない時）に使用されます。この場合、 mysql_store_result() が空でない結果を提供すべきかどうかを調べるために、mysql_field_count() を呼び出すことができます。これは、クエリが SELECT（または SELECTに似た）ステートメントであるかを知ること無しに、クライアントプログラムに、適切な行動をとらせることができます。下に示される例は、これをどのように行なうことができるかを説明しています。

See NULL mysql_store_result().

戻り値
...

結果セット中のフィールド番号を表す unsigned integer。

エラー
...

無し。

例
.

     MYSQL_RES *result;
     unsigned int num_fields;
     unsigned int num_rows;

     if (mysql_query(&mysql,query_string))
     {
         // error
     }
     else // query succeeded, process any data returned by it
     {
         result = mysql_store_result(&mysql);
         if (result)  // there are rows
         {
             num_fields = mysql_num_fields(result);
             // retrieve rows, then call mysql_free_result(result)
         }
         else  // mysql_store_result() returned nothing; should it have?
         {
             if(mysql_field_count(&mysql) == 0)
             {
                 // query does not return data
                 // (it was not a SELECT)
                 num_rows = mysql_affected_rows(&mysql);
             }
             else // mysql_store_result() should have returned data
             {
                 fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
             }
         }
     }

別の方法は、mysql_field_count(&mysql) 呼び出しを mysql_errno(&mysql) に置き換えることです。この場合、ステートメントが SELECT かどうかを mysql_field_count() の値から推測するのではなく、直接 mysql_store_result() からのエラーをチェックします。

mysql_field_seek()
------------------

MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

説明
..

与えられたオフセットにフィールドカーソルを設定します。次の mysql_fetch_field() の呼び出しはそのオフセットに対応したフィールドを取り出します。

レコードの最初にシークするには、0 の offset 値を渡してください。

戻り値
...

フィールドカーソルの前の値。

エラー
...

無し。

mysql_field_tell()
------------------

MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)

説明
..

最後の mysql_fetch_field() に使用したフィールドカーソルの位置を返します。この値は mysql_field_seek() への引数として使用できます。

戻り値
...

フィールドカーソルの現在のオフセット。

エラー
...

無し。

mysql_free_result()
-------------------

void mysql_free_result(MYSQL_RES *result)

説明
..

mysql_store_result(), mysql_use_result(), mysql_list_dbs() 等によって結果セットに割り当てられたメモリを解放します。結果セットで何かを行なった時、mysql_free_result() を呼び出してそれが使用したメモリを解放する必要があります。

戻り値
...

無し。

エラー
...

無し。

mysql_get_client_info()
-----------------------

char *mysql_get_client_info(void)

説明
..

クライアントライブラリバージョンを表わす文字列を返します。

戻り値
...

MySQL クライアントライブラリバージョンを表わす文字列。

エラー
...

無し。

mysql_get_host_info()
---------------------

char *mysql_get_host_info(MYSQL *mysql)

説明
..

使用中の接続タイプを表わす文字列を返します。サーバのホスト名を含みます。

戻り値
...

サーバホスト名と接続タイプを表わす文字列。

エラー
...

無し。

mysql_get_proto_info()
----------------------

unsigned int mysql_get_proto_info(MYSQL *mysql)

説明
..

現在の接続に使用されているプロトコルバージョンを返します。

Return values
.............

現在の接続に使用されているプロトコルバージョンを表わす符号無し整数値。

エラー
...

無し。

mysql_get_server_info()
-----------------------

char *mysql_get_server_info(MYSQL *mysql)

説明
..

サーバのバージョン番号を表わす文字列を返します。

戻り値
...

サーバのバージョン番号を表わす文字列。

エラー
...

無し。

mysql_info()
------------

char * mysql_info(MYSQL *mysql)

説明
..

最も最近に実行されたクエリについての情報を文字列で返します。が、以下に挙げる構文に限ります。他の構文ではmysql_info() は NULL を返します。文字列の形式はクエリの型によって様々です。次に説明します (数値は例です; 文字列はクエリに適した値を含みます):

INSERT INTO ... SELECT ...
     String format: Records: 100 Duplicates: 0 Warnings: 0

INSERT INTO ... VALUES (...),(...),(...)...
     String format: Records: 3  Duplicates: 0  Warnings: 0

LOAD DATA INFILE ...
     String format: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0

ALTER TABLE
     String format: Records: 3 Duplicates: 0 Warnings: 0

UPDATE
     String format: Rows matched: 40 Changed: 40 Warnings: 0

注意: 複数の値リストがステートメント中に記述された場合にだけ、 mysql_info() は、INSERT ... VALUES ステートメントに非 NULL値を返します。

戻り値
...

最も最近に実行されたクエリについての追加情報を表わす文字列。クエリに有効な情報がない場合は NULL ポインタ。

エラー
...

無し。

mysql_init()
------------

MYSQL * mysql_init(MYSQL *mysql)

説明
..

mysql_real_connect() に適した MYSQL オブジェクトの割り当てまたは初期化を行ないます。引数が NULL ポインタの場合、関数は新しいオブジェクトを割り当てて初期化し返します。そうでなければオブジェクトは初期化され、オブジェクトのアドレスが返されます。新しいオブジェクトが割り当てられた場合、mysql_close() はこのオブジェクトを解放します。

戻り値
...

初期化された MYSQL* ハンドル、または新しいオブジェクトを割り当てるのに十分なメモリがなかった場合は NULL ポインタ。

エラー
...

メモリ不足の場合は NULL が返されます。

mysql_insert_id()
-----------------

my_ulonglong mysql_insert_id(MYSQL *mysql)

説明
..

前のクエリによって AUTO_INCREMENT フィールドに生成された ID を返します。 AUTO_INCREMENT フィールドを含むテーブルに INSERT クエリを実行した後で、この関数を使用してください。

注意: 前のクエリが AUTO_INCREMENT 値を生成しなかった場合、 mysql_insert_id() は 0 を返します。後のために値を保存する必要がある場合、値を生成するクエリの直後に mysql_insert_id() を呼び出すことに気をつけてください。

また、SQL LAST_INSERT_ID() 常に最後に生成された AUTO_INCREMENT 値を含み、クエリ間でリセットされないことに注意して下さい。その関数の値はサーバ内で保守されるからです。

戻り値
...

前のクエリによって更新された AUTO_INCREMENT フィールドの値。接続上の前のクエリがない場合、クエリが AUTO_INCREMENT 値を更新しなかった場合には 0 が返ります。

エラー
...

無し。

mysql_kill()
------------

int mysql_kill(MYSQL *mysql, unsigned long pid)

説明
..

pid で指定されたスレッドを殺すようにサーバに頼みます。

戻り値
...

成功時0。失敗時非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_list_dbs()
----------------

MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)

説明
..

サーバ上の、wild 引数で指定された簡易正規表現に適合する、データベース名からなる結果セットを返します。wild はワイルドカード文字 % または _ を含むことができます。また、全てのデータベースに適合するように NULL ポインタにできます。mysql_list_dbs() の呼び出しはクエリ SHOW databases [LIKE wild] を実行するのと同様です。

mysql_free_result() で結果セットを解放する必要があります。

戻り値
...

成功時 MYSQL_RES 結果セット。失敗した場合は NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_OUT_OF_MEMORY
     メモリ不足。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_list_fields()
-------------------

MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)

説明
..

与えられたテーブル内の、wild 引数で指定された簡易正規表現に適合するフィールド名からなる結果セットを返します。wild はワイルドカード文字 % または _ を含むことができます。また、全てのフィールドに適合するように NULL ポインタにできます。 mysql_list_fields() はクエリ SHOW COLUMNS FROM table [LIKE wild] を実行するのと同様です。

注意: mysql_list_fields() の代わりに SHOW COLUMNS FROM tbl_name の使用を勧めます。

mysql_free_result() で結果セットを解放する必要があります。

戻り値
...

成功時 MYSQL_RES 結果セット。エラーが発生した場合は NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_list_processes()
----------------------

MYSQL_RES *mysql_list_processes(MYSQL *mysql)

説明
..

現在のサーバスレッドを示す結果セットを返します。これは mysqladmin processlist や SHOW PROCESSLIST クエリで報告されるものと同じ種類の情報です。

mysql_free_result() で結果セットを解放する必要があります。

戻り値
...

成功時 MYSQL_RES 結果セット。失敗した場合は NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_list_tables()
-------------------

MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)

説明
..

wild 引数で指定された簡易正規表現に適合する、現在のデータベース内のテーブル名からなる結果セットを返します。wild はワイルドカード文字 % または _ を含むことができます。また、全てのテーブルに適合するように NULL ポインタにできます。 mysql_list_tables() はクエリ SHOW tables [LIKE wild] を実行するのと同様です。

mysql_free_result() で結果セットを解放する必要があります。

戻り値
...

成功時 MYSQL_RES 結果セット。失敗した場合は NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_num_fields()
------------------

unsigned int mysql_num_fields(MYSQL_RES *result)

または

unsigned int mysql_num_fields(MYSQL *mysql)

二番目の形式は MySQL 3.23 以上では動作しません。MYSQL* 引数を通す場合は、代わりに unsigned int mysql_field_count(MYSQL*mysql) を使用しなくてはいけません。

説明
..

結果セット中のフィールド数を返します。

注意: 結果セットへのポインタまたは接続ハンドルのいずれかからフィールドの数を得ることができます。mysql_store_result() または mysql_use_result() が NULL を返した（つまり結果セットポインタが無い）場合、接続ハンドルを使用します。この場合、 mysql_field_count() を呼び出して、mysql_store_result() が空でない結果を提供すべきかどうかを決定できます。これにより、クライアントプログラムはクエリが SELECT（または SELECT に似た）ステートメントだったかどうかを知ることなしに、適切な行動を取ることができます。以下に示す例はこれをどのように行なうかを説明しています。

See NULL mysql_store_result().

戻り値
...

結果セット中のフィールド数を表わす符号無し整数。

エラー
...

無し。

例
.

     MYSQL_RES *result;
     unsigned int num_fields;
     unsigned int num_rows;

     if (mysql_query(&mysql,query_string))
     {
         // error
     }
     else // query succeeded, process any data returned by it
     {
         result = mysql_store_result(&mysql);
         if (result)  // there are rows
         {
             num_fields = mysql_num_fields(result);
             // retrieve rows, then call mysql_free_result(result)
         }
         else  // mysql_store_result() returned nothing; should it have?
         {
             if (mysql_errno(&mysql))
     	{
                fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
     	}
             else if (mysql_field_count(&mysql) == 0)
             {
                 // query does not return data
                 // (it was not a SELECT)
                 num_rows = mysql_affected_rows(&mysql);
             }
         }
     }

（結果セットが返るべきクエリであることを知っている場合の）方法は、 mysql_errno(&mysql) コールを mysql_field_count(&mysql) が 0 かどうかのチェックに置き換えることです。これは何かが悪い場合にだけ起こります。

mysql_num_rows()
----------------

my_ulonglong mysql_num_rows(MYSQL_RES *result)

説明
..

結果セット中のレコード数を返します。

mysql_num_rows() の使用は、結果セットを返すのに mysql_store_result() か mysql_use_result() のどちらを使用するかに依存します。mysql_store_result() を使用する場合、 mysql_num_rows() はすぐに呼ぶことができます。 mysql_use_result() を使用する場合、結果セットの全てのレコードが取り出されるまで、mysql_num_rows() は正しい値を返しません。

戻り値
...

結果セットのレコード数。

エラー
...

無し。

mysql_options()
---------------

int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)

説明
..

特別な接続オプションを設定し、接続の振舞いに影響を与えるために使用できます。この関数は複数のオプションを設定するために複数回呼ぶことができます。

mysql_options() は mysql_init() の後で、 mysql_connect() や mysql_real_connect() の前に呼ばれなければなりません。

option 引数は設定したいオプションです; arg 引数はオプションに対する値です。オプションが整数の場合、arg は整数値へのポインタです。

有効なオプション値:

オプション   引数型   機能
MYSQL_OPT_CONNECT_TIMEOUT   unsigned int *   接続タイムアウト（秒）。
MYSQL_OPT_COMPRESS   使用しない   圧縮クライアント／サーバプロトコルを使用する。
MYSQL_OPT_NAMED_PIPE   使用しない   NT 上の MySQL サーバへの接続に名前付パイプを使用する。
MYSQL_INIT_COMMAND   char *   MySQL サーバへの接続時に実行するコマンド。再接続時に自動的に再実行される。
MYSQL_READ_DEFAULT_FILE   char *   my.cnf の代わりに指定されたオプションファイルからオプションを読み込む。
MYSQL_READ_DEFAULT_GROUP   char *   my.cnf または MYSQL_READ_DEFAULT_FILE で指定されたファイルから指定されたグループのオプションを読み込む。

注意: MYSQL_READ_DEFAULT_FILE と MYSQL_READ_DEFAULT_GROUP を使用する場合、client グループが常に読まれます。

オプションファイル中に指定されるグループは次のオプションを含むことができます:

compress   圧縮クライアント／サーバプロトコルを使用する。
database   接続命令中でデータベースが指定されない場合、このデータベースに接続する。
debug   デバッグオプション
host   デフォルトホスト名
init-command   MySQL サーバへの接続時に実行するコマンド。再接続時に自動的に再実行される。
password   デフォルトパスワード
pipe   NT 上の MySQL サーバへの接続に名前付パイプを使用する。
port   デフォルトポート番号
return-found-rows   UPDATE 使用時、mysql_info() が更新された行の代わりに見つかった行を返すようにする。
socket   デフォルトソケット番号
timeout   接続タイムアウト（秒）。
user   デフォルトユーザ

オプションファイルについてのさらなる情報は、Option files を参照して下さい。

戻り値
...

成功の場合は0。未知のオプションを使用した場合は非0。

例
.

     MYSQL mysql;

     mysql_init(&mysql);
     mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
     mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
     if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
     {
         fprintf(stderr, "Failed to connect to database: Error: %s\n",
               mysql_error(&mysql));
     }

上記は、圧縮クライアント／サーバプロトコルを使用し、my.cnf ファイル中の odbc セクションから追加オプションを読むように、クライアントに要求します。

mysql_ping()
------------

int mysql_ping(MYSQL *mysql)

説明
..

サーバへの接続が動作しているかどうかをチェックします。ダウンしている場合は、自動的に再接続を試みます。

この関数は、長い間静かにしているクライアントが、サーバが接続をクローズしたかどうかをチェック（と再接続）するために使用できます。

戻り値
...

サーバが生きている場合0。他の値はエラーを示します。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_query()
-------------

int mysql_query(MYSQL *mysql, const char *query)

説明
..

NULL 終端文字列 query で示される SQL クエリを実行します。クエリはひとつの SQL ステートメントでなければなりません。終端のセミコロン (;)や \g をステートメントに追加すべきではありません。

mysql_query() はバイナリデータを含むクエリには使用できません（バイナリデータは \0 文字を含むことがあります。これはクエリ文字列の最後として解釈されます）。この場合、mysql_real_query() を代わりに使用してください。

If you want to know if the query should return a result set or not, you can use mysql_field_count() to check for this. See mysql_field_count.

戻り値
...

クエリが成功した場合は0。クエリが失敗した場合は非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_real_connect()
--------------------

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned int client_flag)

説明
..

host 上で動作している MySQL データベースエンジンへの接続の確立を試みます。 mysql_get_client_info() 以外の他の API 関数を実行する前に、 mysql_real_connect() が成功している必要があります。

mysql_real_connect() を呼び出す前に、MYSQL 構造体を獲得または初期化するために mysql_init() を呼ぶ必要があることに注意してください。

  * 最初のパラメータは既存の MYSQL 構造体のアドレスです。 mysql_real_connect() を呼ぶ前に、MYSQL 構造体の初期化のために mysql_init() を呼ぶ必要があります。後述の例を参照してください。

  * host の値はホスト名か IP アドレスのどちらでも可能です。 host が NULL または文字列 "localhost" の場合はローカルホストへの接続とみなされます。OS がソケットをサポートする場合(Unix) または名前つきパイプをサポートする場合(Win32)、サーバへの TCP/IP 接続の代わりに使用されます。

  * user パラメータはユーザの MySQL ログイン ID が入っています。 user が NULL の場合、現在のユーザとみなされます。Windows ODBC 下では、現在のユーザは明示的に指定されなければなりません。Unix 下では現在のログイン名が適用されます。 Windows ODBC では, カレントのユーザー名を与えなければなりません。 See ODBC administrator.

  * passwd パラメータは user のパスワードが入っています。もし passwd が NULL の場合、空白のパスワードフィールドを持つ user テーブル内のレコードだけが適合チェックされます。このような方法で、パスワードが記述されたかどうかによってユーザが異なる権限を得るように、データベース管理者が MySQL 特権システムを設定することができます。

     注意: mysql_connect() を呼び出す前に passwd を暗号化しないでください。パスワードの暗号化はクライアント API で自動的に処理されます。

  * db が NULL でない場合、接続はこの値をデフォルトデータベースにセットします。

  * port が 0 でない場合、値は TCP/IP 接続のポート番号として使用されます。host パラメータが接続のタイプを決定することに注意してください。

  * unix_socket が NULL でない場合、文字列は使用されるソケットまたは名前つきパイプを記述します。host パラメータが接続のタイプを決定することに注意してください。

  * client_flag の値は通常 0 ですが、とても特殊な状況のため次のフラグの組み合わせを設定できます:

     フラグ名          フラグの意味
     CLIENT_FOUND_ROWS   影響された行数ではなく見つかった行数を返します
     CLIENT_NO_SCHEMA    db_name.tbl_name.col_name を許しません。これは ODBC のためです; その構文を使用した場合、パーサがエラーを生成します。これはいくつかの ODBC プログラムのバグのトラップに役立ちます。
     CLIENT_COMPRESS     圧縮プロトコルを使用します
     CLIENT_ODBC         クライアントが ODBC クライアント。これは mysqld をさらに ODBC-フレンドリに変更します。

mysql_real_connect() の最初の引数に NULL ポインタを記述することもできます。これは C API が接続構造体のメモリを割り当て、 mysql_close() 呼び出し時に自動的に解放されます。この方法の不利な点は、接続が失敗した場合に mysql_real_connect() からのエラーメッセージを取り出すことができないことです。

最初の引数が NULL ポインタでない場合は、存在する MYSQL 構造体のアドレスであるべきです。

戻り値
...

接続が成功した場合は MYSQL* 接続ハンドルです。接続が失敗した場合は C NULL ポインタです。接続に成功すると、最初のパラメータが NULL でない場合、戻り値はそのパラメータの値と同じです。

エラー
...

CR_CONN_HOST_ERROR
     MySQL サーバへの接続に失敗した。

CR_CONNECTION_ERROR
     ローカル MySQL サーバへの接続に失敗した。

CR_IPSOCK_ERROR
     IP ソケットの生成に失敗した。

CR_OUT_OF_MEMORY
     メモリ不足。

CR_SOCKET_CREATE_ERROR
     Unix ソケットの生成に失敗した。

CR_UNKNOWN_HOST
     ホスト名の IP  アドレスを見つけるのに失敗した。

CR_VERSION_ERROR
     異なるプロトコルバージョンを使用するクライアントライブラリでサーバへの接続を試みた結果のプロトコルミスマッチ。これは、とても古いクライアントライブラリを使用して、--old-protocol オプション付きで開始していない新しいサーバに接続する場合に発生します。

CR_NAMEDPIPEOPEN_ERROR;
     Win32 上の名前つきパイプの生成に失敗した。

CR_NAMEDPIPEWAIT_ERROR;
     Win32 上の名前つきパイプの wait に失敗した。

CR_NAMEDPIPESETSTATE_ERROR;
     Win32 上のパイプハンドラの獲得に失敗した。

例
.

     MYSQL mysql;

     mysql_init(&mysql);
     mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
     if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
     {
         fprintf(stderr, "Failed to connect to database: Error: %s\n",
               mysql_error(&mysql));
     }

By using mysql_options() the MySQL library will read the [client] and your_prog_name sections in the my.cnf file which will ensure that your program will work, even if someone has set up MySQL in some non-standard way.

Note that upon connection, mysql_real_connect() sets the reconnect flag (part of the MYSQL structure) to a value of 1. This flag indicates, in the event that a query cannot be performed because of a lost connection, to try reconnecting to the server before giving up.

mysql_real_escape_string()
--------------------------

unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)

説明
..

from の文字列を、SQL ステートメントとしてサーバに送ることができるように、現在のキャラクタ・セットを考慮しながら変換します。結果は to に入り、終端 null 文字を追加します。変換される文字列は NUL (ASCII 0), \n, \r, \, ', ", Control-Z です。(see Literals).

from で示される文字列はlength バイト長でなければなりません。 to バッファには少なくとも length*2+1 バイト長を割り当てる必要があります。（最悪の場合、それぞれの文字が２バイトに変換されることがあり、さらに終端 null バイトのための場所が必要です。） mysql_escape_string() が復帰するとき、to の内容は NUL 終端文字列になります。戻り値は変換された文字列の長さです。終端 null 文字は含みません。

例
.

     char query[1000],*end;

     end = strmov(query,"INSERT INTO test_table values(");
     *end++ = '\'';
     end += mysql_real_escape_string(&mysql, end,"What's this",11);
     *end++ = '\'';
     *end++ = ',';
     *end++ = '\'';
     end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16);
     *end++ = '\'';
     *end++ = ')';

     if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
     {
        fprintf(stderr, "Failed to insert row, Error: %s\n",
                mysql_error(&mysql));
     }

上記の strmov() 関数は mysqlclient ライブラリに含まれていて、strcpy() のように働きますが、最初の引数の終りの null へのポインタを返します。

戻り値
...

to へ置かれた値の長さ。終端 null 文字は含みません。

エラー
...

無し。

mysql_real_query()
------------------

int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)

説明
..

query で示される SQL クエリを実行します。これは length バイト長です。クエリはひとつの SQL ステートメントでなければなりません。終端のセミコロン(;)や \g をステートメントに追加すべきではありません。

バイナリデータを含むクエリは mysql_real_query() を使用しなければなりません。バイナリデータは \0 文字を含むことがあるからです。また、mysql_real_query() は mysql_query() よりも速いです。クエリの strlen() を呼ばないからです。

If you want to know if the query should return a result set or not, you can use mysql_field_count() to check for this. See mysql_field_count.

戻り値
...

クエリが成功した場合は0。クエリが失敗した場合は非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_reload()
--------------

int mysql_reload(MYSQL *mysql)

説明
..

MySQL サーバに、アクセス権テーブルを再読み込みするように依頼します。接続されたユーザは reload 権限を持つ必要があります。

この関数は推奨されません。代わりに、SQL FLUSH PRIVILEGES ステートメントを発行する mysql_query() の使用が推奨されます。

戻り値
...

成功時0。失敗時非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_row_seek()
----------------

MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)

説明
..

レコードカーソルをクエリ結果セット中の絶対レコードに設定します。これは、結果セット構造体がクエリのすべての結果を持っていることを要求します。そのため、 mysql_row_seek() は mysql_store_result() と共にだけ使用でき、 mysql_use_result() と共には使用できません。

オフセットは mysql_row_tell() または mysql_row_seek() 呼びだしからの戻り値であるべきです。この値は単純なレコード番号ではありません;レコード番号を使用して結果セット内のレコードにシークしたい場合は、 mysql_data_seek() を代わりに使用してください。

戻り値
...

レコードカーソルの前の値。この値はその後の mysql_row_seek() 呼びだしに渡すことができます。

エラー
...

無し。

mysql_row_tell()
----------------

MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)

説明
..

最後の mysql_fetch_row() についてレコードカーソルの現在の位置を返します。この値は mysql_row_seek() への引数として使用できます。

mysql_row_tell() は mysql_store_result() の後にだけ使用すべきで、mysql_use_result() の後には使用すべきではありません。

戻り値
...

行カーソルの現在のオフセット。

エラー
...

無し。

mysql_select_db()
-----------------

int mysql_select_db(MYSQL *mysql, const char *db)

説明
..

mysql で示される現在の接続に、デフォルト(現在の)データベースとして db で示されるデータベースを使用するように指示します。以降のクエリでは、明示的にデータベースを指定しないテーブル参照について、このデータベースがデフォルトになります。

接続されたユーザがデータベースを使用する権限を持っていると証明されなければ、mysql_select_db() は失敗します。

戻り値
...

成功時0。失敗時非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_shutdown()
----------------

int mysql_shutdown(MYSQL *mysql)

説明
..

データベースサーバにシャットダウンするように要求します。接続されたユーザは shutdown 権限を持っている必要があります。

戻り値
...

成功時0。失敗時非0。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_stat()
------------

char *mysql_stat(MYSQL *mysql)

説明
..

mysqladmin status で提供されるのと同様の情報を文字列として返します。これは秒での uptime と、実行中のスレッド数、問い合わせ数、再読み込み数、オープンテーブル数を含みます。

戻り値
...

サーバ状態を表わす文字列。エラーが発生した場合 NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_store_result()
--------------------

MYSQL_RES *mysql_store_result(MYSQL *mysql)

説明
..

データを取り出すクエリ(SELECT, SHOW, DESCRIBE, EXPLAIN)が成功する毎に、mysql_store_result() または mysql_use_result() を呼び出す必要があります。

If you want to know if the query should return a result set or not, you can use mysql_field_count() to check for this. See mysql_field_count.

mysql_store_result() はクエリのすべての結果をクライアントへ読み込み、 MYSQL_RES 構造体を割り当て、この構造体に結果を配置します。

mysql_store_results() returns a null pointer if the query didn't return a result sets (If the query was for example an INSERT statement).

mysql_store_results() returns also null pointer if reading of the result set failed. You can check if you got an error by checking if mysql_error() doesn't return a null pointer, if mysql_errno() returns <> 0 or if mysql_field_count() returns <> 0.

返されるレコードが無い場合、空の結果セットが返されます。 (空の結果セットは NULL 戻り値とは異なります。)

一度 mysql_store_result() を呼び出して null ポインターでない結果を得る事ができたら、結果セット中にいくつのレコードがあるかを見つけるために、mysql_num_rows() を呼び出すことができます。

結果セットからレコードを取り出すために mysql_fetch_row() を呼び出すことができます。また、結果セット内の現在のレコード位置を設定／取得するために mysql_row_seek() と mysql_row_tell() を呼び出すことができます。

一度結果セットで行なうと、mysql_free_result() を呼び出す必要があります。

See NULL mysql_store_result().

戻り値
...

結果の MYSQL_RES 結果構造体。エラーがある場合 NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_OUT_OF_MEMORY
     メモリ不足。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_thread_id()
-----------------

unsigned long mysql_thread_id(MYSQL *mysql)

説明
..

現在の接続のスレッド ID を返します。この値は、スレッドを殺すための mysql_kill() への引数として使用できます。

接続が失われて、mysql_ping() で再接続した場合、スレッド ID は変更されます。これはスレッド ID を後で使うために取得して格納すべきではないことを意味します。必要な時にそれを取得すべきです。

戻り値
...

現在の接続のスレッド ID。

エラー
...

無し。

mysql_use_result()
------------------

MYSQL_RES *mysql_use_result(MYSQL *mysql)

説明
..

データを取り出すクエリ(SELECT, SHOW, DESCRIBE, EXPLAIN)が成功する毎に、 mysql_store_result() または mysql_use_result() を呼び出す必要があります。

mysql_use_result() は結果セット検索を開始しますが, mysql_store_result() のように、実際にクライアントに結果セットを読み取りません. 代わりに、各レコードは mysql_fetch_row() 呼びだしが行なわれることにより、個々に取り出されます。 mysql_use_result() はクエリの結果を、一時テーブルやローカルバッファに格納すること無く、サーバから直接読み込みます。これは mysql_store_result() よりもいくらか速く、少ないメモリを使用します。この場合、クライアントは現在の行と接続バッファ ( max_allowed_packet bytes まで増加する ) のメモリだけを割り当てます。

一方、クライアント側で各行について多くの処理を行なう場合や、ユーザが ^S (スクロール停止) を入力できるような画面に出力を送る場合は、mysql_use_result() を使用すべきではありません。これはサーバと連携しており、他のスレッドがデータが取り出されるテーブルを更新する事を邪魔します。

mysql_use_result() 使用時、NULL 値を取り出すまで mysql_fetch_row() を実行する必要があります。そうしないと、次のクエリは前のクエリから結果を取り出します。これを忘れると、C API はエラー Commands out of sync; You can't run this command now を与えます！

mysql_use_result() から返される結果では、 mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows(), mysql_affected_rows() を使用できません。また、mysql_use_result() が終了するまで他のクエリの発行もできません。(全ての行をフェッチした後に、フェッチされた行数を知るために mysql_num_rows を呼び出すことができます。)

一度結果セットで行なうと、mysql_free_result() を呼び出す必要があります。

戻り値
...

結果の MYSQL_RES 結果構造体。エラーがある場合 NULL。

エラー
...

CR_COMMANDS_OUT_OF_SYNC
     不当な順にコマンドが実行された。

CR_OUT_OF_MEMORY
     メモリ不足。

CR_SERVER_GONE_ERROR
     MySQL サーバがいなくなった。

CR_SERVER_LOST
     サーバへの接続がクエリ中に失われた。

CR_UNKNOWN_ERROR
     未知のエラーが発生した。

mysql_query() が成功を返した後、mysql_store_result() が NULL を返す時があるのは何故？
---------------------------------------------------------------

mysql_query() の呼び出しが成功した後に mysql_store_result() が NULL を返すことがあります。これが起こったとき、次の条件のどれかの発生を意味します:

  * malloc() が失敗した (例えば、結果セットが大き過ぎた場合)。

  * データが読めなかった (接続のエラー)。

  * クエリがデータを返さなかった (INSERT, UPDATE, DELETE)。

ステートメントが空でない結果を提供するかどうかは mysql_field_count() の呼び出しによっていつでもチェックできます。 mysql_field_count() が 0 を返す場合、結果は空で最後のクエリは値を返さないステートメントです (例えば、INSERT や DELETE)。 mysql_field_count() が非 0 値を返す場合、ステートメントは空でない結果を提供します。例はmysql_field_count() 関数の説明を参照してください。

mysql_error() または mysql_errno() を呼び出すことによってエラーのテストもできます。

クエリから得られる結果は何か？
---------------

クエリによって返される結果セットに加えて、次の情報も得ることができます:

  * mysql_affected_rows() は、INSERT, UPDATE または DELETE を行なった時の最後のクエリで、影響された行数を返します。 WHERE 節がない DELETE が使用されて、テーブルが切り詰められた場合は例外です。これはとても速いです！ この場合、 mysql_affected_rows() は影響された行数を 0 と返します。

  * mysql_num_rows() は結果セットのレコード数を返します。 mysql_store_result() では、mysql_num_rows() は mysql_store_result() が復帰したすぐ後に呼び出すことができます。 mysql_use_result() では、mysql_num_rows() は mysql_fetch_row() ですべてのレコードを取り出した後にだけ呼ぶ出すことができます。

  * mysql_insert_id() は、AUTO_INCREMENT インデックスを持つテーブルに行を挿入した最後のクエリによって生成された ID を返します。 See mysql_insert_id().

  * いくつかのクエリ (LOAD DATA INFILE..., INSERT INTO ... SELECT ..., UPDATE) は追加情報を返します。結果は mysql_info() で返されます。返す文字列の形式については、mysql_info() の説明を参照してください。 mysql_info() は追加情報がない場合は NULL ポインタを返します。

最後に挿入された行のユニーク ID をどのように得られるか？
------------------------------

AUTO_INCREMENT 属性を持つ項目を含むテーブルにレコードを挿入する場合、mysql_insert_id() 関数で与えられた ID を得ることができます。

mysql_query() に渡すクエリ文字列内のLAST_INSERT_ID() 関数を使用することでも、ID を取り出すことができます。

次のコードを実行することで、AUTO_INCREMENT インデックスが使用されたかどうかチェックできます。これは、クエリが AUTO_INCREMENT インデックスを伴う INSERT だったかどうかもチェックできます:

     if (mysql_error(&mysql)[0] == 0 &&
         mysql_num_fields(result) == 0 &&
         mysql_insert_id(&mysql) != 0)
     {
         used_id = mysql_insert_id(&mysql);
     }

生成された最後の ID は接続毎にサーバ内で維持されています。他のクライアントによって変更はされません。他の AUTO_INCREMENT 項目を非マジック値 (すなわち、NULL でなく 0 でない値) で更新する場合でも、それは変更されません。

また、他のテーブルにその ID を挿入しようとする場合、次で行なうことができます:

     INSERT INTO foo (auto,text)
         VALUES(NULL,'text');              # generate ID by inserting NULL
     INSERT INTO foo2 (id,text)
         VALUES(LAST_INSERT_ID(),'text');  # use ID in second table

C API でのリンクの問題
--------------

C API でリンクする時、いくつかのシステム上では次のエラーになります:

     gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

     Undefined        first referenced
      symbol          in file
     floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
     ld: fatal: Symbol referencing errors. No output written to client

これは、あなたのシステム上では、コンパイル/リンク行の最後に、math ライブラリ (-lm) を含める必要があることを意味します。

スレッド安全クライアントを作る方法
-----------------

クライアントは `ほとんど' スレッド安全です。一番大きな問題は net.c (ソケットから読み込みをするサブルーチンを含むファイル) が割り込み安全でないことです。これは、サーバからの長い読み込みを中断できるように、自身のアラームを持ちたいだろうという考慮で行なわれました。 If you install an interrupt handlers for the SIGPIPE interrupt, the socket handling should be thread safe.

標準クライアントライブラリはスレッドオプションでコンパイルされていません。

スレッド安全クライアント(MySQLサーバーとの通信時に、他のスレッドがクライアントのスレッドに interrupt をかけたり、タイムアウトをセットしたりする) を得るためには、-lmysys, -lstring, -ldbug ライブラリとサーバが使用する net_serv.o を使用します。

If you don't need interrupts or timeouts you can just compile the client library (mysqlclient) to be thread safe and use this.  In this case you don't have to worry about the net_serv.o object file or the other MySQL libraries.

スレッドクライアントを使用する時、thr_alarm.c ルーチンを大いに使用できます。mysys ライブラリからのルーチンを使用する場合、覚えておかなければならないことは my_init() を最初に呼ぶことだけです！

mysql_real_connect() を除く全ての関数は現在スレッド安全です。スレッド安全クライアントライブラリをコンパイルし、それをスレッド安全なマナーで使用するための方法を、次の注意で説明します。(この mysql_real_connect() についての注意は、実際には mysql_connect() にも有効です。しかし mysql_connect() は推奨されませんので、とにかく mysql_real_connect() を使用すべきです。)

mysql_real_connect() をスレッド安全にするためには、クライアントを次のコマンドで再コンパイルする必要があります:

     shell> ./configure --enable-thread-safe-client

This will ensure that the client library will use the header files required for thread safe programs and also that mysql_real_connect() will use a thread safe version of the gethostbyname() call.

標準クライアントのリンク時に未定義シンボルのためいくつかのエラーが出るでしょう。これはデフォルトでは pthread ライブラリが含まれていないためです。

結果の libmysqlclient.a ライブラリはスレッド安全です。これの意味することは、同じ接続ハンドル(mysql_real_connect() で返される)に、同時に２つのスレッドからクエリを行なわない限り、クライアントコードはスレッド安全ということです; クライアント／サーバプロトコルは、与えられた接続上で同時に一つの要求だけを許します。複数のスレッドから同じ接続を使用したい場合は、 mysql_query() と mysql_store_result() の組み合わせのまわりで mutex lock を行なう必要があります。一度 mysql_store_result() の用意ができると、ロックは解放でき、他のスレッドが同じ接続にクエリを行なうことができます。(他の言葉で言うと、正しいロックプロトコルを使用する限り、別のスレッドは、mysql_store_result() で生成される別の MYSQL_RES ポインタを使用できます。) POSIX スレッドでプログラムを行なう場合、 pthread_mutex_lock() と pthread_mutex_unlock() を、mutex lock の確立と解放に使用できます。

mysql_store_result() でなく mysql_use_result() を使用する場合、mysql_use_result() の回りと mysql_fetch_row() 呼び出しにロックが必要です。しかし、スレッド化クライアントに本当に一番良いのは、 mysql_use_result() を使用しないことです。

MySQL Perl API
==============

ここでは Perl DBI インターフェースについて述べる。以前のインターフェースは mysqlperl であった。 DBI/DBD が Perl インターフェースとして現在推奨されているので、 mysqlperl に関してはここでは述べない。

DBI with DBD::mysql
-------------------

DBI は多くのデーターベースとの一般的なインターフェースである。これは、多くのデーターベースと動作するスクリプトを変更なしに書けることを意味する。そのためには、それぞれのデータベース用のデータベースドライバ (DBD) が必要である。 MySQL では、そのドライバは DBD::mysql である。

Perl5 DBI に関する詳細は、DBIウェッブページを参照のこと：

     http://www.symbolstone.org/technology/perl/DBI/index.html

Object Oriented Programming (OOP) に関する詳細は、Perl OOP ページを参照のこと：

     http://language.perl.com/info/documentation.html

Installation instructions for MySQL Perl support are given in Perl support.

The DBI interface
.................

Portable DBI methods

connect   データベースサーバと接続する
disconnect   データベースサーバとの接続を切る
prepare   SQL文を設定する
execute   設定されたSQL文を実行する
do        SQL文を設定し、実行する
quote     挿入するためのクォート文字、または BLOB 値
fetchrow_array   フィールドの配列として次のレコードを取り出す
fetchrow_arrayref   フィールドの配列参照として次のレコードを取り出す
fetchrow_hashref   ハッシュテーブルへの参照として次のレコードを取り出す
fetchall_arrayref   配列の配列として全データを取り出す
finish    命令を終了し、リソースからシステムを切り離す
rows      影響のあったレコードの数を返す
data_sources   ローカルホスト上で利用できるデータベースの配列を返す
ChopBlanks   fetchrow_* メソッドが空白を取り除くかどうかを管理する
NUM_OF_PARAMS   設定された命令文中の placeholder の数
NULLABLE   どのフィールドに NULL 値があるか？
trace      Perform tracing for debugging

MySQL 固有メソッド

insertid   最後の AUTO_INCREMENT 値
is_blob   どのフィールドが BLOB か？
is_key   どのフィールドがキーか？
is_num   どのフィールドが数値型か？
is_pri_key   どのフィールドがプライマリキーか？
is_not_null   どのフィールドが NULL 値か？　NULLABLE 参照。
length   利用可能なフィールドサイズの最大値
max_length   実際に存在しているフィールドサイズの最大値
NAME   フィールド名
NUM_OF_FIELDS   返されたフィールドの数
table   返されたセットのテーブル名
type   全てのフィールドの型
_CreateDB   データベースを作成する
_DropDB   データベースを削除する。 ＊＊＊このメソッドは危険である＊＊＊

以下の節に、より詳細な Perl メソッドの解説がある。 Variables used for method return values have these meanings:

$dbh
     Database handle

$sth
     Statement handle

$rc
     Return code (often a status)

$rv
     Return value (often a row count)

汎用 DBI メソッド

     Generally the 'do' statement is MUCH faster (and is preferable) than prepare/execute for statements that doesn't contain parameters.

connect($data_source, $username, $password)
     データソースとのデータベース接続をするために connect を使う。 $data_source 値は DBI:driver_name: ではじめること。 DBD::mysql ドライバーを用いた connect の使用例：

          $dbh = DBI->connect("DBI:mysql:$database", $user, $password);
          $dbh = DBI->connect("DBI:mysql:$database:$hostname",
                              $user, $password);
          $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port",
                              $user, $password);

     ユーザー名またはパスワードが未設定の場合、 DBI は環境変数である DBI_USER と DBI_PASS をそれぞれ使う。ホスト名を指定しない場合は、'localhost' がデフォルトとなる。ポート番号を指定しない場合は、MySQL ポート（default_port）がデフォルトとなる。

     As of Msql-Mysql-modules version 1.2009, the $data_source value allows certain modifiers:

     mysql_read_default_file=file_name
          Read filename as an option file.  For information on option files, see Option files.

     mysql_read_default_group=group_name
          The default group when reading an option file is normally the [client] group.  By specifying the mysql_read_default_group option, the default group becomes the [group_name] group.

     mysql_compression=1
          Use compressed communication between the client and server (MySQL 3.22.3 or later).

     mysql_socket=/path/to/socket
          Specify the pathname of the Unix socket that is used to connect to the server (MySQL 3.21.15 or later).

     Multiple modifiers may be given; each must be preceded by a semicolon.

     For example, if you want to avoid hardcoding the user name and password into a DBI script, you can take them from the user's ~/.my.cnf option file instead by writing your connect call like this:

          $dbh = DBI->connect("DBI:mysql:$database"
                          . ";mysql_read_default_file=$ENV{HOME}/.my.cnf",
                          $user, $password);

     This call will read options defined for the [client] group in the option file.  If you wanted to do the same thing, but use options specified for the [perl] group as well, you could use this:

          $dbh = DBI->connect("DBI:mysql:$database"
                          . ";mysql_read_default_file=$ENV{HOME}/.my.cnf"
                          . ";mysql_read_default_group=perl",
                          $user, $password);

disconnect
     disconnect メソッドは、データベースとのデータベースハンドルを切断する。プログラムを終了する直前に呼び出されるのが典型的である。例：

          $rc = $dbh->disconnect;

prepare($statement)
     データベースエンジンで実行するためのSQL文を設定し、execute メソッドで使用出来るステートメントハンドル ($sth) を返す。 Typically you handle SELECT statements (and SELECT-like statements such as SHOW, DESCRIBE and EXPLAIN) by means of prepare and execute. 例：

          $sth = $dbh->prepare($statement)
              or die "Can't prepare $statement: $dbh->errstr\n";

execute
     execute メソッドは、設定されたSQL文を実行する。非 SELECT 文のときは、影響のあったレコードの数を返す。 もしなんの変化もなかったなら、 execute は "0E0" (これは Perl では ゼロ 扱いですが、 真 でもある) を返す。 SELECT 文のときは、SQL要求を開始するのみである。データを操作する fetch_* メソッドの内の一つを記述する必要がある。例：

          $rv = $sth->execute
                    or die "can't execute the query: $sth->errstr;

do($statement)
     do メソッドはSQL文を設定・実行し、影響のあったレコードの数を返す。このメソッドは、「非 select」文、すなわち、高度（ドライバーの限界のため）で設定できない文、一度の実行（inserts, deletes など）で済む文のときに一般的に用いられる。例：

          $rv = $dbh->do($statement)
                  or die "Can't execute $statement: $dbh- >errstr\n";

quote($string)
     quote メソッドは、文字列中にエスケープ文字があるときに用いられ、クォート文字を文の外側に付加する。例：

          $sql = $dbh->quote($string)

fetchrow_array
     このメソッドはデータの次のレコードを取り出し、フィールドの値の配列として返す。例：

          while(@row = $sth->fetchrow_array) {
                  print qw($row[0]\t$row[1]\t$row[2]\n);
          }

fetchrow_arrayref
     このメソッドはデータの次のレコードを取り出し、フィールドの値の配列への参照として返す。例：

          while($row_ref = $sth->fetchrow_arrayref) {
                  print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n);
          }

fetchrow_hashref
     このメソッドはデータのレコードを取り出し、名前・値のペアのフィールドを含んだハッシュテーブルへの参照を返す。このメソッドは、上で示した配列参照（訳注：fetchrow_arrayref）よりもかなり効率的ではない。例：

          while($hash_ref = $sth->fetchrow_hashref) {
                  print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\
                          $hash_ref- > title}\n);
          }

fetchall_arrayref
     このメソッドは、SQL文より返されたデータ（レコード）の全てを得るために使う。このメソッドは、各レコードへの参照の配列の配列への参照を返す。入れ子のループを使ってデータを利用・表示する。例：

          my $table = $sth->fetchall_arrayref
                          or die "$sth->errstr\n";
          my($i, $j);
          for $i ( 0 .. $#{$table} ) {
                  for $j ( 0 .. $#{$table->[$i]} ) {
                          print "$table->[$i][$j]\t";
                  }
                  print "\n";
          }

finish
     そのステートメントハンドルからそれ以上データを取り出さないことを示す。ステートメントハンドルや、つかんでいたシステムリソースを解放するためにこのメソッドを呼び出す。例：

          $rc = $sth->finish;

rows
     最後の命令により、（データの更新、削除、などで）影響のあったレコードの数を返す。このメソッドは do あるいは 非 SELECT execute 文を実行した後に、たいてい使われる。例： Example:

          $rv = $sth->rows;

NULLABLE
     配列の各要素に対し、ブール値の配列への参照を返す。 TRUE であればそのフィールドに NULL 値が含まれていることを示す。例： Example:

          $null_possible = $sth->{NULLABLE};

NUM_OF_FIELDS
     この属性は、SELECT 文や SHOW FIELDS 文によって返されたフィールドの数を示している。命令文が結果を返したかどうかをチェックするのに、これを使うことが出来る：０値は、INSERT, DELETE または UPDATE のような非 SELECT 文を示している。例： Example:

          $nr_of_fields = $sth->{NUM_OF_FIELDS};

data_sources($driver_name)
     このメソッドは、'localhost' ホスト上の MySQL サーバで利用可能なデータベースの名前を含んだ配列を返す。例：

          @dbs = DBI->data_sources("mysql");

ChopBlanks
     この属性は、 fetchrow_* メソッドが返り値から前後の空白を除去するかどうかを決定する。例：

          $sth->{'ChopBlanks'} =1;

trace($trace_level)
trace($trace_level, $trace_filename)
     The trace method enables or disables tracing.  When invoked as a DBI class method, it affects tracing for all handles.  When invoked as a database or statement handle method, it affects tracing for the given handle (and any future children of the handle).  Setting $trace_level to 2 provides detailed trace information.  Setting $trace_level to 0 disables tracing.  Trace output goes to the standard error output by default.  If $trace_filename is specified, the file is opened in append mode and output for all traced handles is written to that file.  Example:

          DBI->trace(2);                # trace everything
          DBI->trace(2,"/tmp/dbi.out"); # trace everything to /tmp/dbi.out
          $dth->trace(2);               # trace this database handle
          $sth->trace(2);               # trace this statement handle

     You can also enable DBI tracing by setting the DBI_TRACE environment variable.  Setting it to a numeric value is equivalent to calling DBI->(value).  Setting it to a pathname is equivalent to calling DBI->(2,value).

MySQL 固有メソッド

The methods shown below are MySQL-specific and not part of the DBI standard.  Several of them are now deprecated: is_blob, is_key, is_num, is_pri_key, is_not_null, length, max_length, and table. Where DBI-standard alternatives exist, they are noted below.

insertid
     MySQL の特徴である AUTO_INCREMENT を使うとき、新しい自動繰り上がり値がここに記憶される。例： Example:

          $new_id = $sth->{insertid};

     As an alternative, you can use $dbh->{'mysql_insertid'}.

is_blob
     配列の各要素に対し、ブール値の配列への参照を返す。TRUE であればそのフィールドが BLOB 値であることを示す。例：

          $keys = $sth->{is_blob};

is_key
     配列の各要素に対し、ブール値の配列への参照を返す。TRUE であればそのフィールドがキーであることを示す。例：

          $keys = $sth->{is_key};

is_num
     配列の各要素に対し、ブール値の配列への参照を返す。TRUE であればそのフィールドが数値型であることを示す。例：

          $nums = $sth->{is_num};

is_pri_key
     配列の各要素に対し、ブール値の配列への参照を返す。TRUE であればそのフィールドがプライマリーキーであることを示す。例：

          $pri_keys = $sth->{is_pri_key};

is_not_null
     配列の各要素に対し、ブール値の配列への参照を返す。FALSE であればそのフィールドが NULL 値を含むことを示す。例：

          $not_nulls = $sth->{is_not_null};

     is_not_null is deprecated; 前述の NULLABLE 属性を使用するほうが望ましい。それが DBI の標準である。

length
max_length
     それぞれのメソッドは、フィールドサイズの配列への参照を返す。length 配列は、（テーブル記述で定義された）各フィールドの利用可能最大値を示す。 max_length 配列は、テーブル中に実際に存在している最大値を示す。例：

          $lengths = $sth->{length};
          $max_lengths = $sth->{max_length};

NAME
     フィールド名の配列への参照を返す。例：

          $names = $sth->{NAME};

table
     テーブル名の配列への参照を返す。例：

          $tables = $sth->{table};

type
     フィールドの型の配列への参照を返す。例：

          $types = $sth->{type};

DBI/DBD に関するそれ以上の情報
-------------------

DBI に関するそれ以上の情報は perldoc コマンドで得られる。

     perldoc DBI
     perldoc DBI::FAQ
     perldoc DBD::mysql

他のフォーマットに変換するツール、pod2man, pod2html なども使うことが出来る。

そしてもちろん、DBI の最新情報は DBI ウェッブページで見ることが出来る：

     http://www.symbolstone.org/technology/perl/DBI/index.html

MySQL Eiffel wrapper
====================

The MySQL Contrib directory (http://www.mysql.com/Contrib/) contains an Eiffel wrapper written by Michael Ravits

You can also find this at: http://www.netpedia.net/hosting/newplayer/

MySQL Java connectivity (JDBC)
==============================

There are 2 supported JDBC drivers for MySQL (the twz and mm driver). You can find a copy of these at http://www.mysql.com/Contrib. For documentation consult any JDBC documentation and the drivers own documentation for MySQL specific features.

MySQL PHP API
=============

PHP is a server-side, HTML embedded scripting language that may be used to create dynamic web pages.  It contains support for accessing several databases, including MySQL.  PHP may be run as a separate program, or compiled as a module for use with the Apache web server.

The distribution and documentation are available at the PHP website (http://www.php.net/).

Common problems with MySQL and PHP
----------------------------------

  bullet Error: "Maximum Execution Time Exeeded" This is a PHP limit;  Go into the php3.ini file and set the maximum execution time up from 30 seconds to something higher, as needed. It is also not a bad idea to double the ram allowed per script to 16 instead of 8 MB.

  bullet Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in .." This means that your PHP version isn't compiled with MySQL support. You can either compile a dynamic MySQL module and load it into PHP or recompile PHP with built-in MySQL support.  This is described in detail in the PHP manual.

MySQL C++ APIs
==============

Two API's is available in the MySQL Contrib directory (http://www.mysql.com/Contrib/).

MySQL Python APIs
=================

The MySQL Contrib directory (http://www.mysql.com/Contrib/) contains a Python interface written by Joseph Skinner.

You can also use the Python interface to iODBC to access a MySQL server. mxODBC (http://starship.skyport.net/~lemburg/)

MySQL Tcl APIs
==============

Tcl at binevolve (http://www.binevolve.com/~tdarugar/tcl-sql/). The Contrib directory (http://www.mysql.com/Contrib) contains a Tcl interface that is based on msqltcl 1.50.

MySQL Ruby API
==============

以下のサイトに、Ruby の MySQL インターフェースがあります。

www.tmtm.org とみたまさひろ氏の Web ページ (http://www.tmtm.org/)

How MySQL compares to other databases
*************************************

MySQL と mSQL との比較
=================

この節は、MySQL 開発者によって書かれていますので、そのつもりで読んで下さい。しかし我々が知っている事実上の間違いはありません。

For a list of all supported limits, functions and types, see the crash-me web page (http://www.mysql.com/crash-me-choose.htmy).

Performance

     真の速度比較のためは、増加する MySQL ベンチマークスイートを見て下さい see Benchmarks.

     Because there is no thread creation overhead, a small parser, few features and simple security, mSQL should be quicker at:

       * Tests that perform repeated connects and disconnects, running a very simple query during each connection.

       * INSERT operations into very simple tables with few columns and keys.

       * CREATE TABLE and DROP TABLE.

       * SELECT on something that isn't an index. (A table scan is very easy.)

     これらのオペレーションはとても単純なので、開始のオーバーヘッドが高くなる時にそれらを良くするのは難しいです。接続が確立された後は MySQL はとても良い性能になります。

     他のものでは MySQL は mSQL や多くの他の SQL 実装よりとても速いです:

       * Complex SELECT operations.

       * 大きな結果の取り出し (MySQL はより良く, より速くそしてより安全なプロトコルを持ちます)

       * 可変長文字列を持つテーブル。MySQL はさらに効率的な処理を持ち、 VARCHAR 上にインデックスを持つことができます。

       * 多くのフィールドを持つテーブルの処理。

       * 大きなレコード長のテーブルの処理。

       * SELECT with many expressions.

       * SELECT on large tables.

       * 同時に多くの接続を処理します。MySQL は完全なマルチスレッドです。各接続はそれ自身のスレッドを持ちます。これは、それらが他を待つ必要がないことを意味します(同じテーブルを変更するクエリが実行される場合を除く)。 mSQL では、全ての他の接続は、最初のもの - クエリが長いか短いかに関わらず - が実行され、終わるまで待つ必要があります。その後次の接続が与えられ、他の全ては再び待ちます。

       * Joins. mSQL can become pathologically slow if you change the order of tables in a SELECT. In the benchmark suite, a time more than 15000 times slower than MySQL was seen.  This is due to mSQL's lack of a join optimizer to order tables in the optimal order. However, if you put the tables in exactly the right order in mSQL2 and the WHERE is simple and uses index columns, the join will be relatively fast! See Benchmarks.

       * ORDER BY and GROUP BY.

       * DISTINCT.

       * TEXT または BLOB フィールドの使用。

SQL Features

       * GROUP BY and HAVING. mSQL does not support GROUP BY at all. MySQL は HAVING を伴う完全な GROUP BY や、次の関数 count(), avg(), min(), max(), sum() そして std() をサポートします。min() と max() は文字列の引数も取れます。count(*) は、クエリ内がこれだけの場合にとても速く返されるように最適化されます。mSQL は GROUP BY を全くサポートしません。

       * INSERT and UPDATE with calculations. MySQL can do calculations in an INSERT or UPDATE. For example:

               mysql> UPDATE SET x=x*10+y WHERE x<20;

       * Aliasing. MySQL はフィールドのエイリアス名を持ちます。

       * Qualifying column names. In MySQL, if a column name is unique among the tables used in a query, you do not have to use the full qualifier.

       * SELECT with functions. MySQL has many functions (too many to list here; see Functions).

領域能力
     これは、テーブルをどのように小さくできるかです。

     MySQL はとても精密な型を持ちます。とても小さい領域を使用するテーブルを作成できるためです。MySQL データ型の有用な例は、3バイト長の MEDIUMINT です。10,000,000 レコードを持つ場合、1レコードあたり1バイトの節約でもとても重要です。

     mSQL2 は4つの型(char,text,int,real)しかないので、小さなテーブルを得るのは難しいです。

安定性
     これを客観的に判断するのは難しいです。MySQL の安定性については Stability を参照してください。

     我々には mSQL 安定性の経験がありません。そのため、我々はこれについては何も言えません。

価格
     もう一つの重要な問題はもちろんライセンスです。MySQL は mSQL よりも柔軟なライセンスを持っています。そして mSQL よりもより安いです。少なくとも、あなたが使用を選択した製品全てに、ライセンスまたは email サポートへの支払いを考慮することを覚えていて下さい。 MySQL を含めた製品を売る場合、もちろんこのライセンスの獲得が要求されます。

Perl interfaces
     MySQL は基本的に mSQL と同じ perl インタフェースと、いくつかの追加機能を持ちます。

JDBC (Java)
     MySQL currently has 4 JDBC drivers:

       * The gwe driver: A Java interface by GWE technologies (not supported anymore).

       * The jms driver: An improved gwe driver by Xiaokun Kelvin ZHU X.Zhu@brad.ac.uk.

       * The twz driver: A type 4 JDBC driver by Terrence W. Zellers zellert@voicenet.com.  This is commercial but is free for private and educational use.

       * The mm driver: A type 4 JDBC driver by Mark Matthews mmatthew@ecn.purdue.edu.  This is released under the GPL.

     The recommended drivers are the twz or mm driver. Both are reported to work excellently.

     We know that mSQL has a JDBC driver, but we have too little experience with it to compare.

開発の速度
     MySQL はとても小さい開発チームを持っていますが、我々は C と C++ のコーディングをとても速く行ないます。スレッド、関数、 GROUP BY などはまだ mSQL には実装されていませんので、it has a lot of chatching up to do.  この上でいくつかの見通しを得るために、去年の mSQL HISTORY ファイルを見て、MySQL Reference Manual News 節と比較できます(see News)。速く開発された多くのものが、かなり明白になります。

ユーティリティプログラム
     mSQL と MySQL は多くの興味深いサードパーティツールを持っています。上位への移行 (mSQL -> MySQL) はとても簡単です。 MySQL は、ほとんど全ての興味深い mSQL アプリケーションを持っています。

     MySQL には、簡単な msql2mysql プログラムが用意されています。これは、mSQL と MySQL の C API 関数のスペルの違いを修正するプログラムです。 For example, it changes instances of msqlConnect() to mysql_connect(). mSQL から MySQL への変換は通常、数分使用するだけです。

How to convert mSQL tools for MySQL
-----------------------------------

According to our experience, it would just take a few hours to convert tools such as msql-tcl and msqljava that use the mSQL C API so that they work with the MySQL C API.

The conversion procedure is:

 1. シェルスクリプト msql2mysql をソースに実行します。バイナリプログラム replace が必要です。これは MySQL で配布されます。

 2. Compile.

 3. 全てのコンパイラエラーを修復します.

MySQL と mSQL 間の C API の違い:

  * MySQL は MYSQL 構造体を接続型として使用します (mSQL は int を使用します)。

  * mysql_connect() は MYSQL 構造体へのポインタをパラメータとして使用します。それをグローバルに定義したり、その獲得に malloc() を使用するのは簡単です。 mysql_connect() also takes two parameters for specifying the user and password.  You may set these to NULL, NULL for default use.

  * mysql_error() は MYSQL 構造体をパラメータとして使用します。古いコードを移行する場合、あなたの古い  msql_error() コードへパラメータを追加してください。

  * MySQL returns an error number and a text error message for all errors. mSQL returns only a text error message.

  * Some incompatibilities exist as a result of MySQL supporting multiple connections to the server from the same process.

How mSQL and MySQL client/server communications protocols differ
----------------------------------------------------------------

There are enough differences that it is impossible (or at least not easy) to support both.

The most significant ways in which the MySQL protocol differs from the mSQL protocol are listed below:

  * メッセージバッファは多くの結果行を含めます。

  * 質問または回答が現在のバッファよりも大きい場合、サーバとクライアントのコンフィグ可能制限まで、メッセージバッファは動的に増大されます。

  * 全てのパケットは、パケットの重複や見失いを見つけ出すために、番号づけされています。

  * 全ての項目は ASCII で送られ、項目の行と長さはパックされたバイナリコーディング(1,2 または 3 バイト)で送られます。

  * MySQL はバッファされない結果で読み込み可能です(クライアント内に完全なセットを格納する必要がありません)。

  * 一つの書き込み/読み込みが 30 秒以上かかると、サーバは接続をクローズします。

  * 接続で 8 時間何も起きないと、サーバは接続をクローズします。

MySQL & mSQL 2.0 間の SQL 構文の違いは？
-------------------------------

Column types

MySQL
     他に加え次の項目オプション型を持ちます (among others; see CREATE TABLE):

       * ENUM type for one of a set of strings.

       * SET type for many of a set of strings.

       * BIGINT type for 64-bit integers.

     MySQL also supports the following additional type attributes:

       * 整数項目への UNSIGNED オプション

       * 整数項目への ZEROFILL オプション

       * PRIMARY KEY も含み全ての整数項目への AUTO_INCREMENT オプション see mysql_insert_id().

       * 全ての項目への DEFAULT 値

mSQL2
     mSQL column types correspond to the MySQL types shown below:

     mSQL type   Corresponding MySQL type
     CHAR(len)   CHAR(len)
     TEXT(len)   TEXT(len). len is the maximal length.
     And LIKE works.
     INT   INT. With many more options!
     REAL   REAL. Or FLOAT. Both 4- and 8-byte versions are available.
     UINT   INT UNSIGNED
     DATE   DATE. Uses ANSI SQL format rather than mSQL's own format.
     TIME   TIME
     MONEY   DECIMAL(12,2). A fixed-point value with two decimals.

Index creation

MySQL
     Indexes may be specified at table creation time with the CREATE TABLE statement.

mSQL
     Indexes must be created after the table has been created, with separate CREATE INDEX statements.

To insert a unique identifier into a table

MySQL
     Use AUTO_INCREMENT as a column type specifier. See mysql_insert_id().

mSQL
     Create a SEQUENCE on a table and select the _seq column.

To obtain a unique identifier for a row

MySQL
     Add a PRIMARY KEY or UNIQUE key to the table and use this. New in 3.23.11: If the PRIMARY or UNIQUE key consists of only one column and this is of type integer, one can also refer to it as _rowid.

mSQL
     Use the _rowid column. Observe that _rowid may change over time depending on many factors.

To get the time a column was last modified

MySQL
     Add a TIMESTAMP column to the table. This column is automatically set to the current date and time for INSERT or UPDATE statements if you don't give the column a value or if you give it a NULL value.

mSQL
     Use the _timestamp column.

NULL value comparisons

MySQL
     MySQL follows ANSI SQL and a comparison with NULL is always NULL.

mSQL
     In mSQL, NULL = NULL is TRUE.  You must change =NULL to IS NULL and <>NULL to IS NOT NULL when porting old code from mSQL to MySQL.

String comparisons

MySQL
     Normally, string comparisons are performed in case-independent fashion with the sort order determined by the current character set (ISO-8859-1 Latin1 by default).  If you don't like this, declare your columns with the BINARY attribute, which causes comparisons to be done according to the ASCII order used on the MySQL server host.

mSQL
     All string comparisons are performed in case-sensitive fashion with sorting in ASCII order.

Case-insensitive searching

MySQL
     LIKE is a case-insensitive or case-sensitive operator, depending on the columns involved. If possible, MySQL uses indexes if the LIKE argument doesn't start with a wildcard character.

mSQL
     Use CLIKE.

Handling of trailing spaces

MySQL
     Strips all spaces at the end of CHAR and VARCHAR columns. Use a TEXT column if this behavior is not desired.

mSQL
     Retains trailing space.

WHERE clauses

MySQL
     MySQL correctly prioritizes everything (AND is evaluated before OR). To get mSQL behavior in MySQL, use parentheses (as shown below).

mSQL
     Evaluates everything from left to right. This means that some logical calculations with more than three arguments cannot be expressed in any way. It also means you must change some queries when you upgrade to MySQL. You do this easily by adding parentheses.  Suppose you have the following mSQL query:

          mysql> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4;

     To make MySQL evaluate this the way that mSQL would, you must add parentheses:

          mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));

Access control

MySQL
     Has tables to store grant (permission) options per user, host and database. See Privileges.

mSQL
     Has a file mSQL.acl in which you can grant read/write privileges for users.

How MySQL compares to PostgreSQL
================================

We would first like to note that PostgreSQL and MySQL are both widely used products but their design goals are completely different.  This means that for some applications MySQL is more suitable and for others PostgreSQL is more suitable.  When choosing which database to use you should first check if the databases feature set is good enough to satisfy your application.  If you need speed then MySQL is probably your best choice, if you need some of the extra features that PostgreSQL can offer you should use PostgreSQL.

PostgreSQL はさらに進んだ機能をいくつか持っています。ユーザ定義型、トリガ、ルール、トランザクションのような。 (currently it's has about same symantic as MySQL's transactions in that the transaction is not 100 % atomic) しかし ANSI SQL と ODBC の標準型と機能の多くが欠けています。サポート/未サポートの型/関数の完全な一覧は crash-me web page (http://www.mysql.com/crash-me-choose.htmy) を見てください。

通常、PostgreSQL は MySQL よりとても遅いです。 See Benchmarks.  This is due largely to they have only transaction safe tables and that their transactions system is not as sophisticated as Berkeley DB's.  In MySQL you can decide per table if you want the table to be fast or take the speed penalty of making it transaction safe.

The most important things that PostgreSQL supports that MySQL don't yet support:

Sub select

Foregin keys

Stored procedures

An extendable type system.

A way to extend the SQL to handle new key types (like R-trees)

MySQL on the other hand supports a many ANSI SQL constructs that PostgreSQL doesn't support;  Most of these can be found at the crash-me web page (http://www.mysql.com/crash-me-choose.htmy).

If you really need the rich type system PostgreSQL offers and you can afford the speed penalty of having to do everything transaction safe, you should take a look at PostgreSQL.

MySQL internals
***************

This chapter describes a lot of things that you need to know when working on the MySQL code.

MySQL threads
=============

MySQL サーバーは以下のスレッドを作成します：

  * TCP/IP 接続ハンドルは、全ての接続要求を扱い、さらに、認証を行うためのスレッドSQLクエリを処理するスレッドを生成します

  * NTでは、ネームド・パイプ・ハンドラー・スレッドがあります。これはネームド・パイプの接続要求に対し、TCP/IP接続スレッドと同様に動きます。

  * シグナルスレッドは、全てのシグナルを扱います。 This thread also normally handles alarms and calls process_alarm() to force timeouts on connections that have been idle too long.

  * If compiled with -DUSE_ALARM_THREAD, a dedicated thread that handles alarms is created. This is only used on some systems where there are some problems with sigwait() or if one wants to use the thr_alarm() code in ones application without a dedicated signal handling thread.

  * もし --flush-time オプションを使用したなら、全てのテーブルを一定期間でフラッシュするためだけのスレッドを作ります。

  * Every connection has its own thread.

  * Every different table on which one uses INSERT DELAYED gets its own thread.

  * If you use --master-host , slave replication thread will be started to read and apply updates from the master.

mysqladmin processlist only shows the connection and INSERT DELAYED threads.

Environment variables
*********************

Here follows a list of all environment variables that are used directly or indirectly by MySQL. Most of these can also be found at other places in this manual.

Note that any options on the command line will take precedence over values specified in configuration files and environment variables, and values in configuration files take precedence over values in environment variables.

In many cases its preferable to use a configure file instead of environment variables to modify the behaviour of MySQL. See Option files.

CCX    Set this to your C++ compiler when running configure.
CC    Set this to your C compiler when running configure.
CFLAGS   Flags for your C compiler when running configure.
CXXFLAGS   Flags for your C++ compiler when running configure.
DBI_USER   The default user name for Perl DBI.
DBI_TRACE   Used when tracing Perl DBI.
HOME   The default path for the mysql history file is $HOME/.mysql_history.
LD_RUN_PATH   Used to specify where your libmysqlclient.so is.
MYSQL_DEBUG   Debug-trace options when debugging
MYSQL_HISTFILE   The path to the mysql history file.
MYSQL_HOST   Default host name used by the mysql command line prompt.
MYSQL_PWD   The default password when connecting to mysqld. Note that use of this is insecure!
MYSQL_TCP_PORT   The default TCP/IP port.
MYSQL_UNIX_PORT   The default socket; used for connections to localhost.
PATH   Used by the shell to finds the MySQL programs.
TMPDIR   The directory where temporary tables/files are created.
TZ   This should be set to your local timezone. See Timezone problems.
UMASK_DIR   The user-directory creation mask when creating directories. Note that this is anded with UMSK !
UMASK   The user-file creation mask when creating files.
USER   The default user on Windows to use when connection to mysqld.

Some MySQL users
****************

General news sites
==================

  * Yahoo! (http://www.yahoo.com/)

  * Slashdot: A pro-Linux/tech news and comment/discussion site (http://slashdot.org/)

  * All about Linux (http://www.linux.com/)

  * Linuxtoday (http://www.linuxtoday.com/)

  * 32Bits Online: because there's more than one way to compute (http://www.32bitsonline.com/)

  * Freshmeat: News about new versions of computer related stuff (http://www.freshmeat.net/)

Some Web search engines
=======================

  * AAA Matilda Web Search (http://www.aaa.com.au)

  * What's New (http://www.whatsnu.com/)

  * Aladin (http://www.aladin.de/)

  * Columbus Finder (http://www.columbus-finder.de/)

  * Spider (http://www.spider.de/)

  * Blitzsuche (http://www.blitzsuche.de/)

  * Indoseek Indonesia (http://www.indoseek.co.id)

  * Yaboo - Yet Another BOOkmarker (http://www.yaboo.dk/)

  * Yahoosuck (http://www.yahoosuck.com)

  * OzSearch Internet Guide (http://www.ozsearch.com.au)

  * Splat! Search (http://www.splatsearch.com/)

Some Information search engines concentrated on some area
=========================================================

  * TuCows Network; Free Software archive (http://www.tucows.com/)

  * Jobvertise: Post and search for jobs (http://www.jobvertise.com)

  * The Music Database (http://www.musicdatabase.com)

  * Fotball (Soccer) search page (http://www.soccersearch.com)

  * TAKEDOWN - wrestling (http://www.headrush.net/takedown)

  * The International Lyrics Network (http://www.lyrics.net)

  * Musicians looking for other musicians (Free Service) (http://TheMatrix.com/~matrix/band_search.phtml)

  * AddALL books searching and price comparison (http://www.addall.com/AddBooks/Stores.html)

  * Harvard's Gray Herbarium Index of Plant Names (http://www.herbaria.harvard.edu/Data/Gray/gray.html)

  * The Game Development Search Engine (http://www.game-developer.com/)

  * My-Recipe.com; Cookbook at i-run.com (http://www.i-run.com/html/cookbook.html)

  * The Innkeeper Vacation Guides (www.theinnkeeper.com)

  * The Mac Game Database uses PHP and MySQL (http://www.macgamedatabase.com/)

  * Research Publications at Monash University in Australia (http://www.csse.monash.edu.au/publications/)

  * Occupational Health & Safety website databse (a project for the ECC) (http://www.ipielle.emr.it/bts/index.html)

  * Bioinformatics databases at the Montreal Children's Hospital using MySQL (http://data.mch.mcgill.ca/)

Online magazines
================

  * Spoiler Webzine (http://www.spoiler.com). An online magazine featuring music, literature, arts, and design content.

  * Daily news about Linux in German language (http://www.linux-magazin.de/newsflash/)

  * Betazine - The Ultimate Online Beta Tester's Magazine (http://www.betazine.com)

  * Computer Currents Magazine (http://www.currents.net/ccinfo/aboutcc.html)

Web sites that use MySQL as a backed
====================================

  * Qt Widget and Object Repository (http://lindev.jmc.tju.edu/qwor)

  * Brazilian samba site (in Portuguese) (http://www.samba-choro.com.br)

  * Polish General Social Survey (http://pgss.iss.uw.edu.pl/en_index.ISS)

  * Expo2000 (http://www.expo2000.com) World-wide distribution of tickets for this event is implemented using MySQL and tcl/tk. More than 5000 travel-agencies all over the world have access to it.

  * FreeVote.com is a free voting service with millions of users. (http://www.freevote.com/)

  * Forza Motorsport (http://f1.tauzero.se)

Some Domain/Internet/Web and related services
=============================================

  * Registry of Web providers that support MySQL (http://www.wix.com/mysql-hosting)

  * Dynamic DNS Services (http://www.yi.org/)

  * Dynamic domain name service (http://www.dynodns.net/)

  * Open DNS Project; free dynamic DNS service (http://www.ods.org/)

  * Free 3rd level domains (http://www.fdns.net/)

  * Online Database (http://worldcommunity.com/)

  * BigBiz Internet Services (http://www.bigbiz.com)

  * The Virt Gazette (http://virt.circle.net)

  * Global InfoNet Inc (http://www.california.com)

  * WebHosters - A Guide to WWW Providers (http://www.webhosters.com)

  * Internet information server (http://online.dn.ru)

  * A technology news site (http://www.stopbit.com)

  * WorldNet Communications - An Internet Services Provider (http://www.worldnetla.net)

  * Netizen: Australian-based web consultancy (http://www.netizen.com.au/)

  * Search site for training courses in the UK (http://www.trainingpages.co.uk)

  * Gannon Chat (GPL). Written in Perl and Javascript (http://chat.nitco.com)

  * A general links directory (http://www.addurls.com/)

  * A web-based bookmark management service (http://www.bookmarktracker.com)

  * Walnut Creek CDROM (http://www.cdrom.com)

  * WWWThreads; Interactive discussion Forums (http://www.wwwthreads.org/)

  * In Italian; Storage data from meteo station (http://pvmon.portici.enea.it/Meteo)

  * Online "Person To Person" Auction (http://www.buysell.net/)

  * Tips on web development (http://tips.pair.com)

  * Mailfriends.com is a FREE service for everybody who wants to find friends over the internet. (http://www.mailfriends.com)

  * Web Page Telnet BBS List (http://www.uninova.com/cgi-bin/wctelnets?list)

  * UniNova Digital Postcards (http://www.uninova.com/cnc.html)

  * DSL providers search with reviews (http://www.dslreports.com) Made with MySQL and Modperl, all pages are generated dynamically out of the MySQL database

Web sites that use PHP and MySQL
================================

  * Jgaa's Internet - Official Support Site (http://war.jgaa.com:8080/support/index.php3)

  * Ionline - online publication: (http://io.incluso.com) MySQL, PHP, Java, Web programming, DB development

  * BaBoo(Browse and bookmark). Free web-based bookmark manager and Calendar (http://www.baboo.com)

  * Course Schedule System at Pensacola Junior College (http://www.courses.pjc.cc.fl.us/Schedule/index.php)

  * Florida Community College at Jacksonville (http://www.fccj.org)

  * 32bit.com; An extensive shareware / freeware archive (http://www.32bit.com/)

  * Jokes 2000 (http://www.jokes2000.com/)

  * Burken.NU (http://www.burken.nu/) Burken is a webhotel that provides scripts, among other things, for remote users, like counters, guestbooks etc.

  * tips.pair.com (http://tips.pair.com) Contains tips on html, javascript, 2d/3d graphics and PHP3/MySQL. All pages are generated from a database.

Some MySQL consultants
======================

  * Ayni AG (http://www.ayni.com)

  * Online Database (http://worldcommunity.com/)

  * DataGuard (Uses MySQL and PHP) (http://www2.dataguard.no/)

  * WWITS (Uses MySQL and PHP) (http://wwits.net/programs/mysql.phtml)

  * WCN - The World Community Network (http://www.worldcommunity.com/)

  * Chip Castle Dot Com Inc (http://www.chipcastle.com)

  * Cybersource Pty. Ltd (http://www.cyber.com.au/)

  * Spring infotainment gmbh & co. kg (http://www.spring.de)

  * Develops websites using MySQL (http://www.wamdesign.com/)

  * Berkeley Consultants Group (http://www.berkeleyconsultants.com)

Programming
===========

  * The Perl CPAN Testers results page (http://www.perl.org/cpan-testers)

Uncategorized pages
===================

  * AZC.COM's Feature Showcase (http://www.feature-showcase.com/htmls/demo_mysql.sql)

  * Course Search (http://www.teach.org.uk/subjects/trainingcourse/g.html)

  * Northerbys Online Auctions (http://www.northerbys.com)

  * Amsterdam Airport Schiphol (http://www.schiphol.nl/flights/home.htm)

  * CD database (http://TheMatrix.com/seventhsin/query.phtml)

  * Used Audio Gear Database (http://TheMatrix.com/~flmm/GEAR.html)

  * Musical note-sheets (http://www.kiss.de/musik-mueller)

  * Bagism - A John Lennon fan page (http://www.bagism.com)

  * US Folk art broker (http://www.selftaught.com/)

  * Mail reading on the web (http://organizer.net/)

  * Free home pages on www.somecoolname.mypage.org (http://www.mypage.org/)

  * Der Server für Schulen im Web (In German) (http://www.schulweb.de/)

  * Auldhaefen Online Services (http://www.ald.net/)

  * CaryNET Information Center (http://www.cary.net/)

  * Dataden Computer Systems (http://www.dataden.com/)

  * Andrémuseet (In Swedish) (http://andree.grm.se/)

  * HOMESITE Internet Marketing (http://www.him.net/)

  * Jade-V Network Services (http://www.jade-v.com/techinfo.html)

  * Weather World 2010 Technical Credits (http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml)

  * About The Gimp plugin registry (http://gimp.foebud.org/registry/doc/)

  * Java tool Archiver technical detail (Slightly optimistic about MySQL ANSI-92 compliance) (http://www.fast-inc.com/Products/Archiver/database.html)

  * Games Domain Cheats Database (http://www.gamesdomain.com/cheats/usrcheat.phtml)

  * The "Powered By" Page (Kcilink) (http://www.kcilink.com/poweredby/)

  * Netcasting (http://www.netcasting.net/index.whtml)

  * NBL (Australian National Basketball League) tipping (http://homepages.tig.com.au/~mjj/nbltips)

  * CGI shop (http://www.cgishop.com/)

  * Whirlycott: Website Design (http://www.whirlycott.com/)

  * Museum Tusculanum Press (http://www.mtp.dk)

  * Centro Siciliano di Documentazione (http://csdgi.historie.ku.dk/biblio)

  * Quake statistics database (http://caribou.dyn.ml.org:8000)

  * Astroforum: Astrologie and related things (in German) (http://www.astroforum.ch)

  * OpenDebate - Interactive Polls & Open Discussion (http://www.opendebate.com)

  * Online chemical dissertation server (http://vermeer.organik.uni-erlangen.de/dissertationen/)

  * FreSch! The Free Scholarship Search Service (http://www.freschinfo.com)

  * Stockholm Pinball Locator (http://www.nada.kth.se/~staffanu/pinball)

  * HEK A construction company (http://www.hek.com)

  * Elsevier Bussines Information (http://www.nbi.nl)

  * Medical Links (Using ColdFusion and MySQL) (http://vaccination.medicallink.se/)

  * Search for jobs & people at JobLink-USA (http://www.joblink-usa.com)

  * Competition Formation Skydiving (http://www.skydive.net/competfs)

  * E-commerce and internal accounting (http://www.galaxy-net.net/Galaxy-NET Telecommunications)

  * Denmark's leading business daily newspaper Borsen (http://www.borsen.dk/)

  * The Internet NES Database (http://tmmm.simplenet.com/indb/)

  * Travel agency in Prague in 3 languages (http://www.russia.cz)

  * Linkstation (http://www.linkstation.de)

  * Searchable online database at Peoplestaff (http://www.peoplestaff.com)

  * A searchable database system for horse classified ads (http://www.dreamhorse.com)

  * The Poot site (http://pootpoot.com/)

  * "Playin' in the LAN"; a network monitoring suite (http://grateful.net/hw_html/)

  * U.S. Army Publishing Agency (http://www.usapa.army.mil)

  * Realestate handling in Yugoslavia (http://www.nekretnine.co.yu/)

  * PIMS; a Patient Information Management System (http://demo.cpsoft.com/pims/devFAQ.html)

  * Pilkington Software Inc (http://cpsoft.com)

  * A Vietnam Veteran's Memorial (The Wall) database. (http://www.no-quarter.org/)

  * Gamer's Union specializes inauctions of used & out of print gaming material (http://www.gamers-union.com/)

  * A daily bulletin at Monterey High school (http://www.montereyhigh.com/office/dbul.php3)

  * Community-owned site serving Lake Washington's Eastside residents and businesses (http://www.myEastside.com)

  * French bowling site (http://bowling-france.net/).

Send any additions to this list to webmaster@mysql.com.

Contributed programs
********************

Many users of MySQL have contributed very useful support tools and addons.

A list of what is available at http://www.mysql.com/Contrib (or any mirror) is shown below. If you want to build MySQL support for the Perl DBI/DBD interface, you should fetch the Data-Dumper, DBI, and Msql-Mysql-modules files and install them. See Perl support.

00-README (http://www.mysql.com/Contrib/00-README) This listing.

API's
=====

  * Perl modules

       * Data-Dumper-2.101.tar.gz (http://www.mysql.com/Contrib/Data-Dumper-2.101.tar.gz) Perl Data-Dumper module.  Useful with DBI/DBD support for older perl installations.

       * DBI-1.13.tar.gz (http://www.mysql.com/Contrib/DBI-1.13.tar.gz) Perl DBI module.

       * KAMXbase1.0.tar.gz (http://www.mysql.com/Contrib/KAMXbase1.0.tar.gz) Convert between .dbf files and MySQL tables.  Perl module written by Pratap Pereira pereira@ee.eng.ohio-state.edu, extened by Kevin A. McGrail kmcgrail@digital1.peregrinehw.com. This converter can handle MEMO fields.

       * Msql-Mysql-modules-1.2209.tar.gz (http://www.mysql.com/Contrib/Msql-Mysql-modules-1.2209.tar.gz) Perl DBD module to access mSQL and MySQL databases..

       * Data-ShowTable-3.3.tar.gz (http://www.mysql.com/Contrib/Data-ShowTable-3.3.tar.gz) Perl Data-ShowTable module.  Useful with DBI/DBD support.

  * JDBC

       * mm.mysql.jdbc-1.2c.tar.gz (http://www.mysql.com/Contrib/mm.mysql.jdbc-1.2c.tar.gz) The mm JDBC driver for MySQL. This is a production release and is actively developed. By Mark Matthews (mmatthew@ecn.purdue.edu).

       * mm.mysql.jdbc-2.0pre5.tar.gz (http://www.mysql.com/Contrib/mm.mysql.jdbc-2.0pre5.tar.gz) The mm JDBC driver for MySQL. This is a pre-release beta version and is actively developed. By Mark Matthews (mmatthew@ecn.purdue.edu). The two drivers above have an LGPL license. Please check http://www.worldserver.com/mm.mysql/ for the latest drivers (and other JDBC information) because these drivers may be ou updated as frequently.

       * twz1jdbcForMysql-1.0.4-GA.tar.gz (http://www.mysql.com/Contrib/twz1jdbcForMysql-1.0.4-GA.tar.gz) The twz driver: A type 4 JDBC driver by Terrence W. Zellers zellert@voicenet.com.  This is commercial but is free for private and educational use.

       * pmdamysql.tgz (http://www.mysql.com/Contrib/pmdamysql.tgz) A MySQL PMDA. Provides MySQL server status and configuration variables.

  * C++

       * mysql-c++-0.02.tar.gz (http://www.mysql.com/Contrib/mysql-c++-0.02.tar.gz) MySQL C++ wrapper library. By Roland Haenel, rh@ginster.net.

       * MyDAO (http://www.mysql.com/Contrib/MyDAO.tar.gz) MySQL C++ API. By Satish spitfire@pn3.vsnl.net.in. Inspired by Roland Haenel's C++ API and Ed Carp's MyC library.

       * mysql++ (http://www.mysql.com/download_mysql++.html) MySQL C++ API (More than just a wrapper library). Originally by kevina@clark.net. Nowadays maintained by Sinisa at TCX.

       * NJrAPI (http://nelsonjr.homepage.com/NJrAPI) A C++ database independent library that supports MySQL.

  * Delphi

       * delphi-interface.gz (http://www.mysql.com/Contrib/delphi-interface.gz) Delphi interface to libmysql.dll, by Blestan Tabakov, root@tdg.bis.bg.

       * DelphiMySQL2.zip (http://www.mysql.com/Contrib/DelphiMySQL2.zip) Delphi interface to libmysql.dll, by bsilva@umesd.k12.or.us

       * Udmysql.pas (http://www.mysql.com/Contrib/Udmysel.pas) A wrapper for libmysql.dll for usage in Delphi. By Reiner Sombrowsky.

       * A Delphi interface to MySQL. (http://www.fichtner.net/delphi/mysql.delphi.phtml) With source code. By Matthias Fichtner.

       * TmySQL A library to use MySQL with Delphi (http://www.productivity.org/projects/mysql/)

       * Delphi TDataset-component (http://www.geocities.com/CapeCanaveral/2064/mysql.html)

  * mysql-ruby-2.2.0.tar.gz (http://www.mysql.com/Contrib/mysql-ruby-2.2.0.tar.gz) MySQL Ruby module. By TOMITA Masahiro tommy@tmtm.org Ruby (http://www.netlab.co.jp/ruby/) is an Object-Oriented Interpreter Language.

  * JdmMysqlDriver-0.1.0.tar.gz (http://www.mysql.com/Contrib/JdmMysqlDriver-0.1.0.tar.gz) A VisualWorks 3.0 Smalltalk driver for MySQL. By joshmiller@earthlink.net

  * Db.py (http://www.mysql.com/Contrib/Db.py) Python module with caching. By gandalf@rosmail.com.

  * MySQLmodule-1.4.tar.gz (http://www.mysql.com/Contrib/MySQLmodule-1.4.tar.gz) Python interface for MySQL. By Joseph Skinner joe@earthlight.co.nz;  Modified by Joerg Senekowitsch senekow@ibm.net

  * mysql_mex_1_1.tar.gz (http://www.mysql.com/Contrib/mysql_mex_1_1.tar.gz) An interface program for the Matlab program by MathWorks.  The interface is done by Kimmo Uutela and John Fisher (not by Mathworks). Check mysqlmex.html (http://boojum.hut.fi/~kuutela/mysqlmex.html) for more information.

  * mysqltcl-1.53.tar.gz (http://www.mysql.com/Contrib/mysqltcl-1.53.tar.gz) Tcl interface for MySQL. Based on msqltcl-1.50.tar.gz. Updated by Tobias Ritzau, tobri@ida.liu.se.

  * MyC-0.1.tar.gz (http://www.mysql.com/Contrib/MyC-0.1.tar.gz) A Visual Basic-like API, by Ed Carp.

  * sqlscreens-1.0.1.tar.gz (http://www.mysql.com/Contrib/sqlscreens-1.0.1.tar.gz) Tcl/TK code to generate database screens. By Jean-Francois Dockes.

  * Vdb-dflts-2.1.tar.gz (http://www.mysql.com/Contrib/Vdb-dflts-2.1.tar.gz) This is a new version of a set of library utilities intended to provide a generic interface to SQL database engines such that your application becomes a 3-tiered application.  The advantage is that you can easily switch between and move to other database engines by implementing one file for the new backend without needing to make any changes to your applications. By damian@cablenet.net.

  * DbFramework-1.10.tar.gz (http://www.mysql.com/Contrib/DbFramework-1.10.tar.gz) DbFramework is a collection of classes for manipulating MySQL databases.  The classes are loosely based on the CDIF Data Model Subject Area. By Paul Sharpe paul@miraclefish.com.

  * pike-mysql-1.4.tar.gz (http://www.mysql.com/Contrib/pike-mysql-1.4.tar.gz) MySQL module for pike. For use with the Roxen web server.

  * squile.tar.gz (http://www.mysql.com/Contrib/squile.tar.gz) Module for guile that allows guile to interact with SQL databases. By Hal Roberts.

  * stk-mysql.tar.gz (http://www.mysql.com/Contrib/stk-mysql.tar.gz) Interface for Stk. Stk is the Tk widgets with Scheme underneath instead of Tcl. By Terry Jones

  * eiffel-wrapper-1.0.tar.gz (http://www.mysql.com/Contrib/eiffel-wrapper-1.0.tar.gz). Eiffel wrapper by Michael Ravits.

Clients
=======

  * Graphical clients

       * mysqlgui homepage (http://www.mysql.com/download_clients.html) The MySQL GUI client homepage. By Sinisa at TCX.

       * kmysqladmin-0.4.1.tar.gz (http://www.mysql.com/Contrib/kmysqladmin-0.4.1.tar.gz)

       * kmysqladmin-0.4.1-1.src.rpm (http://www.mysql.com/Contrib/kmysqladmin-0.4.1-1.src.rpm)

       * kmysqladmin-0.4.1-1.i386.rpm (http://www.mysql.com/Contrib/kmysqladmin-0.4.1-1.i386.rpm) An administration tool for the MySQL server using QT / KDE.  Tested only on Linux.

       * Java client using Swing (http://www.mysql.com/Contrib/mysql-admin-using-java+swing.tar.gz) By Fredy Fischer, se-afs@dial.eunet.ch. Ypu can always find the latest version here (http://www.trash.net/~ffischer/admin/index.html).

       * mysqlwinadmn.zip (http://www.mysql.com/Contrib/mysqlwinadmn.zip) Win32 GUI (binary only) to administrate a database, by David B. Mansel, david@zhadum.org.

       * netadmin.zip (http://www.mysql.com/Contrib/netadmin.zip) A administrator tool for MySQL on Windows 95/98 and Windows NT 4.0. Only tested with MySQL 3.23.5 - 3.23.7. Written using the Tmysql components.

          You can write queries and show tables, indexes, table syntax and administrate user,host and database and so on. The is still beta and have still some bugs. you can test the program with all features. Please send bugs and hints to Marco Suess ms@it-netservice.de. Original URL http://www.it-netservice.de/pages/software/index.html.

       * xmysqladmin-1.0.tar.gz (http://www.mysql.com/Contrib/xmysqladmin-1.0.tar.gz) A front end to the MySQL database engine.  It allows reloads, status check, process control, myisamchk, grant/revoke privileges, creating databases, dropping databases, create, alter, browse and drop tables.  Originally by Gilbert Therrien, gilbert@ican.net but now in public domain and supported by TcX.

       * xmysql-1.9.tar.gz (http://www.mysql.com/Contrib/xmysql-1.9.tar.gz)

       * xmysql home page (http://web.wt.net/~dblhack) A front end to the MySQL database engine. It allows for simple queries and table maintenance, as well as batch queries. By Rick Mehalick, dblhack@wt.net. Requires xforms 0.88 (http://bragg.phys.uwm.edu/xforms) to work.

       * dbMetrix (http://www.tamos.net/sw/dbMetrix) An open source client for exploring databases and executing SQL. Supports MySQL, Oracle, PostgreSQL and mSQL.

       * GtkSQL (http://www.multimania.com/bbrox/GtkSQL) A query tool for MySQL and PostgreSQL.

       * dbMan (http://dbman.linux.cz/) A query tool written in Perl. Uses DBI and Tk.

       * Atronic's MySQL client for Win32 (http://www.mysql.com/Downloads/Win32/ArtronicWINAdmin.exe)

       * mascon1.exe (http://www.mysql.com/Contrib/mascon1.exe) You can get the newest one from http://www.SciBit.com.

       * DBUI (http://www.virtualbeer.net/dbui/) DBUI is a Gtk graphical database editor.

  * Web clients

       * mysqladmin-atif-1.0.tar.gz (http://www.mysql.com/Contrib/mysqladmin-atif-1.0.tar.gz) WWW MySQL administrator for the user, db and host tables.  By Tim Sailer, modified by Atif Ghaffar aghaffar@artemedia.ch.

       * mysql-webadmin-1.0a8-rz.tar.gz (http://www.mysql.com/Contrib/mysql-webadmin-1.0a8-rz.tar.gz) A tool written in PHP-FI to administrate MySQL databases remotely over the web within a Web-Browser. By Peter Kuppelwieser, peter.kuppelwieser@kantea.it. Updated by Wim Bonis, bonis@kiss.de. Not maintained anymore!

       * mysqladm.tar.gz (http://www.mysql.com/Contrib/mysqladm.tar.gz) MySQL Web Database Administration written in Perl.  By Tim Sailer.

       * mysqladm-2.tar.gz (http://www.mysql.com/Contrib/mysqladm-2.tar.gz) Updated version of mysqladm.tar.gz, by High Tide.

       * billowmysql.zip (http://www.mysql.com/Contrib/billowmysql.zip) Updated version of mysqladm.tar.gz, by Ying Gao.

       * myadmin-0.4.tar.gz (http://www.mysql.com/Contrib/myadmin-0.4.tar.gz)

       * MyAdmin home page (http://myadmin.cheapnet.net/) A web based mysql administrator by Mike Machado.

       * phpMyAdmin_2.0.1.tar.gz (http://www.mysql.com/Contrib/phpMyAdmin_2.0.1.tar.gz) A set of PHP3-scripts to adminstrate MySQL over the WWW.

       * phpMyAdmin home page (http://www.htmlwizard.net/phpMyAdmin/) A PHP3 tool in the spirit of mysql-webadmin, by Tobias Ratschiller, tobias@dnet.it

       * useradm.tar.gz (http://www.mysql.com/Contrib/useradm.tar.gz) MySQL administrator in PHP. By Ofni Thomas othomas@vaidsystems.com.

  * mysql-editor.tar.gz (http://www.mysql.com/Contrib/mysql-editor.tar.gz) This cgi scripts in Perl enables you to edit content of Mysql database. By Tomas Zeman.

Web tools
=========

  * mod_mysql_include_1.0.tar.gz (http://www.mysql.com/Contrib/mod_mysql_include_1.0.tar.gz) Apache module to include HTML from MySQL queries into your pages, and run update queries. Originally written to implement a simple fast low-overhead banner-rotation system. By Sasha Pachev.

  * http://www.odbsoft.com/cook/sources.htm This package has various functions for generating html code from a SQL table structure and for generating SQL statements (Select, Insert, Update, Delete) from an html form. You can build a complete forms interface to a SQL database (query, add, update, delete) without any programming!  By Marc Beneteau, marc@odbsoft.com.

  * sqlhtml.tar.gz (http://www.mysql.com/Contrib/sqlhtml.tar.gz) SQL/HTML is an HTML database manager for MySQL using DBI 1.06.

  * UdmSearch 2.2.1b (stable version) (http://www.mysql.com/Contrib/udmsearch-2.2.1b.tar.gz)

  * UdmSearch 3.0.5 (development version) (http://www.mysql.com/Contrib/udmsearch-3.0.5.tar.gz)

  * UdmSearch home page (http://mysearch.udm.net) A MySQL- and PHP- based search engine over HTTP. By Alexander I. Barkov bar@izhcom.ru.

  * wmtcl.doc (http://www.mysql.com/Contrib/wmtcl.doc)

  * wmtcl.lex (http://www.mysql.com/Contrib/wmtcl.lex) With this you can write HTML files with inclusions of TCL code. By vvs@scil.npi.msu.su.

  * www-sql-0.5.7.lsm (http://www.mysql.com/Contrib/www-sql-0.5.7.lsm)

  * www-sql-0.5.7.tar.gz (http://www.mysql.com/Contrib/www-sql-0.5.7.tar.gz) A CGI program that parses an HTML file containing special tags, parses them and inserts data from a MySQL database.

  * genquery.zip (http://www.mysql.com/Contrib/genquery.zip) Perl SQL database interface package for html.

  * cgi++-0.8.tar.gz (http://www.mysql.com/Contrib/cgi++-0.8.tar.gz) A macro-processor to simply writing CGI/Database programs in C++ by Sasha Pachev.

  * WebBoard 1.0 (http://www.mysql.com/Contrib/webboard-1.0.zip) EU-Industries Internet-Message-Board.

  * DBIx-TextIndex-0.02.tar.gz (http://www.mysql.com/Contrib/DBIx-TextIndex-0.02.tar.gz) Full-text searching with Perl on BLOB/TEXT columns by Daniel Koch.

Performance Benchmarking tools
==============================

  * mysql-super-smack and friends (http://www.mysql.com/Contrib/mysql-bench-0.6.tar.gz) User-customizable multi-threaded tool set to benchmark MySQL. By Sasha Pachev.

Authentication tools
====================

  * ascend-radius-mysql-0.7.1.patch.gz (http://www.mysql.com/Contrib/ascend-radius-mysql-0.7.1.patch.gz) This is authentication and logging patch using MySQL for Ascend-Radius. By takeshi@SoftAgency.co.jp.

  * icradius 0.10 (http://www.mysql.com/Contrib/icradius-0.10.tar.gz) icradius readme file (http://www.mysql.com/Contrib/icradius.README)

  * checkpassword-0.81-mysql-0.6.5.patch.gz (http://www.mysql.com/Contrib/checkpassword-0.81-mysql-0.6.5.patch.gz) MySQL authentication patch for QMAIL and checkpassword. These are useful for management user(mail,pop account) by MySQL. By takeshi@SoftAgency.co.jp

  * jradius-diff.gz (http://www.mysql.com/Contrib/jradius-diff.gz) MySQL support for Livingston's Radius 2.01. Authentication and Accounting. By Jose de Leon, jdl@thevision.net

  * mod_auth_mysql-2.20.tar.gz (http://www.mysql.com/Contrib/mod_auth_mysql-2.20.tar.gz) Apache authentication module for MySQL. By Zeev Suraski, bourbon@netvision.net.il.

     Please register this module at: http://bourbon.netvision.net.il/mysql/mod_auth_mysql/register.html. The registering information is only used for statistical purposes and will encourage further development of this module!

  * mod_log_mysql-1.05.tar.gz (http://www.mysql.com/Contrib/mod_log_mysql-1.05.tar.gz) MySQL logging module for Apache. By Zeev Suraski, bourbon@netvision.net.il.

  * mypasswd-2.0.tar.gz (http://www.mysql.com/Contrib/mypasswd-2.0.tar.gz) Extra for mod_auth_mysql. This is a little tool that allows you to add/change user records storing group and/or password entries in MySQL tables. By Harry Brueckner, brueckner@respublica.de.

  * mysql-passwd.README (http://www.mysql.com/Contrib/mysql-passwd.README)

  * mysql-passwd-1.2.tar.gz (http://www.mysql.com/Contrib/mysql-passwd-1.2.tar.gz) Extra for mod_auth_mysql. This is a two-part system for use with mod_auth_mysql.

  * pam_mysql.tar.gz (http://www.mysql.com/Contrib/pam_mysql.tar.gz) This module authenticates users via pam, using MySQL.

  * nsapi_auth_mysql.tar (http://www.mysql.com/Contrib/nsapi_auth_mysql.tar) Netscape Web Server API (NSAPI) functions to authenticate (BASIC) users against MySQL tables. By Yuan John Jiang.

  * qmail-1.03-mysql-0.6.5.patch.gz (http://www.mysql.com/Contrib/qmail-1.03-mysql-0.6.5.patch.gz) Patch for qmail to authenticate users from a MySQL table.

  * pwcheck_mysql-0.1.tar.gz (http://www.mysql.com/Contrib/pwcheck_mysql-0.1.tar.gz) An authentication module for the Cyrus IMAP server. By Aaron Newsome.

Converters
==========

  * dbf2mysql-1.13.tgz (http://www.mysql.com/Contrib/dbf2mysql-1.13.tgz) Convert between .dbf files and MySQL tables. By Maarten Boekhold, boekhold@cindy.et.tudelft.nl, and Michael Widenius. This converter can't handle MEMO fields.

  * dbf2mysql.zip (http://www.mysql.com/Contrib/dbf2mysql.zip) Convert between FoxPro .dbf files and MySQL tables on Win32. By Alexander Eltsyn, ae@nica.ru or ae@usa.net.

  * dump2h-1.20.gz (http://www.mysql.com/Contrib/dump2h-1.20.gz) Convert from mysqldump output to a C header file. By Harry Brueckner, brueckner@mail.respublica.de.

  * exportsql.txt (http://www.mysql.com/Contrib/exportsql.txt) A script that is similar to access_to_mysql.txt, except that this one is fully configurable, has better type conversion (including detection of TIMESTAMP fields), provides warnings and suggestions while converting, quotes all special characters in text and binary data, and so on.  It will also convert to mSQL v1 and v2, and is free of charge for anyone. See http://www.cynergi.net/prod/exportsql/ for latest version. By Pedro Freire, support@cynergi.net.  Note: Doesn't work with Access2!

  * access_to_mysql.txt (http://www.mysql.com/Contrib/access_to_mysql.txt) Paste this function into an Access module of a database which has the tables you want to export. See also exportsql. By Brian Andrews. Note: Doesn't work with Access2!

  * importsql.txt (http://www.mysql.com/Contrib/importsql.txt) A script that does the exact reverse of exportsql.txt.  That is, it imports data from MySQL into an Access database via ODBC. This is very handy when combined with exportsql, because it lets you use Access for all DB design and administration, and synchronize with your actual MySQL server either way. Free of charge. See http://www.netdive.com/freebies/importsql/ for any updates. Created by Laurent Bossavit of NetDIVE. Note: Doesn't work with Access2!

  * /msql2mysqlWrapper 1.0 (http://www.mysql.com/Contrib/msql2mysqlWrapper-1.0.tgz) A C wrapper from mSQL to MySQL. By alfred@sb.net

  * sqlconv.pl (http://www.mysql.com/Contrib/sqlconv.pl) A simple script that can be used to copy fields from one MySQL table to another in bulk. Basically, you can run mysqldump and pipe it to the sqlconv.pl script and the script will parse through the mysqldump output and will rearrange the fields so they can be inserted into a new table. An example is when you want to create a new table for a different site you are working on, but the table is just a bit different (ie - fields in different order, etc.). By Steve Shreeve.

Using MySQL with other products
===============================

  * emacs-sql-mode.tar.gz (http://www.mysql.com/Contrib/emacs-sql-mode.tar.gz) Raw port of a SQL mode for XEmacs. Supports completion. Original by Peter D. Pezaris pez@atlantic2.sbi.com and partial MySQL port by David Axmark.

  * MyAccess97 1.01 (http://www.mysql.com/Downloads/Win32/MyAccess97_Ver_1_01.zip) MyAccess is an AddIn for Access 97 and handles a lot of maintanance work for MySQL databases.

  * MyAccess2000 1.01 (http://www.mysql.com/Downloads/Win32/MyAccess2000_Ver_1_01.zip) MyAccess is an AddIn for Access 2000 and handles a lot of maintanance work for MySQL databases.

     MyAccess-readme (http://www.mysql.com/Downloads/Win32/MyAccess-1.01.readme).  By Hubertus Hiden.

  * radius-0.3.tar.gz (http://www.mysql.com/Contrib/radius-0.3.tar.gz) Patches for radiusd to make it support MySQL. By Wim Bonis, bonis@kiss.de.

Useful tools
============

  * mysql_watchdog.pl (http://www.mysql.com/Contrib/mysql_watchdog.pl) Monitor the MySQL daemon for possible lockups. By Yermo Lamers, yml@yml.com.

  * mysqltop.tar.gz (http://www.mysql.com/Contrib/mysqltop.tar.gz) Sends a query in a fixed time interval to the server and shows the resulting table. By Thomas Wana.

  * mysql_structure_dumper.tar.gz (http://www.mysql.com/Contrib/mysql_structure_dumper.tar.gz) Prints out the structure of the all tables in a database. By Thomas Wana.

  * structure_dumper.tgz (http://www.mysql.com/Contrib/mysql_structure_dumper.tgz) Prints the structure of every table in a database. By Thomas Wana.

  * mysqlsync-1.0-alpha.tar.gz (http://www.mysql.com/Contrib/mysqlsync). A perl script to keep remote copies of a MySQL database in sync with a central master copy. By Mark Jeftovic.  markjr@easydns.com

  * MySQLTutor (http://www.mysql.com/Contrib/MySQLTutor-0.2.tar.gz). MySQLTutor. A tutor of MySQL for beginners

  * MySQLDB.zip (http://www.mysql.com/Contrib/MySQLDB.zip) A COM library for MySQL by Alok Singh.

  * MySQLDB-readme.html (http://www.mysql.com/Contrib/MySQLDB-readme.html)

  * mysql_replicate.pl (http://www.mysql.com/Contrib/mysql_replicate.pl) Perl program that handles replication.  By elble@icculus.nsg.nwu.edu

  * DBIx-TextIndex-0.02.tar.gz (http://www.mysql.com/Contrib/DBIx-TextIndex-0.02.tar.gz) Perl program that uses reverse indexing to handle text searching. By Daniel Koch.

RPMs for common tools (Most are for RedHat 6.1)
===============================================

  * perl-Data-ShowTable-3.3-2.i386.rpm (http://www.mysql.com/Contrib/perl-Data-ShowTable-3.3-2.i386.rpm)

  * perl-Msql-Mysql-modules-1.2210-2.i386.rpm (http://www.mysql.com/Contrib/perl-Msql-Mysql-modules-1.2210-2.i386.rpm)

  * php-pg-3.0.13-1.i386.rpm (http://www.mysql.com/Contrib/php-pg-3.0.13-1.i386.rpm)

  * php-pg-manual-3.0.13-1.i386.rpm (http://www.mysql.com/Contrib/php-pg-manual-3.0.13-1.i386.rpm)

  * php-pg-mysql-3.0.13-1.i386.rpm (http://www.mysql.com/Contrib/php-pg-mysql-3.0.13-1.i386.rpm)

  * phpMyAdmin-2.0.5-1.noarch.rpm (http://www.mysql.com/Contrib/phpMyAdmin-2.0.5-1.noarch.rpm)

Useful functions
================

  * mysnprintf.c (http://www.mysql.com/Contrib/mysnprintf.c) sprintf() function for SQL queries that can escape blobs. By Chunhua Liu.

Uncategorized
=============

  * findres.pl (http://www.mysql.com/Contrib/findres.pl) Find reserved words in tables. By Nem W Schlecht.

  * handicap.tar.gz (http://www.mysql.com/Contrib/handicap.tar.gz) Performance handicapping system for yachts. Uses PHP. By rhill@stobyn.ml.org.

  * hylalog-1.0.tar.gz (http://www.mysql.com/Contrib/hylalog-1.0.tar.gz) Store hylafax outgoing faxes in a MySQL database. By Sinisa Milivojevic, sinisa@mysql.com.

  * mrtg-mysql-1.0.tar.gz (http://www.mysql.com/Contrib/mrtg-mysql-1.0.tar.gz) MySQL status plotting with MRTG, by Luuk de Boer, luuk@wxs.nl.

  * wuftpd-2.4.2.18-mysql_support.2.tar.gz (http://www.mysql.com/Contrib/wuftpd-2.4.2.18-mysql_support.2.tar.gz) Patches to add logging to MySQL for WU-ftpd. By Zeev Suraski, bourbon@netvision.net.il.

  * wu-ftpd-2.6.0-mysql_support.4.tar.gz (http://www.mysql.com/Contrib/wu-ftpd-2.6.0-mysql.4.tar.gz) Patches to add logging to MySQL for WU-ftpd 2.6.0. By, takeshi@SoftAgency.co.jp, based on Zeev Suraski wuftpd patches.

  * Old-Versions (http://www.mysql.com/Contrib/Old-Versions) Previous versions of things found here that you probably won't be interested in.

Contributors to MySQL
*********************

Contributors to the MySQL distribution are listed below, in somewhat random order:

Michael (Monty) Widenius
     Has written the following parts of MySQL:

       * All the main code in mysqld.

       * New functions for the string library.

       * Most of the mysys library.

       * The ISAM and MyISAM libraries (B-tree index file handlers with index compression and different record formats).

       * The heap library. A memory table system with our superior full dynamic hashing. In use since 1981 and published around 1984.

       * The replace program (look into it, it's COOL!).

       * MyODBC, the ODBC driver for Windows95.

       * Fixing bugs in MIT-pthreads to get it to work for MySQL. And also Unireg, a curses-based application tool with many utilities.

       * Porting of mSQL tools like msqlperl, DBD/DBI and DB2mysql.

       * Most parts of crash-me and the MySQL benchmarks.

David Axmark

       * Coordinator and main writer for the Reference Manual, including enhancements to texi2html. Also automatic website updating from this manual.

       * Autoconf, Automake and libtool support.

       * The licensing stuff.

       * Parts of all the text files.  (Nowadays only the README is left. The rest ended up in the manual.)

       * Our Mail master.

       * Lots of testing of new features.

       * Our in-house ``free'' software lawyer.

       * Mailing list maintainer (who never has the time to do it right...)

       * Our original portability code (more than 10 years old now). Nowadays only some parts of mysys are left.

       * Someone for Monty to call in the middle of the night when he just got that new feature to work. :-)

Paul DuBois
     Help with making the Reference Manual correct and understandable. That includes rewriting Monty's and David's attempts at English into English as other people know it.

Gianmassimo Vigazzola qwerg@mbox.vol.it or qwerg@tin.it
     The initial port to Win32/NT.

Kim Aldale
     Helped to rewrite Monty's and David's early attempts at English into English.

Allan Larsson (The BOSS at TcX)
     For all the time he has allowed Monty to spend on this ``maybe useful'' tool (MySQL). Dedicated user (and bug finder) of Unireg & MySQL.

Per Eric Olsson
     For more or less constructive criticism and real testing of the dynamic record format.

Irena Pancirov irena@mail.yacc.it
     Win32 port with Borland compiler. mysqlshutdown.exe and mysqlwatch.exe

David J. Hughes
     For the effort to make a shareware SQL database. We at TcX started with mSQL, but found that it couldn't satisfy our purposes so instead we wrote a SQL interface to our application builder Unireg.  mysqladmin and mysql are programs that were largely influenced by their mSQL counterparts. We have put a lot of effort into making the MySQL syntax a superset of mSQL. Many of the APIs ideas are borrowed from mSQL to make it easy to port free mSQL programs to MySQL. MySQL doesn't contain any code from mSQL. Two files in the distribution (client/insert_test.c and client/select_test.c) are based on the corresponding (non-copyrighted) files in the mSQL distribution, but are modified as examples showing the changes necessary to convert code from mSQL to MySQL. (mSQL is copyrighted David J. Hughes.)

Fred Fish
     For his excellent C debugging and trace library. Monty has made a number of smaller improvements to the library (speed and additional options).

Richard A. O'Keefe
     For his public domain string library.

Henry Spencer
     For his regex library, used in WHERE column REGEXP regexp.

Free Software Foundation
     From whom we got an excellent compiler (gcc), the libc library (from which we have borrowed strto.c to get some code working in Linux) and the readline library (for the mysql client).

Free Software Foundation & The XEmacs development team
     For a really great editor/environment used by almost everybody at TcX/detron.

Patrick Lynch
     For helping us acquire www.mysql.com.

Fred Lindberg
     For setting up qmail to handle MySQL mailing list and for the incredible help we got in managing the MySQL mailing lists.

Igor Romanenko igor@frog.kiev.ua
     mysqldump (previously msqldump, but ported and enhanced by Monty).

Tim Bunce, Alligator Descartes
     For the DBD (Perl) interface.

Andreas Koenig a.koenig@mind.de
     For the Perl interface to MySQL.

Eugene Chan eugene@acenet.com.sg
     For porting PHP to MySQL.

Michael J. Miller Jr. mke@terrapin.turbolift.com
     For the first MySQL manual. And a lot of spelling/language fixes for the FAQ (that turned into the MySQL manual a long time ago).

Giovanni Maruzzelli maruzz@matrice.it
     For porting iODBC (Unix ODBC).

Chris Provenzano
     Portable user level pthreads. From the copyright: This product includes software developed by Chris Provenzano, the University of California, Berkeley, and contributors.  We are currently using version 1_60_beta6 patched by Monty (see mit-pthreads/Changes-mysql).

Xavier Leroy Xavier.Leroy@inria.fr
     The author of LinuxThreads (used by MySQL on Linux).

Zarko Mocnik zarko.mocnik@dem.si
     Sorting for Slovenian language and the cset.tar.gz module that makes it easier to add other character sets.

"TAMITO" tommy@valley.ne.jp
     The _MB character set macros and the ujis and sjis character sets.

Yves Carlier Yves.Carlier@rug.ac.be
     mysqlaccess, a program to show the access rights for a user.

Rhys Jones rhys@wales.com (And GWE Technologies Limited)
     For the JDBC, a module to extract data from MySQL with a Java client.

Dr Xiaokun Kelvin ZHU X.Zhu@brad.ac.uk
     Further development of the JDBC driver and other MySQL-related Java tools.

James Cooper pixel@organic.com
     For setting up a searchable mailing list archive at his site.

Rick Mehalick Rick_Mehalick@i-o.com
     For xmysql, a graphical X client for MySQL.

Doug Sisk sisk@wix.com
     For providing RPM packages of MySQL for RedHat Linux.

Diemand Alexander V. axeld@vial.ethz.ch
     For providing RPM packages of MySQL for RedHat Linux-Alpha.

Antoni Pamies Olive toni@readysoft.es
     For providing RPM versions of a lot of MySQL clients for Intel and SPARC.

Jay Bloodworth jay@pathways.sde.state.sc.us
     For providing RPM versions for MySQL 3.21 versions.

Jochen Wiedmann wiedmann@neckar-alb.de
     For maintaining the Perl DBD::mysql module.

Therrien Gilbert gilbert@ican.net, Jean-Marc Pouyot jmp@scalaire.fr
     French error messages.

Petr snajdr, snajdr@pvt.net
     Czech error messages.

Jaroslaw Lewandowski jotel@itnet.com.pl
     Polish error messages.

Miguel Angel Fernandez Roiz
     Spanish error messages.

Roy-Magne Mo rmo@www.hivolda.no
     Norwegian error messages and testing of 3.21.#.

Timur I. Bakeyev root@timur.tatarstan.ru
     Russian error messages.

brenno@dewinter.com && Filippo Grassilli phil@hyppo.com
     Italian error messages.

Dirk Munzinger dirk@trinity.saar.de
     German error messages.

Billik Stefan billik@sun.uniag.sk
     Slovak error messages.

Stefan Saroiu tzoompy@cs.washington.edu
     Romanian error messages.

Peter Feher
     Hungarian error messages

David Sacerdote davids@secnet.com
     Ideas for secure checking of DNS hostnames.

Wei-Jou Chen jou@nematic.ieo.nctu.edu.tw
     Some support for Chinese(BIG5) characters.

Wei He hewei@mail.ied.ac.cn
     A lot of functionality for the Chinese(GBK) character set.

Zeev Suraski bourbon@netvision.net.il
     FROM_UNIXTIME() time formatting, ENCRYPT() functions, and bison advisor. Active mailing list member.

Luuk de Boer luuk@wxs.nl
     Ported (and extended) the benchmark suite to DBI/DBD. Have been of great help with crash-me and running benchmarks. Some new date functions. The mysql_setpermissions script.

Jay Flaherty fty@utk.edu
     Big parts of the Perl DBI/DBD section in the manual.

Paul Southworth pauls@etext.org, Ray Loyzaga yar@cs.su.oz.au
     Proof-reading of the Reference Manual.

Alexis Mikhailov root@medinf.chuvashia.su
     User definable functions (UDFs); CREATE FUNCTION and DROP FUNCTION.

Andreas F. Bobak bobak@relog.ch
     The AGGREGATE extension to UDF functions.

Ross Wakelin R.Wakelin@march.co.uk
     Help to set up InstallShield for MySQL-Win32.

Jethro Wright III jetman@li.net
     The libmysql.dll library.

James Pereria jpereira@iafrica.com
     Mysqlmanager, a Win32 GUI tool for administrating MySQL.

Curt Sampson cjs@portal.ca
     Porting of MIT-pthreads to NetBSD/Alpha and NetBSD 1.3/i386.

Sinisa Milivojevic sinisa@mysql.com
     Compression (with zlib) to the client/server protocol. Perfect hashing for the lexical analyzer phase.

Antony T. Curtis antony.curtis@olcs.net
     Porting of MySQL to OS/2.

Martin Ramsch m.ramsch@computer.org
     Examples in the MySQL Tutorial.

Tim Bunce
     Author of mysqlhotcopy.

Steve Harvey
     For making mysqlaccess more secure.

Jeremy Cole jeremy@spaceapes.com
     Proofreading and editing this fine manual.

Other contributors, bugfinders and testers: James H. Thompson, Maurizio Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar Haneke, jehamby@lightside, psmith@BayNetworks.COM, duane@connect.com.au, Ted Deppner ted@psyber.com, Mike Simons, Jaakko Hyvätti.

And lots of bug report/patches from the folks on the mailing list.

And a big tribute to those that help us answer questions on the mysql@lists.mysql.com mailing list:

Daniel Koch dkoch@amcity.com
     Irix setup.

Luuk de Boer luuk@wxs.nl
     Benchmark questions.

Tim Sailer tps@users.buoy.com
     DBD-mysql questions.

Boyd Lynn Gerber gerberb@zenez.com
     SCO related questions.

Richard Mehalick RM186061@shellus.com
     xmysql-related questions and basic installation questions.

Zeev Suraski bourbon@netvision.net.il
     Apache module configuration questions (log & auth), PHP-related questions, SQL syntax related questions and other general questions.

Francesc Guasch frankie@citel.upc.es
     General questions.

Jonathan J Smith jsmith@wtp.net
     Questions pertaining to OS-specifics with Linux, SQL syntax, and other things that might be needing some work.

David Sklar sklar@student.net
     Using MySQL from PHP and Perl.

Alistair MacDonald A.MacDonald@uel.ac.uk
     Not yet specified, but is flexible and can handle Linux and maybe HP-UX. Will try to get user to use mysqlbug.

John Lyon jlyon@imag.net
     Questions about installing MySQL on Linux systems, using either .rpm files, or compiling from source.

Lorvid Ltd. lorvid@WOLFENET.com
     Simple billing/license/support/copyright issues.

Patrick Sherrill patrick@coconet.com
     ODBC and VisualC++ interface questions.

Randy Harmon rjharmon@uptimecomputers.com
     DBD, Linux, some SQL syntax questions.

MySQL change history
********************

新しい変更を MySQL に施すと同時に、マニュアルを変更することに注意してください。もしマニュアルにかかれているのに MySQL download page (http://www.mysql.com/download.html) に新しいバージョンの MySQL が見つからない場合、そのバージョンはまだリリースされていません！

Changes in release 3.23.x (Released as alpha)
=============================================

リリース3.23、およびリリース3.22と3.21との違いは、 3.23が新しいISAMライブラリ( MyISAM )を含むということです。これは古いISAMより、SQLにとってよりチューニングされています。

3.23リリースは開発中で、機能は速いペースで付け加えられるでしょう。さしあたり、我々は、このリリースを、このリリースのみにある機能 (大ファイルのサポート、および、マシン非依存のテーブル)を必要としているユーザーに対してのみ、推薦します。 ( MySQL 3.23の全ての新しい機能は、広くテストされます。しかし、このリリースが多くの新型コードを含むので、すべてをテストすることが難しいです)。

We are not adding any more new features that are likely to break any old code in MySQL 3.23 so this version should stabilise pretty soon and will soon be declared beta, gamma and release.

Changes in release 3.23.18
--------------------------

  * Fixed a problem from 3.23.17 when choosing character set on the client side.

  * Added FLUSH TABLES WITH READ LOCK to make a global lock suitable to make a copy of MySQL data files.

  * CREATE TABLE  ... SELECT ... PROCEDURE now works.

  * Internal temporary tables will now uses compressed index when using GROUP BY on VARCHAR/CHAR columns.

  * Fixed a problem when locking the same table with both a READ and a WRITE lock.

  * Fixed problem with myisamchk and RAID tables.

Changes in release 3.23.17
--------------------------

  * Fixed a bug in find_in_set() when the first argument was NULL.

  * Added table locks to Berkeley DB.

  * Fixed a bug with LEFT JOIN and ORDER BY where the first table had only one matching row.

  * Added 4 sample my.cfg example files in the support-files directory.

  * Fixed duplicated key problem when doing big GROUP BY's. (This bug was probably introduced in 3.23.15).

  * Changed syntax for INNER JOIN to match ANSI SQL.

  * Added NATURAL JOIN syntax.

  * A lot of fixes in the BDB interface.

  * Added handling of --no-defaults and --defaults-file to safe_mysqld.sh and mysql_install_db.sh.

  * Fixed bug in reading compressed tables with many threads.

  * Fixed that USE INDEX works with PRIMARY keys.

  * Added BEGIN statement to start a transaction in AUTOCOMMIT mode.

  * Added symbolic links support for Win32.

  * Changed protocol to let client know if the server is in AUTOCOMMIT mode and if there is a pending transaction.  If there is a pending transaction the client library will give an error before reconnecting to the server to let the client know that the server did a rollback. The protocol is still backward compatible with old clients

  * KILL now works on a thread that is locked on a 'write' to a dead client.

  * Fixed memory leak in the  replication slave thread

  * Added new option log-slave-updates to allow daisy-chaining the slaves

  * Fixed compile error on FreeBSD and other systems where pthread_t is not the same as int

  * Fixed master shutdown aborting the slave thread

  * Fixed a race condition in INSERT DELAYED code when doing ALTER TABLE.

  * Added deadlock detection sanity checks to INSERT DELAYED

Changes in release 3.23.16
--------------------------

  * Added option TYPE=QUICK to CHECK and REPAIR.

  * Fixed bug in REPAIR TABLE when the table was in use by other threads.

  * Added a thread cache to make it possible to debug MySQL with gdb when one does a lot of reconnects. This will also improve systems where you can't use persistent connections.

  * Lots of fixes in the Berekely DB interface.

  * UPDATE IGNORE will not abort if an update results in a DUPLICATE_KEY error.

  * Put CREATE TEMPORARY TABLE commands in the update log.

  * Fixed bug in handling of masked IP numbers in the privilege tables.

  * Fixed bug with delayed_key_writes tables and CHECK TABLE.

  * Added replicate-do-db and replicate-ignore-db options to restrict which databases get replicated

  * Added SQL_LOG_BIN option

Changes in release 3.23.15
--------------------------

  * To start mysqld as root one must now use the --user=root option.

  * Added interface to Berkeley DB. (This is not yet functional;  Play with it at your own risk!)

  * Replication between master and slaves.

  * Fixed bug that other threads could steal a lock when a thread had a lock on a table and did a FLUSH TABLES command.

  * Added the slow_launch_time variable and the Slow_launch_threads status variable to mysqld.  These can be examined with mysqladmin variables and mysqladmin extended-status.

  * Added functions INET_NTOA() and INET_ATON().

  * The default type of IF() now depends on the second and third arguments and not only on the second argument.

  * Fixed case when myisamchk could go into a loop when trying to repair a crashed table.

  * Don't write INSERT DELAYED to update log if SQL_LOG_UPDATE=0.

  * Fixed problem with REPLACE on HEAP tables.

  * Added possible character sets and time zone to SHOW VARIABLES.

  * Fixed bug in locking code that could result it locking problems with concurrent inserts under high load.

  * Fixed a problem with DELETE of many rows on a table with compressed keys where MySQL scanned the index to find the rows.

  * Fixed problem with CHECK on table with deleted keyblocks.

  * Fixed a bug in reconnect (at the client side) where it didn't free memory properly in some contexts.

  * Fixed problems in update log when using LAST_INSERT_ID() to update a table with an auto_increment key.

  * Added function NULLIF().

  * Fixed bug when using LOAD DATA INFILE on a table with BLOB/TEXT columns.

  * Optimised MyISAM to be faster when inserting keys in sorted order.

  * EXPLAIN SELECT.. now also prints out whether MySQL needs to create a temporary table or use file sorting when resolving the SELECT.

  * Added optimization to skip ORDER BY parts where the part is a constant expression in the WHERE part.  Indexes can now be used even if the ORDER BY doesn't match the index exactly, as long as all the not used index parts and all the extra ORDER BY columns are constants in the WHERE clause.  See MySQL indexes.

  * UPDATE and DELETE on a whole unique key in the WHERE part, is now faster than before.

  * Changed RAID_CHUNKSIZE to be in 1024 byte increments.

  * Fixed coredump in LOAD_FILE(NULL) - you have to be as stupid as Sasha to try this :-)

Changes in release 3.23.14
--------------------------

  * Fixed a bug in CONCAT() where one of the arguments was a function that returned a modified argument.

  * myisamchk の致命的なバグを修正した。 このバグはインデックスファイル中のヘッダーを、テーブルをチェックしているだけなのにもかかわらず、更新していた。 This confused the mysqld daemon if it updated the same table at the same time. Now the status in the index file is only updated if one uses --update-state.  With older myisamchk versions you shoul use --read-only when only checking tables, if there is the slightest chance that the mysqld server is working on the table at the same time!

  * Fixed that DROP TABLE is logged in the update log.

  * Fixed problem when searching on DECIMAL() key field where the column data contained leading zeros.

  * auto_increment が最初のキーでない場合の myisamchk のバグを修正。

  * Allow DATETIME in ISO8601 format: 2000-03-12T12:00:00

  * 動的キャラクタセット。  １個の mysqld バイナリで、多くの違うキャラクタセットを扱えるようになった。 (mysqld スタート時に指定できます).

  * REPAIR TABLE コマンドを追加。

  * mysql_thread_safe() C API 関数を追加。

  * UMASK_DIR 環境変数を追加。

  * CONNECTION_ID() 関数を追加

  * When using = on BLOB or VARCHAR BINARY keys, where only a part of the column was indexed, the whole column of the result row wasn't compared.

  * sjis キャラクターセットの ORDER BY の問題を修正

  * When running in ANSI mode, don't allow columns to be used that aren't in the GROUP BY part.

Changes in release 3.23.13
--------------------------

  * Fixed problem when doing locks on the same table more than 2 times in the same LOCK TABLE command; This fixed the problem one got when running the test-ATIS test with --fast.

  * SQL_BUFFER_RESULT オプションを SELECT に追加

  * Removed end space from double/float numbers in results from temporary tables. CHECK TABLE コマンドの追加。

  * Added changes for MyISAM in 3.23.12 that didn't get into the source distribution because of CVS problems.

  * Fixed bug so that mysqladmin shutdown will wait for the local server to close down.

  * Fixed a possible endless loop when calculating timestamp.

  * Added print_defaults to the .rpm files. Removed mysqlbug from the client rpm file.

Changes in release 3.23.12
--------------------------

  * Fixed bug in MyISAM involving REPLACE ... SELECT which could give a corrupted table.

  * Fixed bug in myisamchk where it wrongly reset the auto_increment value.

  * Linux Alpha 用に多くのパッチを追加. MySQL now appears to be relatively stable on Alpha.

  * 重複したレコードを速く見つけるためのハッシュ化されたキーを使用するために、 HEAP 一時テーブル上の DISTINCT を変更した。 This mostly concerns queries of type SELECT DISTINCT ... GROUP BY ...  This fixes a problem where not all duplicates were removed in queries of the above type. 新しく追加したコードは、とても速い。

  * MacOS X で MySQL をコンパイルできるようになるパッチの追加

  * オプション IF NOT EXISTS を CREATE DATABASE に追加.

  * 多くのデータベースを同時にダンプできるように、 --all-databases と --databases オプションを mysqldump に追加。

  * MyISAM 型テーブル中の圧縮した DECIMAL() インデックスのバグを修正した。

  * 0 を timestamp に保存したときのバグを修正した。

  * ローカルの接続で mysqladmin shutdown を実行した場合に、mysqladmin は終了前に pidfile が無くなるまで待つようになった。

  * いくつかの COUNT(DISTINCT ...) クエリでコアを吐いたのを修正した。

  * Fixed that myisamchk works properly with RAID:ed tables.

  * Fixed problem with LEFT JOIN and key_field IS NULL.

  * Fixed bug in net_clear() which could give the error Aborted connection in the MySQL clients.

  * Added options USE INDEX (key_list) and IGNORE INDEX (key_list) as join parameters in SELECT.

  * DELETE and RENAME should now work on RAID tables.

Changes in release 3.23.11
--------------------------

  * ALTER TABLEL tbl_name ADD (field_list) 文を許可した。

  * Fixed problem with optimizer that could sometimes use wrong keys.

  * GRANT/REVOKE ALL PRIVILEGES が GRANT OPTION に影響しなかったのを修正。

  * Removed extra ) from the output of SHOW GRANTS

  * Fixed problem when storing numbers in timestamps.

  * Fix problem with timezones that have half hour offsets.

  * CREATE 文での UNIQUE INDEX の使用を許可。

  * mysqlhotcopy - ローカルの MySQL データベースをバックアップするツール。 By Tim Bunce.

  * 新しい mysqlaccess. Thanks to Steve Harvey for this.

  * --i-am-a-dummy と --safe-updates オプションを mysql に追加。

  * select_limit と max_join_size 変数を mysql に追加。

  * SQL の変数を追加： SQL_MAX_JOIN_SIZE と SQL_SAFE_UPDATES.

  * Added READ LOCAL lock that doesn't lock the table for concurrent inserts. (This is used by mysqldump).

  * Changed that LOCK TABLES .. READ doesn't anymore allow concurrent inserts.

  * オプション --skip-delay-key-write を mysqld に追加。

  * Fixed security problem in the protocol regarding password checking.

  * _rowid can now be used as an alias for an integer type unique indexed column.

  * Added back blocking of SIGPIPE when compiling with --thread-safe-clients to make things safe for old clients.

Changes in release 3.23.10
--------------------------

  * Fixed bug in 3.23.9 where memory wasn't properly freed when doing LOCK TABLES.

Changes in release 3.23.9
-------------------------

  * Fixed problem that affected queries that did arithmetic on group functions.

  * Fixed problem with timestamps and INSERT DELAYED.

  * Fixed that date_column BETWEEN const_date AND const_date works.

  * Fixed problem when only changing a 0 to NULL in a table with BLOB/TEXT columns.

  * Fixed bug in range optimizer when using many key parts and or on the middle key parts:  WHERE K1=1 and K3=2 and (K2=2 and K4=4 or K2=3 and K4=5)

  * source コマンドを mysql に追加。 これは mysql クライアント内で、バッチファイルを読むことができる。 Original patch by Matthew Vanecek.

  * WITH GRANT OPTION オプションの致命的なバグを修正

  * Don't give an unnecessary GRANT error when using tables from many databases in the same query.

  * Added VIO wrapper (needed for SSL support ; By Andrei Errapart and Tnu Samuel).

  * Fixed optimizer problem on SELECT when using many overlapping indexes. MySQL should now be able to choose keys even better when there is many keys to choose from.

  * Changed optimizer to prefer a range key instead of a ref key when the range key can uses more columns than the ref key (which only can use columns with =).  For example, the following type of queries should now be faster: SELECT * from key_part_1=const and key_part_2 > const2

  * Fixed bug that a change of all VARCHAR columns to CHAR columns didn't change row type from dynamic to fixed.

  * Disabled floating point exceptions for FreeBSD to fix core dump when doing SELECT floor(pow(2,63)).

  * mysqld の起動オプション --delay-key-write を --delay-key-write-for-all-tables に変更

  * Added read-next-on-key to HEAP tables.  This should fix all problems with HEAP tables when using not UNIQUE keys.

  * 変数のデフォルトを表示するオプションをクライアントに追加

  * mysqld に --log-slow-queries を追加。 これは時間のかかった全てのクエリを別のログファイルに記録する。どのくらい時間がかかったかが記される

  * WHERE key_column=RAND(...) を行ったときコアを吐くバグを修正

  * Fixed optimization bug in SELECT .. LEFT JOIN ... key_column IS NULL, when key_column could contain NULL values.

  * Fixed problem with 8-bit characters as separators in LOAD DATA INFILE.

Changes in release 3.23.8
-------------------------

  * 8G より大きなインデックスファイルを扱った場合の問題を修正。

  * NetBSD 用の最新の mit-pthread のパッチを追加。

  * タイムゾーン < GMT - 11 の場合の問題を修正。

  * NISAM 中のパックされたキーの削除時のバグを修正。

  * いくつか ORDER BY ... DESC クエリを実行した際の ISAM の問題を修正。

  * Fixed bug when doing a join on a text key which didn't covert the whole key.

  * オプション --delay-key-write が delayed key writing を有効にしていなかったのを修正。

  * Fixed update of TEXT column which only involved case changes.

  * Fixed that INSERT DELAYED doesn't update timestamps that are given.

  * YEARWEEK() 関数の追加と、x, X, v, V オプションの DATE_FORMAT() への追加。

  * Fixed problem with MAX(indexed_column) and HEAP tables.

  * Fixed problem with BLOB NULL keys and LIKE "prefix%".

  * Fixed problem with MyISAM and fixed length rows < 5 bytes.

  * Fixed problem that could cause MySQL to touch freed memory when doing very complicated GROUP BY queries.

  * Fixed core dump if you got a crashed table where an ENUM field value was too big.

Changes in release 3.23.7
-------------------------

  * Linux環境下において、pthread_mutex_timedwait の問題を避けるようにした。この関数は INSERT DELAYED で使用されていた。 See Linux.

  * Fixed that one will get at 'disk full' error message if one gets disk full when doing sorting (instead of waiting until we got more disk space).

  * MyISAM で、キーが 250 文字を超えた場合のバグを修正。

  * MyISAM において、他のスレッドが読んでいるテーブルに対し、他のスレッドが INSERT を同時に行うことができるようになった。

  * Added variable max_write_lock_count to mysqld to force a READ lock after a certain number of WRITE locks.

  * Inverted flag delayed_key_write on show variables.

  * concurrency 変数を thread_concurrency に改名。

  * 以下の関数がマルチバイト・セーフになった： LOCATE(substr,str), POSITION(substr IN str), LOCATE(substr,str,pos), INSTR(str,substr), LEFT(str,len), RIGHT(str,len), SUBSTRING(str,pos,len), SUBSTRING(str FROM pos FOR len), MID(str,pos,len), SUBSTRING(str,pos), SUBSTRING(str FROM pos), SUBSTRING_INDEX(str,delim,count), RTRIM(str), TRIM([[BOTH | TRAILING] [remstr] FROM] str), REPLACE(str,from_str,to_str), REVERSE(str), INSERT(str,pos,len,newstr), LCASE(str), LOWER(str), UCASE(str) and UPPER(str);  Patch by Wei He.

  * Fix core dump when releasing a lock from a non-existant table.

  * Remove locks on tables before starting to remove duplicates.

  * FULL オプションを SHOW PROCESSLIST に追加。

  * --verbose オプションを mysqladmin に追加。

  * HEAP の MyISAM への自動変換時のバグを修正。

  * HEAP テーブルに対して、insert + delete + insert + scan table を行った際のバグを修正。

  * Alpha プラットフォーム上での、REPLACE() と LOAD DATA INFILE のバグを修正。

  * mysqld 変数に interactive_timeout を追加.

  * mysql_data_seek() の引数を ulong から ulonglong に変更.

Changes in release 3.23.6
-------------------------

  * mysqld に -O lower_case_table_names={0|1} オプションを追加。これはテーブル名を強制的に小文字にします。

  * SELECT ... INTO DUMPFILE 追加。

  * mysqld に --ansi オプションを追加。 これはいくつかの関数を ANSI SQL 互換にします。

  * Temporary tables now starts with #sql.

  * Added quoting of identifiers with ` (" in --ansi mode).

  * Changed to use snprintf() when printing floats to avoid some buffer overflows on FreeBSD.

  * FreeBSD 上で、floor() をオーバーフローセーフにした。

  * --quote-names オプションを mysqldump に追加

  * Fixed bug that one could make a part of a PRIMARY KEY NOT NULL.

  * Fixed encrypt() to be thread safe and not reuse buffer.

  * MyODBC の mysql_odbc_escape_string() 関数が、big5 をサポートした。

  * Rewrote the table handler to use classes.  This introduces a lot of new code, but will make table handling faster and better.

  * ユーザー定義変数のパッチ(Sashaによる)を追加。

  * Changed that FLOAT and DOUBLE (without any length modifiers) are not anymore fixed decimal point numbers.

  * FLOAT(X) の意味を変更: X <=24 ならば、これは FLOAT と同じで、 24 < X <= 53 であるならば DOUBLE と同じになります。

  * DECIMAL(X) は DECIMAL(X,0) のエイリアスになりました。また DECIMAL は DECIMAL(10,0) のエイリアスになりました。 The same goes for NUMERIC.

  * ROW_FORMAT={default | dynamic | static | compressed} オプションを CREATE_TABLE に追加.

  * DELETE FROM table_name が一時テーブルで動かなかった。

  * CHAR_LENGTH() 関数をマルチバイトセーフに変更

  * ORD(string) 関数の追加.

Changes in release 3.23.5
-------------------------

  * 新しいデータハンドリング中のいくつかの Y2K 問題を修正。

  * SELECT DISTINCT ... ORDER BY RAND() の問題を修正。

  * Sergei A. Golubchik による MyISAM のレベルでのテキストサーチのパッチを追加

  * キー無しでfull JOIN を使用した際のキャッシュオーバーフローの問題を修正。

  * いくつかの configure の問題を修正。

  * Some small changes to make parsing faster.

  * ALTER TABLE + adding a column after the last field didn't work.

  * 2つのキー中でauto_incrementフィールドを使用したときの問題を修正。

  * MyISAM で auto_increment をサブパートとして使用できるようになった： CREATE TABLE foo (a int not null auto_increment, b char(5), primary key (b,a))

  * Fixed bug in MyISAM with packed char keys that could be NULL.

  * フィールド名を CREATE TABLE table_name SELECT ...  時にとした場合、動かなかった。

  * Allow use of NATIONAL and NCHAR when defining character columns. This is the same as not using BINARY.

  * NULL のフィールドを PRIMARY KEY ( UNIQUE キー) には許さなくなった。

  * Clear LAST_INSERT_ID if one uses this in ODBC: WHERE auto_increment_column IS NULL.  This seems to fix some problems

  * WHERE auto_increment_column IS NULL を使用して最後にレコードが挿入された後に、 SET SQL_AUTO_IS_NULL=0|1 はサーチのハンドリングの on/off になった。

  * Added new mysqld variable concurrency for Solaris.

  * --relative オプションを mysqladmin に追加。これは extended-status で変更のモニターをする場合、より便利になった。

  * 空のテーブルに対して COUNT(DISTINCT..) を使用した際のバグを修正。

  * 中国語のキャラクターセット GBK を追加。

  * LOAD DATA INFILE を BLOB フィールドに使用した際の問題を修正。

  * 論理演算子 ~ (negation) を追加。

  * UDF 関数での問題を修正。

Changes in release 3.23.4
-------------------------

  * DATETIME 型を TIME フィールドに挿入するとき、'day' を保存しようと試みなくなった。

  * low endian のマシンで float/double の保存の問題を修正。 (これは SUM() に影響する.)

  * TCP/IP 接続の connect timeout を追加。

  * インデックス上で、 NULL 値を持つかもしれないものに LIKE "%" した際の問題を修正。

  * REVOKE ALL PRIVILEGES が全ての権限を取り消していなかったのを修正。

  * オリジナルのテーブル名と同じ名前で一時テーブルを作れるようにした。

  * データベースへの権限をあるユーザーに与えた際、そのユーザーは他のユーザーに権限を与えることが出来なかった。

  * 新コマンド： SHOW GRANTS FOR user (by Sinisa).

  * 新 date_add syntax:  date/datetime + INTERVAL # interval_type. By Joshua Chamas.

  * LOAD DATA REPLACE の権限のチェックを修正。

  * Solaris 2.7 上での、壊れた include ファイルを自動修正。

  * big file system を検出する際のいくつかの configure の問題を修正。

  * REGEXP はケース非依存になった。もしバイナリ文字でない場合は。

Changes in release 3.23.3
-------------------------

  * NetBSD 上での MIT-pthreads パッチを追加。

  * MyISAM 中の range bug を修正。

  * ORDER BY のデフォルトが再び ASC になった。

  * LIMIT を UPDATE に追加。

  * 新クライアント関数： mysql_change_user().

  * SHOW VARIABLES にキャラクターセットを追加。

  * --[whitespace] コメントをサポートした。

  * Allow INSERT into tbl_name VALUES (), that is, you may now specify an empty value list to insert a row in which each column is set to its default value.

  * Changed SUBSTRING(text FROM pos) to conform to ANSI SQL. (Before this construct returned the rightmost 'pos' characters).

  * いくつかのシステム上で GROUP BY をともなった SUM(..) は 0 を返すようになった。

  * SHOW TABLE STATUS の出力を変更。

  * DELAY_KEY_WRITE オプションを CREATE TABLE に追加。

  * AUTO_INCREMENT をいかなるキーの部分に使用できるようにした。

  * YEAR(NOW()) , YEAR(CURDATE()) の問題を修正。

  * Added CASE construct.

  * 新刊数 COALESCE().

Changes in release 3.23.2
-------------------------

  * Fixed range optimizer bug: SELECT * FROM table_name WHERE key_part1 >= const AND (key_part2 = const OR key_part2 = const).  The bug was that some rows could be duplicated in the result.

  * Running myisamchk without -a updated the index distribution wrong.

  * SET SQL_LOW_PRIORITY_UPDATES=1 gave parse error before.

  * WHERE 節に使用されているインデックスフィールドを更新できるようになった： UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100

  * Date handling should now be a bit faster.

  * Added handling of fuzzy dates (dates where day or month is 0): (Like: 1999-01-00)

  * Fixed optimization of SELECT ... WHERE key_part1=const1 AND key_part_2=const2 AND key_part1=const4 AND key_part2=const4 ; Indextype should be range instead of ref.

  * Linux Alpha 上で egcs 1.1.2 optimizer のバグ(BLOB 使用時)を修正。

  * Fixed problem with LOCK TABLES combined with DELETE FROM table.

  * MyISAM テーブルは NULL 値と BLOB/TEXT フィールドにキーを許すようになった。

  * 以下のJOINがより速くなった： SELECT ... FROM t1 LEFT JOIN t2 ON ... WHERE t2.not_null_column IS NULL.

  * ORDER BY and GROUP BY can be done on functions.

  * Changed handling of 'const_item' to allow handling of ORDER BY RAND().

  * WHERE key_column = function でインデックスが使用されるようになった。

  * 例えフィールドが全く同じにパックされていなくても、 WHERE key_column = column_name でインデックスが使用されるようになった。

  * WHERE column_name IS NULL でインデックスが使用されるようになった。

  * Changed heap tables to be stored in low_byte_first order (to make it easy to convert to MyISAM tables)

  * Automatic change of HEAP temporary tables to MyISAM tables in case of 'table is full' errors.

  * --init-file=file_name オプションを mysqld に追加。

  * COUNT(DISTINCT value,[value,...])

  * CREATE TEMPORARY TABLE now creates a temporary table, in its own namespace, that is automatically deleted if connection is dropped.

  * 新予約語 (CASE を要求):  CASE, THEN, WHEN, ELSE and END.

  * 新関数 EXPORT_SET() , MD5().

  * GB2312 中国語キャラクターセットをサポート。

Changes in release 3.23.1
-------------------------

  * いくつかのコンパイル問題を修正した。

Changes in release 3.23.0
-------------------------

  * 多くの新しい特徴を備えた新しいテーブル・ハンドラー・ライブラリ( MyISAM )。 See MyISAM.

  * メモリー内に HEAP テーブルを作成できるようになりました。これは探索がとても速いです。

  * 大容量ファイルをサポートしているOS上で、大ファイル (63 bit) のサポート。

  * 新しい関数 LOAD_FILE(filename) 。 これはファイルの中身を文字列値として読みます。

  * 新しい演算子 <=> 。 これは、 = のように振る舞いますが、もし両辺の引数が NULL なら、真を返します。これはテーブル間の変更の比較に役立ちます。

  * ODBC 3.0 EXTRACT(interval FROM datetime) 関数の追加。

  * FLOAT(X) フィールドは、保存した値を丸めません。これは検索されたときに 科学表記 (1.0 E+10) になるかもしれません。

  * REPLACE が前よりも速くなった。

  * LIKE 文字比較を = のよに振る舞うように変更；これは 'e' LIKE 'é' が真になるということです。

  * SHOW TABLE STATUS はテーブルについての情報を多く出すようになりました。

  * LIKE を SHOW STATUS コマンドに追加。

  * SHOW COLUMNS に Privileges 項目を追加。

  * SHOW INDEX に packed と comment 項目を追加。

  * テーブルへのコメントを追加。 ( CREATE TABLE ... COMMENT "xxx").

  * UNIQUE を次のように追加： CREATE TABLE table_name (col int not null UNIQUE)

  * 新 create 構文： CREATE TABLE table_name SELECT ....

  * 新 create 構文： CREATE TABLE IF NOT EXISTS ...

  * CHAR(0) フィールドの作成を許可した。

  * DATE_FORMAT() は、フォーマット文字の前に % が必要になった。

  * DELAYED が予約語になった。 (sorry about that :( ).

  * プロセジャーの例を追加： analyse, file: sql_analyse.c. これはクエリのデータについて説明します。 以下の様にしてみてください：

          SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])

     この プロセジャーは、テーブルのデータをチェックしたい時に、とても役立ちます！

  * BINARY cast to force a string to be compared case sensitively.

  * --skip-show-database オプションを mysqld に追加。

  * BLOB/TEXT フィールドにおいて、 UPDATE されたレコードをチェックできるようになりました。

  * INNER JOIN の追加。  注意: INNER は予約語になりました！

  * MySQL テーブルのホストにネットマスクをサポートした。 IP/NETMASK として、ネットマスクを指定できます。

  * If you compare a NOT NULL DATE/DATETIME column with IS NULL, this is changed to a compare against 0 to satisfy some ODBC applications.  (By shreeve@uci.edu).

  * NULL IN (...) は 0 ではなく NULL を返します。 これは null_column NOT IN (...) が NULL 値にマッチしないのを確実にします。

  * TIME フィールド中に、浮動小数点の値を入れるのを修正。

  * Changed parsing of TIME strings to be more strict.  Now the fractional second part is detected (and currently skipped). The following formats are supported:

     [[DAYS] [H]H:]MM:]SS[.fraction]

     [[[[[H]H]H]H]MM]SS[.fraction]

  * Detect (and ignore) second fraction part from DATETIME.

  * LOW_PRIORITY 属性を LOAD DATA INFILE に追加。

  * デフォルトのインデックス名を、フィールドの名前と同じケースにした。

  * デフォルトの接続数を 100 に変更。

  * LOAD DATA INFILE 時に、より大きなバッファを使用するようにした。

  * DECIMAL(x,y) は ANSI SQL に従って動作するようになった。

  * Added aggregate UDF functions. Thanks to Andreas F. Bobak bobak@relog.ch for this!

  * LAST_INSERT_ID() is now updated for INSERT INTO ... SELECT.

  * Some small changes to the join table optimizer to make some joins faster.

  * SELECT DISTINCT が凄く速くなった；これは MyISAM の新しい UNIQUE を使用します。 MySQL 3.22 と一つ違う点は、 DISTINCT の出力がソートされないという事です。

  * 全ての C クライアント API が、共有ライブラリを柔軟に作成するため、マクロから関数になりました。 このため、 mysql_num_fields() を MYSQL ととしてコールできず、この代わりに mysql_field_count() を使用しなくてはなりません。

  * LIBWRAP の追加;  Patch by Henning P . Schmiedehausen.

  * Don't allow AUTO_INCREMENT for other than numerical columns.

  * AUTO_INCREMENT の使用は、フィールドを自動的に NOT NULL にします。

  * Show NULL as the default value for AUTO_INCREMENT columns.

  * SQL_BIG_RESULT の追加;  SQL_SMALL_RESULT がデフォルトになりました。

  * Added a shared library RPM. This enchancement was contributed by David Fox (dsfox@cogsci.ucsd.edu).

  * --enable-large-files/--disable-large-files スイッチを configure に追加。 See configure.in for some systems where this is automatically turned off because of broken implementations.

  * readline 4.0 にアップグレード

  * 新しい CREATE TABLE オプション： PACK_KEYS と CHECKSUM.

  * mysqld オプションに --default-table-type を追加。

Changes in release 3.22.x
=========================

3.22 はより早く、より安全なコードをもち、たくさんの新しい機能が盛り込まれています。これらの変更を 3.21 に行わないのは、3.21 の安定度を保つためにはとても多くの変更が必要とされるからです。これらの変更はメジャーバージョンの変更ではないので、簡単に障害もなく 3.22 にアップグレードができます。 See Upgrading-from-3.21.

3.22 は新しい DBD-mysql (1.20xx) ドライバーのみを新しい接続プロトコルに対して使用します！

Changes in release 3.22.35
--------------------------

  * Fixed problem with STD().

  * Merged changes from the newest ISAM library from 3.23.

  * Fixed problem with INSERT DELAYED.

  * Fixed a bug core dump when using a LEFT JOIN/STRAIGHT_JOIN on a table with only one row.

Changes in release 3.22.34
--------------------------

  * Fixed problem with GROUP BY on TINYBLOB columns;  This caused bugzilla to not show rows in some queries.

  * Had to do total recompile of the Windows binary version as VC++ didn't compile all relevant files for 3.22.33 :(

Changes in release 3.22.33
--------------------------

  * Fixed problems in windows when locking tables with LOCK TABLE

  * Quicker kill of SELECT DISTINCT queries.

Changes in release 3.22.32
--------------------------

  * 数値を timestamps に保存する際の問題を修正した。

  * Fix problem with timezones that have half hour offsets.

  * mysqlhotcopy - ローカルの MySQL データベースをコピーするツール. By Tim Bunce.

  * mysqlaccess が新しくなった. Thanks to Steve Harvey for this.

  * Fixed security problem in the protocol regarding password checking.

  * Fixed problem that affected queries that did arithmetic on GROUP functions.

  * Fixed a bug in the ISAM code when deleting rows on tables with packed indexes.

Changes in release 3.22.31
--------------------------

  * Win32 でのいくつかの小さなバグ修正

Changes in release 3.22.30
--------------------------

  * Fixed optimizer problem on SELECT when using many overlapping indexes.

  * Disabled floating point exceptions for FreeBSD to fix core dump when doing SELECT floor(pow(2,63)).

  * Added print of default arguments options to all clients.

  * WITH GRANT OPTION オプションの致命的なバグを修正.

  * Fixed non-critical Y2K problem when writing short date to log files.

Changes in release 3.22.29
--------------------------

  * Upgraded the configure and include files to match the latest 3.23 version. This should increase portability and make it easier to build shared libraries.

  * NetBSD 用の最新の mit-pthread のパッチを追加。

  * タイムゾーン < GMT - 11 の場合の問題を修正。

  * NISAM 中のパックされたキーの削除時のバグを修正。

  * Fixed problem that could cause MySQL to touch freed memory when doing very complicated GROUP BY queries.

  * Fixed core dump if you got a crashed table where an ENUM field value was too big.

  * Added mysqlshutdown.exe and mysqlwatch.exe to the Windows distribution.

  * キーに対して ORDER BY を行ったときの問題を修正

  * Fixed that INSERT DELAYED doesn't update timestamps that are given.

Changes in release 3.22.28
--------------------------

  * Fixed problem with LEFT JOIN and COUNT() on a column which was declared NULL + and it had a DEFAULT value.

  * CONCAT() をある WHERE 節で使用した際にコア・ダンプする問題を修正した。

  * Fixed problem with AVG() and STD() with NULL values.

Changes in release 3.22.27
--------------------------

  * my_ctype.h 中の、他のキャラクターセットのプロトタイプを修正。

  * configure 中の、大ファイルシステムを検出する部分の問題を修正。

  * 大きなBLOBフィールドをソートしたときのバグを修正。

  * ROUND() will now work on Win32.

Changes in release 3.22.26
--------------------------

  * 空の BLOB/TEXT フィールドを REVERSE() した際にコアダンプしたのを修正。

  * /*! */ バージョン番号 を拡張した

  * Changed SUBSTRING(text FROM pos) to conform to ANSI SQL. (Before this construct returned the rightmost 'pos' characters).

  * Fixed problem with LOCK TABLES combined with DELETE FROM table

  * INSERT ... SELECT が SQL_BIG_TABLES を使用していなかったのを修正。

  * SET SQL_LOW_PRIORITY_UPDATES=# が動いてなかった。

  * 許可を GRANT ... IDENTIFIED BY で変更しても直にパスワードが反映されなかったのを修正。

  * 以下の最適化のバグを修正： SELECT * FROM table_name WHERE key_part1 >= const AND (key_part2 = const OR key_part2 = const)

  * Fixed bug in compression key handling in ISAM.

Changes in release 3.22.25
--------------------------

  * インストール時の小さな問題を修正。

Changes in release 3.22.24
--------------------------

  * DATA は予約語でなくなった。

  * たった１レコードしかないテーブルの最適化のバグを修正。

  * LOCK TABLES table_name READ; FLUSH TABLES; を使用した際のバグ修正。

  * HP-UX のパッチを適用。

  * isamchk が Win32 上で動くようになった。

  * Changed configure to not use big file handling on Linux as this crashes some RedHat 6.0 systems

Changes in release 3.22.23
--------------------------

  * Autoconf 2.13, Automake 1.4, libtool 1.3.2 を使用するようにアップグレード。

  * Better support for SCO in configure.

  * Added option --defaults-file=### to option file handling to force use of only one specific option file.

  * MySQL 3.23 のキーワードを無視するように CREATE 構文を拡張した。

  * LOCK TABLES でロックされているテーブルに INSERT DELAYED を使用した際の、デッドロックの問題を修正。

  * 他のスレッドにロックされているテーブルに DROP TABLE を使用した際の問題を修正。

  * GRANT/REVOKE コマンドを update log に追加。

  * 新しいエラー項目を検出するように isamchk を修正。

  * NATURAL LEFT JOIN のバグを修正。

Changes in release 3.22.22
--------------------------

  * mysql_init() の後に直接 mysql_close() を読んだときの問題を修正。 (C API)

  * Better client error message when you can't open socket.

  * 新しいdelayed_insert スレッドが作成できなかったときの delayed_insert_thread 数の表示を修正。

  * CONCAT() の引数を多くした場合のバグを修正。

  * DEC 3.2 と SCO のパッチの追加。

  * NT のサービスとして MySQL をインストールした際のパスの問題を修正。

  * MySQL-Win32 は VC++ 6.0 でコンパイルされるようになった。 (VC++ 5.0 のかわりに)

  * MySQL-Win32 の新しいインストーラー

Changes in release 3.22.21
--------------------------

  * テーブルが他のスレッドにロックされたときの、DELETE FROM TABLE の問題を修正。

  * Fixed bug in LEFT JOIN involving empty tables.

  * mysql.db フィールドを char(32) から char(60) に変更。

  * MODIFY と DELAYED は予約語でなくなった。

  * TIME フィールドに日にちを入れようとしたときのバグを修正。

  * GRANT コマンドで新しい MySQL ユーザーを登録した後に Host '..' is not allowed to connect to this MySQL server となる問題を修正。

  * Linux 上で TCP_NODELAY を使用するように変更。 (これは TCP/IP 接続を速くします)

Changes in release 3.22.20
--------------------------

  * Fixed STD() for big tables when result should be 0.

  * いくつかのOS でupdate log が改行を入れていなかったのを修正。

  * INSERT DELAYED had some garbage at end in the update log.

Changes in release 3.22.19
--------------------------

  * mysql_install_db のバグ修正。 (from 3.22.17).

  * デフォルトのキーキャッシュを 8M に変更。

  * BLOB フィールドで一時テーブルが必要とされるクエリの問題を修正。

Changes in release 3.22.18
--------------------------

  * Linux上で、3.22.17の致命的な問題の修正； shutdown 後、全てのスレッドが確実に死ななかった。

  * -O flush-time=# オプションを mysqld に追加。 This is mostly useful on Win32 and tells how often MySQL should close all unused tables and flush all updated tables to disk.

  * VARCHAR フィールドと  CHAR を比較した際にキーを効果的に使用していなかったのを修正。

Changes in release 3.22.17
--------------------------

  * --log-update を使用したときとデフォルトのデータベースを指定しないで接続したときのコアダンプを修正した。

  * いくつかの configure と移植性の問題を修正した。

  * Using LEFT JOIN on tables that had circular dependencies caused mysqld to hang forever.

Changes in release 3.22.16
--------------------------

  * mysqladmin processlist could kill the server if a new user logged in.

  * DELETE FROM table_name WHERE key_column=column_name がマッチする行を1行も見つけれないのを修正

  * DATE_ADD(column,...) が動かないのを修正

  * INSERT DELAYED could deadlock with status 'upgrading lock'

  * 2文字以上のソルトが使用できるように、ENCRYPT() を拡張。

  * longlong2str は以前よりかなり速くなった。Intel x86 用にこのコードは最適化されたアセンブラで書き直した

  * ALTER TABLE に MODIFY キーワードを追加

Changes in release 3.22.15
--------------------------

  * GRANT を IDENTIFIED BY と共に使用した際、権限情報がフラッシュされるまで有効にならない

  * Name change of some variables in SHOW STATUS.

  * Fixed problem with ORDER BY with 'only index' optimization when there were multiple key definitions for a used column.

  * DATE and DATETIME columns are now up to 5 times faster than before.

  * INSERT DELAYED can be used to let the client do other things while the server inserts rows into a table.

  * もし2つの違うデータベースのテーブルを使用した場合、 LEFT JOIN USING (col1,col2) が動作しなかった

  * LOAD DATA LOCAL INFILE がファイルがないための理由で UNIX では動作しなかった

  * とても短い行(<4バイト)しかない VARCHAR/BLOB での問題の修正； error 127 がこの行を消去する場合に起きる可能性があった

  * Updating BLOB/TEXT through formulas didn't work for short (< 256 char) strings.

  * 新しいホスト上で GRANT を実行した場合、そのホストからの最初のコネクションで mysqld が死ぬ可能性があった

  * エイリアス名と同じ項目名を ORDER BY で使用する場合のバグを修正 name as an alias.

  * Added BENCHMARK(loop_count,expression) function to time expressions.

Changes in release 3.22.14
--------------------------

  * シェルスクリプトからの起動のために、mysqld の引数がない場合を許可した。

  * Setting a TIMESTAMP column to NULL didn't record the timestamp value in the update log.

  * Fixed lock handler bug when one did INSERT INTO TABLE ... SELECT ... GROUP BY.

  * Added a patch for localtime_r() on Win32 so that it will not crash anymore if your date is > 2039, but instead will return a time of all zero.

  * Names for user-defined functions are no longer case sensitive.

  * Added escape of ^Z (ASCII 26) to \Z as ^Z doesn't work with pipes on Win32.

  * 将来の MySQL リリースのために、mysql_fix_privileges は、 UDF のサポートのために、新しい項目を mysql.func に追加する。 ( type enum ('function','aggregate') NOT NULL が追加された )

Changes in release 3.22.13
--------------------------

  * Saving NOW(), CURDATE() or CURTIME() directly in a column didn't work.

  * WHERE 節が無い場合、SELECT COUNT(*) ... LEFT JOIN ... が動かなかった

  * UnixWare 7.0.x で MySQL をコンフィグできるように config.guess を更新 UnixWare 7.0.x.

  * Changed the implementation of pthread_cond() on the Win32 version. get_lock() now correctly times out on Win32!

Changes in release 3.22.12
--------------------------

  * WHERE 節で DATE_ADD() と DATE_SUB() を使用した際の問題を修正

  * GRANT ... TO user IDENTIFIED BY 'password' 構文でパスワードをセットできるようにした

  * 多くのテーブルを SELECT して GRANT を確認する際のバグを修正

  * RPM 配布での mysql_fix_privilege_tables ファイルの追加。これはクライアントパッケージに含んだため、デフォルトでは起動されない。

  * SQL_SMALL_RESULT オプションを SELECT に追加。これは強制的に速い一時テーブルを使用する。結果が小さいとわかっている場合に使用すると有効。

  * 小数点をつけなくても実数が使用できるようにした

  * DATE_ADD/DATE_SUB() の結果、十分な日数を得られない場合、日数を月の最大日にするようにした。

  * GRANT がカラムをケース非依存で比較していたのを修正

  * ある構文の組み合わせで ALTER TABLE が core をはくバグが sql_list.h にあったのでこれを修正

  * The hostname in user@hostname can now include . and - without quotes in the context of the GRANT, REVOKE and SET PASSWORD FOR ... statements.

  * 大きな一時ファイルを必要とするテーブルへの isamchk を修正

Changes in release 3.22.11
--------------------------

  * 重要: 3.22.11にアップグレードする場合、必ず mysql_fix_privilege_tables スクリプトを実行しなくてはなりません！これは新しい GRANT システムのために実行します。もしこれを行わなければ、ALTER TABLE や CREATE INDEX, DROP INDEX を実行しようとすると Access denied になります。

  * テーブル、カラムごとにユーザーのアクセスに対して許可や拒否を設定できます

  * USER() を user@host を返すように変更

  * 他のユーザーの PASSWORD をセットする構文を変更

  * 新コマンド：FLUSH STATUS はほとんどのステータス変数をゼロにセットします

  * 新ステータス変数： aborted_threads, aborted_connects.

  * 新オプション： connection_timeout

  * ソートのサポート (by Pruet Boonma pruet@ds90.intanon.nectec.or.th).

  * スロバキア語と日本語のエラーメッセージ

  * Configuration and portability fixes.

  * Added option SET SQL_WARNINGS=1 to get a warning count also for simple inserts.

  * FreeBSD 上でシャットダウンするために、SIGQUIT のかわりに SIGTERM を使用します

  * mysql に オプション \G (print vertically) 追加

  * SELECT HIGH_PRIORITY ... killed mysqld.

  * IS NULL on a AUTO_INCREMENT column in a LEFT JOIN didn't work as expected.

  * New function MAKE_SET().

Changes in release 3.22.10
--------------------------

  * mysql_install_db は MySQL サーバーを起動しなくなりました! mysql_install_db を行った後に、safe_mysqld で mysqld を開始させる必要があります。しかし MySQL の RPM パッケージはサーバーをたちあげるようにしています。

  * --bootstrap を mysqld に追加。mysql_install_db はこれを使用します。この引数は RPM パッケージで  MySQL のインストールを簡略化します。

  * +, - (sign and minus), *, /, %, ABS() and MOD() のコードを修正。 BIGINTで使用した場合の危険性を回避しました(64 bit safe).

  * ALTER TABLE が mysqld をクラッシュさせるバグを修正。

  * 重複したキー結果を得た場合、MySQLは常にその旨を報告するようになりました。 (以前のバージョンでは、INSERT の時にしかメッセージが出ませんでした)

  * New syntax: INSERT INTO table_name SET column=value,column=value,...

  * .err ログファイルのログ記録に、time stamp をつけるようにしました。

  * MYSQL_INIT_COMMAND オプションを mysql_options() に追加。 (接続要求する場合に使用できる)

  * MYSQL_READ_DEFAULT_FILE と MYSQL_READ_DEFAULT_GROUP を mysql_options()に追加。 MySQL オプションファイルから以下のパラメーターを読み取る： port, socket, compress, password, pipe, timeout, user, init-command, host and database (訳注)オプションファイルのデフォルトは /etc/my.cnf , install_directory/share/mysql/my.cnf

  * UDF 構文に maybe_null を追加

  * Added option IGNORE to INSERT statemants with many rows.

  * koi8 キャラクターをソートする場合の問題を修正。 koi8を使用しているユーザーは、CHAR や VARCHAR カラムをインデックスにしているテーブルに対して、必ず isamchk -rq を実行すること。

  * 新規スクリプト mysql_setpermission (Luuk de Boer 作) これは指定されたデータベースに対してアクセスを許可するユーザーを簡単に登録してくれます。

  * Allow use of hexadecimal strings (0x...) when specifying a constant string (like in the column separators with LOAD DATA INFILE).

  * OS/2 に移植 (thanks to Antony T. Curtis antony.curtis@olcs.net).

  * SHOW STATUS での変数を増やしました。また、SHOW VARIABLES のような出力フォーマットに変更しました。

  * extended-status コマンドを mysqladmin に追加。これは新しいステイタス変数を表示します

Changes in release 3.22.9
-------------------------

  * SET SQL_LOG_UPDATE=0 caused a lockup of the server.

  * New SQL command:  FLUSH [ TABLES | HOSTS | LOGS | PRIVILEGES ] [, ...]

  * New SQL command:  KILL thread_id .

  * AIX, DEC OSF1 4.x で MySQL を簡単にコンパイルできるように include ファイルを変更。

  * ALTER TABLE を使用して INT からサイズの小さい CHAR() に変更する場合におきていた不具合を修正。

  * SELECT HIGH_PRIORITY 追加。 SELECT において、たとえ他の SELECT を待っているスレッドがあったとしても、 WRITE LOCK することができます。

  * Moved wild_compare to string class to be able to use LIKE on BLOB/TEXT columns with \0.

  * Added ESCAPE option to LIKE

  * mysqladmin debug において、より多くの出力が得られるようにした。

  * Win32 において、--flush オプションをつけて mysqld を起動できるようになりました。これはアップデートが終わった後ですべてのテーブルをディスクにフラッシュします。このオプションにより NT/Win98 上ですごく安全に動かすことができますが、とても 遅くなります。

Changes in release 3.22.8
-------------------------

  * Czech character sets should now work much better.  You must also install ftp://www.mysql.com/pub/mysql/Downloads/Patches/czech-3.22.8-patch. This patch should also be installed if you are using a character set with uses my_strcoll()!  The patch should always be safe to install (for any system), but as this patch changes ISAM internals it's not yet in the default distribution.

  * DATE_ADD() and DATE_SUB() didn't work with group functions.

  * mysql will now also try to reconnect on USE DATABASE commands.

  * Fix problem with ORDER BY and LEFT JOIN and const tables.

  * Fixed problem with ORDER BY if the first ORDER BY column was a key and the rest of the ORDER BY columns wasn't part of the key.

  * Fixed a big problem with OPTIMIZE TABLE.

  * MySQL clients on NT will now by default first try to connect with named pipes and after this with TCP/IP.

  * Fixed a problem with DROP TABLE and mysqladmin shutdown on Win32 (a fatal bug from 3.22.6).

  * Fixed problems with TIME columns and negative strings.

  * Added an extra thread signal loop on shutdown to avoid some error messages from the client.

  * MySQL now uses the next available number as extension for the update log file.

  * Added patches for UNIXWARE 7.

Changes in release 3.22.7
-------------------------

  * Added LIMIT clause for the DELETE statement.

  * You can now use the /*! ... */ syntax to hide MySQL-specific keywords when you write portable code.  MySQL will parse the code inside the comments as if the surrounding /*! and */ comment characters didn't exist.

  * OPTIMIZE TABLE tbl_name can now be used to reclaim disk space after many deletes.  Currently, this uses ALTER TABLE to re-generate the table, but in the future it will use an integrated isamchk for more speed.

  * Upgraded libtool to get the configure more portable.

  * Fixed slow UPDATE and DELETE operations when using DATETIME or DATE keys.

  * Changed optimizer to make it better at deciding when to do a full join and when using keys.

  * You can now use mysqladmin proc to display information about your own threads. Only users with the Process_priv privilege can get information about all threads.

  * Added handling of formats YYMMDD, YYYYMMDD, YYMMDDHHMMSS for numbers when using DATETIME and TIMESTAMP types. (Formerly these formats only worked with strings.)

  * Added connect option CLIENT_IGNORE_SPACE to allow use of spaces after function names and before ( (Powerbuilder requires this). This will make all function names reserved words.

  * Added the --log-long-format option to mysqld to enable timestamps and INSERT_ID's in the update log.

  * Added --where option to mysqldump (patch by Jim Faucette).

  * The lexical analyzer now uses ``perfect hashing'' for faster parsing of SQL statements.

Changes in release 3.22.6
-------------------------

  * Faster mysqldump.

  * For the LOAD DATA INFILE statement, you can now use the new LOCAL keyword to read the file from the client.  mysqlimport will automatically use LOCAL when importing with the TCP/IP protocol.

  * Fixed small optimize problem when updating keys.

  * Changed makefiles to support shared libraries.

  * MySQL-NT can now use named pipes, which means that you can now use MySQL-NT without having to install TCP/IP.

Changes in release 3.22.5
-------------------------

  * All table lock handing is changed to avoid some very subtle deadlocks when using DROP TABLE, ALTER TABLE, DELETE FROM TABLE and mysqladmin flush-tables under heavy usage. Changed locking code to get better handling of locks of different types.

  * Updated DBI to 1.00 and DBD to 1.2.0.

  * Added a check that the error message file contains error messages suitable for the current version of mysqld. (To avoid errors if you accidentally try to use an old error message file.)

  * All count structures in the client (affected_rows(), insert_id(),...) are now of type BIGINT to allow 64-bit values to be used. This required a minor change in the MySQL protocol which should affect only old clients when using tables with AUTO_INCREMENT values > 24M.

  * The return type of mysql_fetch_lengths() has changed from uint * to ulong *. This may give a warning for old clients but should work on most machines.

  * Change mysys and dbug libraries to allocate all thread variables in one struct.  This makes it easier to make a threaded libmysql.dll library.

  * Use the result from gethostname() (instead of uname()) when constructing .pid file names.

  * New better compressed server/client protocol.

  * COUNT(), STD() and AVG() are extended to handle more than 4G rows.

  * You can now store values in the range -838:59:59 <= x <= 838:59:59 in a TIME column.

  * WARNING: INCOMPATIBLE CHANGE!! If you set a TIME column to too short a value, MySQL now assumes the value is given as: [[[D ]HH:]MM:]SS instead of HH[:MM[:SS]].

  * TIME_TO_SEC() and SEC_TO_TIME() can now handle negative times and hours up to 32767.

  * Added new option SET OPTION SQL_LOG_UPDATE={0|1} to allow users with the process privilege to bypass the update log. (Modified patch from Sergey A Mukhin violet@rosnet.net.)

  * Fixed fatal bug in LPAD().

  * Initialize line buffer in mysql.cc to make BLOB reading from pipes safer.

  * Added -O max_connect_errors=# option to mysqld. Connect errors are now reset for each correct connection.

  * Increased the default value of max_allowed_packet to 1M in mysqld.

  * Added --low-priority-updates option to mysqld, to give table-modifying operations (INSERT, REPLACE, UPDATE, DELETE) lower priority than retrievals.  You can now use {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... You can also use SET OPTION SQL_LOW_PRIORITY_UPDATES={0|1} to change the priority for one thread.  One side effect is that LOW_PRIORITY is now a reserved word. :(

  * Add support for INSERT INTO table ... VALUES(...),(...),(...), to allow inserting multiple rows with a single statement.

  * INSERT INTO tbl_name is now also cached when used with LOCK TABLES. (Previously only INSERT ... SELECT and LOAD DATA INFILE were cached.)

  * Allow GROUP BY functions with HAVING:

          mysql> SELECT col FROM table GROUP BY col HAVING COUNT(*)>0;

  * mysqld will now ignore trailing ; characters in queries. This is to make it easier to migrate from some other SQL servers that require the trailing ;.

  * Fix for corrupted fixed-format output generated by SELECT INTO OUTFILE.

  * WARNING: INCOMPATIBLE CHANGE!! Added Oracle GREATEST() and LEAST() functions.  You must now use these instead of the MAX() and MIN() functions to get the largest/smallest value from a list of values. These can now handle REAL, BIGINT and string (CHAR or VARCHAR) values.

  * WARNING: INCOMPATIBLE CHANGE!! DAYOFWEEK() had offset 0 for Sunday. Changed the offset to 1.

  * Give an error for queries that mix GROUP BY columns and fields when there is no GROUP BY specification.

  * Added --vertical option to mysql, for printing results in vertical mode.

  * Index-only optimization; some queries are now resolved using only indexes.  Until MySQL 4.0, this works only for numeric columns. See MySQL indexes.

  * Lots of new benchmarks.

  * A new C API chapter and lots of other improvements in the manual.

Changes in release 3.22.4
-------------------------

  * Added --tmpdir option to mysqld, for specifying the location of the temporary file directory.

  * MySQL now automatically changes a query from an ODBC client:

          SELECT ... FROM table WHERE auto_increment_column IS NULL

     to:

          SELECT ... FROM table WHERE auto_increment_column == LAST_INSERT_ID()

     This allows some ODBC programs (Delphi, Access) to retrieve the newly inserted row to fetch the AUTO_INCREMENT id.

  * DROP TABLE now waits for all users to free a table before deleting it.

  * Fixed small memory leak in the new connect protocol.

  * New functions BIN(), OCT(), HEX() and CONV() for converting between different number bases.

  * Added function SUBSTRING() with 2 arguments.

  * If you created a table with a record length smaller than 5, you couldn't delete rows from the table.

  * Added optimization to remove const reference tables from ORDER BY and GROUP BY.

  * mysqld now automatically disables system locking on Linux and Win32, and for systems that use MIT-pthreads.  You can force the use of locking with the --enable-locking option.

  * Added --console option to mysqld, to force a console window (for error messages) when using Win32.

  * Fixed table locks for Win32.

  * Allow $ in identifiers.

  * Changed name of user-specific configuration file from my.cnf to .my.cnf (Unix only).

  * Added DATE_ADD() and DATE_SUB() functions.

Changes in release 3.22.3
-------------------------

  * Fixed a lock problem (bug in MySQL 3.22.1) when closing temporary tables.

  * Added missing mysql_ping() to the client library.

  * Added --compress option to all MySQL clients.

  * Changed byte to char in mysql.h and mysql_com.h.

Changes in release 3.22.2
-------------------------

  * Searching on multiple constant keys that matched more than 30% of the rows didn't always use the best possible key.

  * New functions <<, >>, RPAD() and LPAD().

  * You can now save default options (like passwords) in a configuration file (my.cnf).

  * Lots of small changes to get ORDER BY to work when no records are found when using fields that are not in GROUP BY (MySQL extension).

  * Added --chroot option to mysqld, to start mysqld in a chroot environment (by Nikki Chumakov nikkic@cityline.ru).

  * Trailing spaces are now ignored when comparing case-sensitive strings; this should fix some problems with ODBC and flag 512!

  * Fixed a core-dump bug in the range optimizer.

  * Added --one-thread option to mysqld, for debugging with LinuxThreads (or glibc).  (This replaces the -T32 flag)

  * Added DROP TABLE IF EXISTS to prevent an error from occurring if the table doesn't exist.

  * IF and EXISTS are now reserved words (they would have to be sooner or later).

  * Added lots of new options to mysqldump.

  * Server error messages are now in mysqld_error.h.

  * The server/client protocol now supports compression.

  * All bug fixes from MySQL 3.21.32.

Changes in release 3.22.1
-------------------------

  * Added new C API function mysql_ping().

  * Added new API functions mysql_init() and mysql_options(). You now MUST call mysql_init() before you call mysql_real_connect(). You don't have to call mysql_init() if you only use mysql_connect().

  * Added mysql_options(...,MYSQL_OPT_CONNECT_TIMEOUT,...) so you can set a timeout for connecting to a server.

  * Added --timeout option to mysqladmin, as a test of mysql_options().

  * Added AFTER column and FIRST options to ALTER TABLE ... ADD columns. This makes it possible to add a new column at some specific location within a row in an existing table.

  * WEEK() now takes an optional argument to allow handling of weeks when the week starts on Monday (some European countries).  By default, WEEK() assumes the week starts on Sunday.

  * TIME columns weren't stored properly (bug in MySQL 3.22.0).

  * UPDATE now returns information about how many rows were matched and updated, and how many ``warnings'' occurred when doing the update.

  * Fixed incorrect result from FORMAT(-100,2).

  * ENUM and SET columns were compared in binary (case-sensitive) fashion; changed to be case insensitive.

Changes in release 3.22.0
-------------------------

  * New (backward compatible) connect protocol that allows you to specify the database to use when connecting, to get much faster connections to a specific database.

     The mysql_real_connect() call is changed to:

          mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
                             const char *passwd, const char *db, uint port,
                             const char *unix_socket, uint client_flag)

  * Each connection is handled by its own thread, rather than by the master accept() thread.  This fixes permanently the telnet bug that was a topic on the mail list some time ago.

  * All TCP/IP connections are now checked with backward resolution of the hostname to get better security. mysqld now has a local hostname resolver cache so connections should actually be faster than before, even with this feature.

  * A site automatically will be blocked from future connections if someone repeatedly connects with an ``improper header'' (like when one uses telnet).

  * You can now refer to tables in different databases with references of the form tbl_name@db_name or db_name.tbl_name.  This makes it possible to give a user read access to some tables and write access to others simply by keeping them in different databases!

  * Added --user option to mysqld, to allow it to run as another Unix user (if it is started as the Unix root user).

  * Added caching of users and access rights (for faster access rights checking)

  * Normal users (not anonymous ones) can change their password with mysqladmin password 'new_password'.  This uses encrypted passwords that are not logged in the normal MySQL log!

  * All important string functions are now coded in assembler for x86 Linux machines.  This gives a speedup of 10% in many cases.

  * For tables that have many columns, the column names are now hashed for much faster column name lookup (this will speed up some benchmark tests a lot!)

  * Some benchmarks are changed to get better individual timing. (Some loops were so short that a specific test took < 2 seconds. The loops have been changed to take about 20 seconds to make it easier to compare different databases. A test that took 1-2 seconds before now takes 11-24 seconds, which is much better)

  * Re-arranged SELECT code to handle some very specific queries involving group functions (like COUNT(*)) without a GROUP BY but with HAVING. The following now works:

          mysql> SELECT count(*) as C FROM table HAVING C > 1;

  * Changed the protocol for field functions to be faster and avoid some calls to malloc().

  * Added -T32 option to mysqld, for running all queries under the main thread.  This makes it possible to debug mysqld under Linux with gdb!

  * Added optimization of not_null_column IS NULL (needed for some Access queries).

  * Allow STRAIGHT_JOIN to be used between two tables to force the optimizer to join them in a specific order.

  * String functions now return VARCHAR rather than CHAR and the column type is now VARCHAR for fields saved as VARCHAR. This should make the MyODBC driver better, but may break some old MySQL clients that don't handle FIELD_TYPE_VARCHAR the same way as FIELD_TYPE_CHAR.

  * CREATE INDEX and DROP INDEX are now implemented through ALTER TABLE. CREATE TABLE is still the recommended (fast) way to create indexes.

  * Added --set-variable option wait_timeout to mysqld.

  * Added time column to mysqladmin processlist to show how long a query has taken or how long a thread has slept.

  * Added lots of new variables to show variables and some new to show status.

  * Added new type YEAR. YEAR is stored in 1 byte with allowable values of 0, and 1901 to 2155.

  * Added new DATE type that is stored in 3 bytes rather than 4 bytes. All new tables are created with the new date type if you don't use the --old-protocol option to mysqld.

  * Fixed bug in record caches; for some queries, you could get Error from table handler: # on some operating systems.

  * Added --enable-assembler option to configure, for x86 machines (tested on Linux + gcc).  This will enable assembler functions for the most important string functions for more speed!

Changes in release 3.21.x
=========================

Changes in release 3.21.33
--------------------------

  * Fixed problem when sending SIGHUP to mysqld; mysqld core dumped when starting from boot on some systems.

  * Fixed problem with losing a little memory for some connections.

  * DELETE FROM tbl_name without a WHERE condition is now done the long way when you use LOCK TABLES or if the table is in use, to avoid race conditions.

  * INSERT INTO TABLE (timestamp_column) VALUES (NULL); didn't set timestamp.

Changes in release 3.21.32
--------------------------

  * Fixed some possible race conditions when doing many reopen/close on the same tables under heavy load!  This can happen if you execute mysqladmin refresh often. This could in some very rare cases corrupt the header of the index file and cause error 126 or 138.

  * Fixed fatal bug in refresh() when running with the --skip-locking option. There was a ``very small'' time gap after a mysqladmin refresh when a table could be corrupted if one thread updated a table while another thread did mysqladmin refresh and another thread started a new update ont the same table before the first thread had finished. A refresh (or --flush-tables) will now not return until all used tables are closed!

  * SELECT DISTINCT with a WHERE clause that didn't match any rows returned a row in some contexts (bug only in 3.21.31).

  * GROUP BY + ORDER BY returned one empty row when no rows where found.

  * Fixed a bug in the range optimizer that wrote Use_count: Wrong count for ... in the error log file.

Changes in release 3.21.31
--------------------------

  * Fixed a sign extension problem for the TINYINT type on Irix.

  * Fixed problem with LEFT("constant_string",function).

  * Fixed problem with FIND_IN_SET().

  * LEFT JOIN core dumped if the second table is used with a constant WHERE/ON expression that uniquely identifies one record.

  * Fixed problems with DATE_FORMAT() and incorrect dates. DATE_FORMAT() now ignores '%' to make it possible to extend it more easily in the future.

Changes in release 3.21.30
--------------------------

  * mysql now returns an exit code > 0 if the query returned an error.

  * Saving of command line history to file in mysql client. By Tommy Larsen tommy@mix.hive.no.

  * Fixed problem with empty lines that were ignored in mysql.cc.

  * Save the pid of the signal handler thread in the pid file instead of the pid of the main thread.

  * tommy@valley.ne.jp による日本語キャラクターセット(SJIS, UJIS)のサポート.

  * Changed safe_mysqld to redirect startup messages to 'hostname'.err instead of 'hostname'.log to reclaim file space on mysqladmin refresh.

  * ENUM always had the first entry as default value.

  * ALTER TABLE wrote two entries to the update log.

  * sql_acc() now closes the mysql grant tables after a reload to save table space and memory.

  * Changed LOAD DATA to use less memory with tables and BLOB columns.

  * Sorting on a function which made a division / 0 produced a wrong set in some cases.

  * Fixed SELECT problem with LEFT() when using the czech character set.

  * Fixed problem in isamchk; it couldn't repair a packed table in a very unusual case.

  * SELECT statements with & or | (bit functions) failed on columns with NULL values.

  * When comparing a field = field, where one of the fields was a part key, only the length of the part key was compared.

Changes in release 3.21.29
--------------------------

  * LOCK TABLES + DELETE from tbl_name never removed locks properly.

  * Fixed problem when grouping on an OR function.

  * Fixed permission problem with umask() and creating new databases.

  * Fixed permission problem on result file with SELECT ... INTO OUTFILE ...

  * Fixed problem in range optimizer (core dump) for a very complex query.

  * Fixed problem when using MIN(integer) or MAX(integer) in GROUP BY.

  * Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha).

  * Fixed bug in WEEK("XXXX-xx-01").

Changes in release 3.21.28
--------------------------

  * Fixed socket permission (clients couldn't connect to Unix socket on Linux).

  * Fixed bug in record caches; for some queries, you could get Error from table handler: # on some operating systems.

Changes in release 3.21.27
--------------------------

  * Added user level lock functions GET_LOCK(string,timeout), RELEASE_LOCK(string).

  * Added opened_tables to show status.

  * Changed connect timeout to 3 seconds to make it somewhat harder for crackers to kill mysqld through telnet + TCP/IP.

  * Fixed bug in range optimizer when using WHERE key_part_1 >= something AND key_part_2 <= something_else.

  * Changed configure for detection of FreeBSD 3.0 9803xx and above

  * WHERE with string_column_key = constant_string didn't always find all rows if the column had many values differing only with characters of the same sort value (like e and é).

  * Strings keys looked up with 'ref' were not compared in case-sensitive fashion.

  * Added umask() to make log files non-readable for normal users.

  * Ignore users with old (8-byte) password on startup if not using --old-protocol option to mysqld.

  * SELECT which matched all key fields returned the values in the case of the matched values, not of the found values. (Minor problem.)

Changes in release 3.21.26
--------------------------

  * FROM_DAYS(0) now returns "0000-00-00".

  * In DATE_FORMAT(), PM and AM were swapped for hours 00 and 12.

  * Extended the default maximum key size to 256.

  * Fixed bug when using BLOB/TEXT in GROUP BY with many tables.

  * An ENUM field that is not declared NOT NULL has NULL as the default value. (Previously, the default value was the first enumeration value.)

  * Fixed bug in the join optimizer code when using many part keys on the same key:  INDEX (Organization,Surname(35),Initials(35)).

  * Added some tests to the table order optimizer to get some cases with SELECT ... FROM many_tables much faster.

  * Added a retry loop around accept() to possibly fix some problems on some Linux machines.

Changes in release 3.21.25
--------------------------

  * Changed typedef 'string' to typedef 'my_string' for better portability.

  * You can now kill threads that are waiting on a disk full condition.

  * Fixed some problems with UDF functions.

  * Added long options to isamchk. Try isamchk --help.

  * Fixed a bug when using 8 bytes long (alpha); filesort() didn't work. Affects DISTINCT, ORDER BY and GROUP BY on 64-bit processors.

Changes in release 3.21.24
--------------------------

  * Dynamic loadable functions. Based on source from Alexis Mikhailov.

  * You couldn't delete from a table if no one had done a SELECT on the table.

  * Fixed problem with range optimizer with many OR operators on key parts inside each other.

  * Recoded MIN() and MAX() to work properly with strings and HAVING.

  * Changed default umask value for new files from 0664 to 0660.

  * Fixed problem with LEFT JOIN and constant expressions in the ON part.

  * Added Italian error messages from brenno@dewinter.com.

  * configure now works better on OSF1 (tested on 4.0D).

  * Added hooks to allow LIKE optimization with international character support.

  * Upgraded DBI to 0.93.

Changes in release 3.21.23
--------------------------

  * The following symbols are now reserved words: TIME, DATE, TIMESTAMP, TEXT, BIT, ENUM, NO, ACTION, CHECK, YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, STATUS, VARIABLES.

  * Setting a TIMESTAMP to NULL in LOAD DATA INFILE ... didn't set the current time for the TIMESTAMP.

  * Fix BETWEEN to recognize binary strings. Now BETWEEN is case sensitive.

  * Added --skip-thread-priority option to mysqld, for systems where mysqld's thread scheduling doesn't work properly (BSDI 3.1).

  * Added ODBC functions DAYNAME() and MONTHNAME().

  * Added function TIME_FORMAT().  This works like DATE_FORMAT(), but takes a time string ('HH:MM:DD') as argument.

  * Fixed unlikely(?) key optimizer bug when using ORs of key parts inside ANDs.

  * Added command variables to mysqladmin.

  * A lot of small changes to the binary releases.

  * Fixed a bug in the new protocol from MySQL 3.21.20.

  * Changed ALTER TABLE to work with Win32 (Win32 can't rename open files). Also fixed a couple of small bugs in the Win32 version.

  * All standard MySQL clients are now ported to MySQL-Win32.

  * MySQL can now be started as a service on NT.

Changes in release 3.21.22
--------------------------

  * Starting with this version, all MySQL distributions will be configured, compiled and tested with crash-me and the benchmarks on the following platforms: SunOS 5.6 sun4u, SunOS 5.5.1 sun4u, SunOS 4.14 sun4c, SunOS 5.6 i86pc, Irix 6.3 mips5k, HP-UX 10.20 hppa, AIX 4.2.1 ppc, OSF1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1 i386.

  * Fix COUNT(*) problems when the WHERE clause didn't match any records.  (Bug from 3.21.17.)

  * Removed that NULL = NULL is true.  Now you must use IS NULL or IS NOT NULL to test whether or not a value is NULL. (This is according to ANSI SQL but may break old applications that are ported from mSQL.) You can get the old behavior by compiling with -DmSQL_COMPLIANT.

  * Fixed bug that core dumped when using many LEFT OUTER JOIN clauses.

  * Fixed bug in ORDER BY on string formula with possible NULL values.

  * Fixed problem in range optimizer when using <= on sub index.

  * Added functions DAYOFYEAR(), DAYOFMONTH(), MONTH(), YEAR(), WEEK(), QUARTER(), HOUR(), MINUTE(), SECOND() and FIND_IN_SET().

  * Added command SHOW VARIABLES.

  * Added support of ``long constant strings'' from ANSI SQL:

          mysql> SELECT 'first ' 'second';       -> 'first second'

  * Upgraded mSQL-Mysql-modules to 1.1825.

  * Upgraded mysqlaccess to 2.02.

  * Fixed problem with Russian character set and LIKE.

  * Ported to OpenBSD 2.1.

  * New Dutch error messages.

Changes in release 3.21.21a
---------------------------

  * Configure changes for some operating systems.

Changes in release 3.21.21
--------------------------

  * Fixed optimizer bug when using WHERE data_field = date_field2 AND date_field2 = constant.

  * Added command SHOW STATUS.

  * Removed manual.ps from the source distribution to make it smaller.

Changes in release 3.21.20
--------------------------

  * Changed the maximum table name and column name lengths from 32 to 64.

  * Aliases can now be of ``any'' length.

  * Fixed mysqladmin stat to return the right number of queries.

  * Changed protocol (downward compatible) to mark if a column has the AUTO_INCREMENT attribute or is a TIMESTAMP. This is needed for the new Java driver.

  * Added Hebrew sorting order by Zeev Suraski.

  * Solaris 2.6: Fixed configure bugs and increased maximum table size from 2G to 4G.

Changes in release 3.21.19
--------------------------

  * Upgraded DBD to 1823. This version implements mysql_use_result in DBD-Mysql.

  * Benchmarks updated for empress (by Luuk).

  * Fixed a case of slow range searching.

  * Configure fixes (Docs directory).

  * Added function REVERSE() (by Zeev Suraski).

Changes in release 3.21.18
--------------------------

  * Issue error message if client C functions are called in wrong order.

  * Added automatic reconnect to the libmysql.c library. If a write command fails, an automatic reconnect is done.

  * Small sort sets no longer use temporary files.

  * Upgraded DBI to 0.91.

  * Fixed a couple of problems with LEFT OUTER JOIN.

  * Added CROSS JOIN syntax. CROSS is now a reserved word.

  * Recoded yacc/bison stack allocation to be even safer and to allow MySQL to handle even bigger expressions.

  * Fixed a couple of problems with the update log.

  * ORDER BY was slow when used with key ranges.

Changes in release 3.21.17
--------------------------

  * Changed documentation string of --with-unix-socket-path to avoid confusion.

  * Added ODBC and ANSI SQL style LEFT OUTER JOIN.

  * The following are new reserved words: LEFT, NATURAL, USING.

  * The client library now uses the value of the environment variable MYSQL_HOST as the default host if it's defined.

  * SELECT col_name, SUM(expr) now returns NULL for col_name when there are matching rows.

  * Fixed problem with comparing binary strings and BLOBs with ASCII characters over 127.

  * Fixed lock problem: when freeing a read lock on a table with multiple read locks, a thread waiting for a write lock would have been given the lock. This shouldn't affect data integrity, but could possibly make mysqld restart if one thread was reading data that another thread modified.

  * LIMIT offset,count didn't work in INSERT ... SELECT.

  * Optimized key block caching. This will be quicker than the old algorithm when using bigger key caches.

Changes in release 3.21.16
--------------------------

  * Added ODBC 2.0 & 3.0 functions POWER(), SPACE(), COT(), DEGREES(), RADIANS(), ROUND(2 arg) and TRUNCATE().

  * WARNING: INCOMPATIBLE CHANGE!! LOCATE() parameters were swapped according to ODBC standard. Fixed.

  * Added function TIME_TO_SEC().

  * In some cases, default values were not used for NOT NULL fields.

  * Timestamp wasn't always updated properly in UPDATE SET ... statements.

  * Allow empty strings as default values for BLOB and TEXT, to be compatible with mysqldump.

Changes in release 3.21.15
--------------------------

  * WARNING: INCOMPATIBLE CHANGE!! mysqlperl is now from Msql-Mysql-modules. This means that connect() now takes host, database, user, password arguments! The old version took host, database, password, user.

  * Allow DATE '1997-01-01', TIME '12:10:10' and TIMESTAMP '1997-01-01 12:10:10' formats required by ANSI SQL. WARNING: INCOMPATIBLE CHANGE!! This has the unfortunate side-effect that you no longer can have columns named DATE, TIME or TIMESTAMP. :( Old columns can still be accessed through tablename.columnname!)

  * Changed Makefiles to hopefully work better with BSD systems. Also, manual.dvi is now included in the distribution to avoid having stupid make programs trying to rebuild it.

  * readline library upgraded to version 2.1.

  * A new sortorder german-1. That is a normal ISO-Latin1 with a german sort order.

  * Perl DBI/DBD is now included in the distribution. DBI is now the recommended way to connect to MySQL from Perl.

  * New portable benchmark suite with DBD, with test results from mSQL 2.0.3, MySQL, PostgreSQL 6.2.1 and Solid server 2.2.

  * crash-me is now included with the benchmarks; This is a Perl program designed to find as many limits as possible in a SQL server. Tested with mSQL, PostgreSQL, Solid and MySQL.

  * Fixed bug in range-optimizer that crashed MySQL on some queries.

  * Table and column name completion for mysql command line tool, by Zeev Suraski and Andi Gutmans.

  * Added new command REPLACE that works like INSERT but replaces conflicting records with the new record. REPLACE INTO TABLE ... SELECT ... works also.

  * Added new commands CREATE DATABASE db_name and DROP DATABASE db_name.

  * Added RENAME option to ALTER TABLE: ALTER TABLE name RENAME AS new_name.

  * make_binary_distribution now includes libgcc.a in libmysqlclient.a. This should make linking work for people who don't have gcc.

  * Changed net_write() to my_net_write() because of a name conflict with Sybase.

  * New function DAYOFWEEK() compatible with ODBC.

  * Stack checking and bison memory overrun checking to make MySQL safer with weird queries.

Changes in release 3.21.14b
---------------------------

  * Fixed a couple of small configure problems on some platforms.

Changes in release 3.21.14a
---------------------------

  * Ported to SCO Openserver 5.0.4  with FSU Pthreads.

  * HP-UX 10.20 should work.

  * Added new function DATE_FORMAT().

  * Added NOT IN.

  * Added automatic removal of 'ODBC function conversions': {fn now() }

  * Handle ODBC 2.50.3 option flags.

  * Fixed comparison of DATE and TIME values with NULL.

  * Changed language name from germany to german to be consistent with the other language names.

  * Fixed sorting problem on functions returning a FLOAT. Previously, the values were converted to INTs before sorting.

  * Fixed slow sorting when sorting on key field when using key_column=constant.

  * Sorting on calculated DOUBLE values sorted on integer results instead.

  * mysql no longer needs a database argument.

  * Changed the place where HAVING should be. According to ANSI, it should be after GROUP BY but before ORDER BY. MySQL 3.20 incorrectly had it last.

  * Added Sybase command USE DATABASE to start using another database.

  * Added automatic adjusting of number of connections and table cache size if the maximum number of files that can be opened is less than needed. This should fix that mysqld doesn't crash even if you haven't done a ulimit -n 256 before starting mysqld.

  * Added lots of limit checks to make it safer when running with too little memory or when doing weird queries.

Changes in release 3.21.13
--------------------------

  * Added retry of interrupted reads and clearing of errno. This makes Linux systems much safer!

  * Fixed locking bug when using many aliases on the same table in the same SELECT.

  * Fixed bug with LIKE on number key.

  * New error message so you can check whether the connection was lost while the command was running or whether the connection was down from the start.

  * Added --table option to mysql to print in table format. Moved time and row information after query result. Added automatic reconnect of lost connections.

  * Added != as a synonym for <>.

  * Added function VERSION() to make easier logs.

  * New multi-user test tests/fork_test.pl to put some strain on the thread library.

Changes in release 3.21.12
--------------------------

  * Fixed ftruncate() call in MIT-pthreads. This made isamchk destroy the .ISM files on (Free)BSD 2.x systems.

  * Fixed broken __P_ patch in MIT-pthreads.

  * Many memory overrun checks. All string functions now return NULL if the returned string should be longer than max_allowed_packet bytes.

  * Changed the name of the INTERVAL type to ENUM, because INTERVAL is used in ANSI SQL.

  * In some cases, doing a JOIN + GROUP + INTO OUTFILE, the result wasn't grouped.

  * LIKE with '_' as last character didn't work. Fixed.

  * Added extended ANSI SQL TRIM() function.

  * Added CURTIME().

  * Added ENCRYPT() function by Zeev Suraski.

  * Fixed better FOREIGN KEY syntax skipping. New reserved words: MATCH, FULL, PARTIAL.

  * mysqld now allows IP number and hostname to the --bind-address option.

  * Added SET OPTION CHARACTER SET cp1251_koi8 to enable conversions of data to/from cp1251_koi8.

  * Lots of changes for Win95 port. In theory, this version should now be easily portable to Win95.

  * Changed the CREATE COLUMN syntax of NOT NULL columns to be after the DEFAULT value, as specified in the ANSI SQL standard. This will make mysqldump with NOT NULL and default values incompatible with MySQL 3.20.

  * Added many function name aliases so the functions can be used with ODBC or ANSI SQL92 syntax.

  * Fixed syntax of ALTER TABLE tbl_name ALTER COLUMN col_name SET DEFAULT NULL.

  * Added CHAR and BIT as synonyms for CHAR(1).

  * Fixed core dump when updating as a user who has only select privilege.

  * INSERT ... SELECT ... GROUP BY didn't work in some cases. An Invalid use of group function error occurred.

  * When using LIMIT, SELECT now always uses keys instead of record scan.  This will give better performance on SELECT and a WHERE that matches many rows.

  * Added Russian error messages.

Changes in release 3.21.11
--------------------------

  * Configure changes.

  * MySQL now works with the new thread library on BSD/OS 3.0.

  * Added new group functions BIT_OR() and BIT_AND().

  * Added compatibility functions CHECK and REFERENCES. CHECK is now a reserved word.

  * Added ALL option to GRANT for better compatibility. (GRANT is still a dummy function.)

  * Added partly-translated dutch messages.

  * Fixed bug in ORDER BY and GROUP BY with NULL columns.

  * Added function last_insert_id() to retrieve last AUTO_INCREMENT value.  This is intended for clients to ODBC that can't use the mysql_insert_id() API function, but can be used by any client.

  * Added --flush-logs option to mysqladmin.

  * Added command STATUS to mysql.

  * Fixed problem with ORDER BY/GROUP BY because of bug in gcc.

  * Fixed problem with INSERT ... SELECT ... GROUP BY.

Changes in release 3.21.10
--------------------------

  * New mysqlaccess.

  * CREATE now supports all ODBC types and the mSQL TEXT type. All ODBC 2.5 functions are also supported (added REPEAT). This provides better portability.

  * Added text types TINYTEXT, TEXT, MEDIUMTEXT and LONGTEXT.  These are actually BLOBtypes, but all searching is done in case-insensitive fashion.

  * All old BLOB fields are now TEXT fields.  This only changes that all searching on strings is done in case-sensitive fashion. You must do an ALTER TABLE and change the field type to BLOB if you want to have tests done in case-sensitive fashion.

  * Fixed some configure issues.

  * Made the locking code a bit safer. Fixed very unlikely deadlock situation.

  * Fixed a couple of bugs in the range optimizer. Now the new range benchmark test-select works.

Changes in release 3.21.9
-------------------------

  * Added --enable-unix-socket=pathname option to configure.

  * Fixed a couple of portability problems with include files.

  * Fixed bug in range calculation that could return empty set when searching on multiple key with only one entry (very rare).

  * Most things ported to FSU Pthreads, which should allow MySQL to run on SCO. See SCO.

Changes in release 3.21.8
-------------------------

  * Works now in Solaris 2.6.

  * Added handling of calculation of SUM() functions. For example, you can now use SUM(column)/COUNT(column).

  * Added handling of trigometric functions: PI(), ACOS(), ASIN(), ATAN(), COS(), SIN() and TAN().

  * New languages: norwegian, norwegian-ny and portuguese.

  * Fixed parameter bug in net_print() in procedure.cc.

  * Fixed a couple of memory leaks.

  * Now allow also the old SELECT ... INTO OUTFILE syntax.

  * Fixed bug with GROUP BY and SELECT on key with many values.

  * mysql_fetch_lengths() sometimes returned incorrect lengths when you used mysql_use_result(). This affected at least some cases of mysqldump --quick.

  * Fixed bug in optimization of WHERE const op field.

  * Fixed problem when sorting on NULL fields.

  * Fixed a couple of 64-bit (Alpha) problems.

  * Added --pid-file=# option to mysqld.

  * Added date formatting to FROM_UNIXTIME(), originally by Zeev Suraski.

  * Fixed bug in BETWEEN in range optimizer (Did only test = of the first argument).

  * Added machine-dependent files for MIT-pthreads i386-SCO. There is probably more to do to get this to work on SCO 3.5.

Changes in release 3.21.7
-------------------------

  * Changed Makefile.am to take advantage of Automake 1.2.

  * Added the beginnings of a benchmark suite.

  * Added more secure password handling.

  * Added new client function mysql_errno(), to get the error number of the error message. This makes error checking in the client much easier. This makes the new server incompatible with the 3.20.x server when running without --old-protocol.  The client code is backward compatible. More information can be found in the README file!

  * Fixed some problems when using very long, illegal names.

Changes in release 3.21.6
-------------------------

  * Fixed more portability issues (incorrect sigwait and sigset defines).

  * configure should now be able to detect the last argument to accept().

Changes in release 3.21.5
-------------------------

  * Should now work with FreeBSD 3.0 if used with FreeBSD-3.0-libc_r-1.0.diff, which can be found at http://www.mysql.com/Download/Patches.

  * Added new option -O tmp_table_size=# to mysqld.

  * New function FROM_UNIXTIME(timestamp) which returns a date string in 'YYYY-MM-DD HH:MM:DD' format.

  * New function SEC_TO_TIME(seconds) which returns a string in 'HH:MM:SS' format.

  * New function SUBSTRING_INDEX(), originally by Zeev Suraski.

Changes in release 3.21.4
-------------------------

  * Should now configure and compile on OSF1 4.0 with the DEC compiler.

  * Configuration and compilation on BSD/OS 3.0 works, but due to some bugs in BSD/OS 3.0, mysqld doesn't work on it yet.

  * Configuration and compilation on FreeBSD 3.0 works, but I couldn't get pthread_create to work.

Changes in release 3.21.3
-------------------------

  * Added reverse check lookup of hostnames to get better security.

  * Fixed some possible buffer overflows if filenames that are too long are used.

  * mysqld doesn't accept hostnames that start with digits followed by a '.', because the hostname may look like an IP number.

  * Added --skip-networking option to mysqld, to only allow socket connections.  (This will not work with MIT-pthreads!)

  * Added check of too long table names for alias.

  * Added check if database name is okay.

  * Added check if too long table names.

  * Removed incorrect free() that killed the server on CREATE DATABASE or DROP DATABASE.

  * Changed some mysqld -O options to better names.

  * Added -O join_cache_size=# option to mysqld.

  * Added -O max_join_size=# option to mysqld, to be able to set a limit how big queries (in this case big = slow) one should be able to handle without specifying SET OPTION SQL_BIG_SELECTS=1.  A # = is about 10 examined records. The default is ``unlimited''.

  * When comparing a TIME, DATE, DATETIME or TIMESTAMP column to a constant, the constant is converted to a time value before performing the comparison. This will make it easier to get ODBC (particularly Access97) to work with the above types. It should also make dates easier to use and the comparisons should be quicker than before.

  * Applied patch from Jochen Wiedmann that allows query() in mysqlperl to take a query with \0 in it.

  * Storing a timestamp with a 2-digit year (YYMMDD) didn't work.

  * Fix that timestamp wasn't automatically updated if set in an UPDATE clause.

  * Now the automatic timestamp field is the FIRST timestamp field.

  * SELECT * INTO OUTFILE, which didn't correctly if the outfile already existed.

  * mysql now shows the thread ID when starting or doing a reconnect.

  * Changed the default sort buffer size from 2M to 1M.

Changes in release 3.21.2
-------------------------

  * The range optimizer is coded, but only 85% tested. It can be enabled with --new, but it crashes core a lot yet...

  * More portable. Should compile on AIX and alpha-digital. At least the isam library should be relatively 64-bit clean.

  * New isamchk which can detect and fix more problems.

  * New options for isamlog.

  * Using new version of Automake.

  * Many small portability changes (from the AIX and alpha-digital port) Better checking of pthread(s) library.

  * czech error messages by snajdr@pvt.net.

  * Decreased size of some buffers to get fewer problems on systems with little memory.  Also added more checks to handle ``out of memory'' problems.

  * mysqladmin: you can now do mysqladmin kill 5,6,7,8 to kill multiple threads.

  * When the maximum connection limit is reached, one extra connection by a user with the PROCESS_ACL privilege is granted.

  * Added -O backlog=# option to mysqld.

  * Increased maximum packet size from 512K to 1024K for client.

  * Almost all of the function code is now tested in the internal test suite.

  * ALTER TABLE now returns warnings from field conversions.

  * Port changed to 3306 (got it reserved from ISI).

  * Added a fix for Visual FoxBase so that any schema name from a table specification is automatically removed.

  * New function ASCII().

  * Removed function BETWEEN(a,b,c). Use the standard ANSI synax instead: expr BETWEEN expr AND expr.

  * MySQL no longer has to use an extra temporary table when sorting on functions or SUM() functions.

  * Fixed bug that you couldn't use tbl_name.field_name in UPDATE.

  * Fixed SELECT DISTINCT when using 'hidden group'. For example:

          mysql> SELECT DISTINCT MOD(some_field,10) FROM test
                     GROUP BY some_field;

     Note: some_field is normally in the SELECT part. ANSI SQL should require it.

Changes in release 3.21.0
-------------------------

  * New reserved words used: INTERVAL, EXPLAIN, READ, WRITE, BINARY.

  * Added ODBC function CHAR(num,...).

  * New operator IN. This uses a binary search to find a match.

  * New command LOCK TABLES tbl_name [AS alias] {READ|WRITE} ...

  * Added --log-update option to mysqld, to get a log suitable for incremental updates.

  * New command EXPLAIN SELECT ... to get information about how the optimizer will do the join.

  * For easier client code, the client should no longer use FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB, FIELD_TYPE_LONG_BLOB or FIELD_TYPE_VAR_STRING (as previously returned by mysql_list_fields).  You should instead only use FIELD_TYPE_BLOB or FIELD_TYPE_STRING.  If you want exact types, you should use the command SHOW FIELDS.

  * Added varbinary syntax: 0x###### which can be used as a string (default) or a number.

  * FIELD_TYPE_CHAR is renamed to FIELD_TYPE_TINY.

  * Changed all fields to C++ classes.

  * Removed FORM struct.

  * Fields with DEFAULT values no longer need to be NOT NULL.

  * New field types:

     ENUM
          A string which can take only a couple of defined values. The value is stored as a 1-3 byte number that is mapped automatically to a string. This is sorted according to string positions!

     SET
          A string which may have one or many string values separated with ','. The string is stored as a 1-, 2-, 3-, 4- or 8-byte number where each bit stands for a specific set member.  This is sorted according to the unsigned value of the stored packed number.

  * Now all function calculation is done with double or long long. This will provide the full 64-bit range with bit functions and fix some conversions that previously could result in precision losses.  One should avoid using unsigned long long columns with full 64-bit range (numbers bigger than 9223372036854775807) because calculations are done with signed long long.

  * ORDER BY will now put NULL field values first. GROUP BY will also work with NULL values.

  * Full WHERE with expressions.

  * New range optimizer that can resolve ranges when some keypart prefix is constant. Example:

          mysql> SELECT * FROM tbl_name
                     WHERE key_part_1="customer"
                     AND key_part_2>=10 AND key_part_2<=10;

Changes in release 3.20.x
=========================

Changes from 3.20.18 to 3.20.32b are not documented here because the 3.21 release branched here. And the relevant changes are also documented as changes to the 3.21 version.

Changes in release 3.20.18
--------------------------

  * Added -p# (remove # directories from path) to isamlog. All files are written with a relative path from the database directory Now mysqld shouldn't crash on shutdown when using the --log-isam option.

  * New mysqlperl version. It is now compatible with msqlperl-0.63.

  * New DBD module available at http://www.mysql.com/Contrib site.

  * Added group function STD() (standard deviation).

  * The mysqld server is now compiled by default without debugging information.  This will make the daemon smaller and faster.

  * Now one usually only has to specify the --basedir option to mysqld. All other paths are relative in a normal installation.

  * BLOB columns sometimes contained garbage when used with a SELECT on more than one table and ORDER BY.

  * Fixed that calculations that are not in GROUP BY work as expected (ANSI SQL extension). Example:

          mysql> SELECT id,id+1 FROM table GROUP BY id;

  * The test of using MYSQL_PWD was reversed. Now MYSQL_PWD is enabled as default in the default release.

  * Fixed conversion bug which caused mysqld to core dump with Arithmetic error on Sparc-386.

  * Added --unbuffered option to mysql, for new mysqlaccess.

  * When using overlapping (unnecessary) keys and join over many tables, the optimizer could get confused and return 0 records.

Changes in release 3.20.17
--------------------------

  * You can now use BLOB columns and the functions IS NULL and IS NOT NULL in the WHERE clause.

  * All communication packets and row buffers are now allocated dynamically on demand. The default value of max_allowed_packet is now 64K for the server and 512K for the client. This is mainly used to catch incorrect packets that could trash all memory. The server limit may be changed when it is started.

  * Changed stack usage to use less memory.

  * Changed safe_mysqld to check for running daemon.

  * The ELT() function is renamed to FIELD().  The new ELT() function returns a value based on an index: FIELD() is the inverse of ELT() Example: ELT(2,"A","B","C") returns "B". FIELD("B","A","B","C") returns 2.

  * COUNT(field), where field could have a NULL value, now works.

  * A couple of bugs fixed in SELECT ... GROUP BY.

  * Fixed memory overrun bug in WHERE with many unoptimizable brace levels.

  * Fixed some small bugs in the grant code.

  * If hostname isn't found by get_hostname, only the IP is checked. Previously, you got Access denied.

  * Inserts of timestamps with values didn't always work.

  * INSERT INTO ... SELECT ... WHERE could give the error Duplicated field.

  * Added some tests to safe_mysqld to make it ``safer''.

  * LIKE was case sensitive in some places and case insensitive in others. Now LIKE is always case insensitive.

  * mysql.cc: Allow '#' anywhere on the line.

  * New command SET OPTION SQL_SELECT_LIMIT=#. See the FAQ for more details.

  * New version of the mysqlaccess script.

  * Change FROM_DAYS() and WEEKDAY() to also take a full TIMESTAMP or DATETIME as argument. Before they only took a number of type YYYYMMDD or YYMMDD.

  * Added new function UNIX_TIMESTAMP(timestamp_column).

Changes in release 3.20.16
--------------------------

  * More changes in MIT-pthreads to get them safer. Fixed also some link bugs at least in SunOS.

  * Changed mysqld to work around a bug in MIT-pthreads. This makes multiple small SELECT operations 20 times faster. Now lock_test.pl should work.

  * Added mysql_FetchHash(handle) to mysqlperl.

  * The mysqlbug script is now distributed built to allow for reporting bugs that appear during the build with it.

  * Changed libmysql.c to prefer getpwuid() instead of cuserid().

  * Fixed bug in SELECT optimizer when using many tables with the same column used as key to different tables.

  * Added new latin2 and Russian KOI8 character tables.

  * Added support for a dummy GRANT command to satisfy Powerbuilder.

Changes in release 3.20.15
--------------------------

  * Fixed fatal bug packets out of order when using MIT-pthreads.

  * Removed possible loop when a thread waits for command from client and fcntl() fails. Thanks to Mike Bretz for finding this bug.

  * Changed alarm loop in mysqld.cc because shutdown didn't always succeed in Linux.

  * Removed use of termbits from mysql.cc.  This conflicted with glibc 2.0.

  * Fixed some syntax errors for at least BSD and Linux.

  * Fixed bug when doing a SELECT as superuser without a database.

  * Fixed bug when doing SELECT with group calculation to outfile.

Changes in release 3.20.14
--------------------------

  * If one gives -p or --password option to mysql without an argument, the user is solicited for the password from the tty.

  * Added default password from MYSQL_PWD (by Elmar Haneke).

  * Added command kill to mysqladmin to kill a specific MySQL thread.

  * Sometimes when doing a reconnect on a down connection this succeeded first on second try.

  * Fixed adding an AUTO_INCREMENT key with ALTER_TABLE.

  * AVG() gave too small value on some SELECTs with GROUP BY and ORDER BY.

  * Added new DATETIME type (by Giovanni Maruzzelli maruzz@matrice.it).

  * Fixed that define DONT_USE_DEFAULT_FIELDS works.

  * Changed to use a thread to handle alarms instead of signals on Solaris to avoid race conditions.

  * Fixed default length of signed numbers. (George Harvey georgeh@pinacl.co.uk.)

  * Allow anything for CREATE INDEX.

  * Add prezeros when packing numbers to DATE, TIME and TIMESTAMP.

  * Fixed a bug in OR of multiple tables (gave empty set).

  * Added many patches to MIT-pthreads. This fixes at least one lookup bug.

Changes in release 3.20.13
--------------------------

  * Added ANSI SQL94 DATE and TIME types.

  * Fixed bug in SELECT with AND-OR levels.

  * Added support for Slovenian characters. The Contrib directory contains source and instructions for adding other character sets.

  * Fixed bug with LIMIT and ORDER BY.

  * Allow ORDER BY and GROUP BY on items that aren't in the SELECT list. (Thanks to Wim Bonis bonis@kiss.de, for pointing this out.)

  * Allow setting of timestamp values in INSERT.

  * Fixed bug with SELECT ... WHERE ... = NULL.

  * Added changes for glibc 2.0. To get glibc to work, you should add the gibc-2.0-sigwait-patch before compiling glibc.

  * Fixed bug in ALTER TABLE when changing a NOT NULL field to allow NULL values.

  * Added some ANSI92 synonyms as field types to CREATE TABLE. CREATE TABLE now allows FLOAT(4) and FLOAT(8) to mean FLOAT and DOUBLE.

  * New utility program mysqlaccess by Yves.Carlier@rug.ac.be. This program shows the access rights for a specific user and the grant rows that determine this grant.

  * Added WHERE const op field (by bonis@kiss.de).

Changes in release 3.20.11
--------------------------

  * When using SELECT ... INTO OUTFILE, all temporary tables are ISAM instead of HEAP to allow big dumps.

  * Changed date functions to be string functions. This fixed some ``funny'' side effects when sorting on dates.

  * Extended ALTER TABLE according to SQL92.

  * Some minor compability changes.

  * Added --port and --socket options to all utility programs and mysqld.

  * Fixed MIT-pthreads readdir_r(). Now mysqladmin create database and mysqladmin drop database should work.

  * Changed MIT-pthreads to use our tempnam(). This should fix the ``sort aborted'' bug.

  * Added sync of records count in sql_update. This fixed slow updates on first connection. (Thanks to Vaclav Bittner for the test.)

Changes in release 3.20.10
--------------------------

  * New insert type: INSERT INTO ... SELECT ...

  * MEDIUMBLOB fixed.

  * Fixed bug in ALTER TABLE and BLOBs.

  * SELECT ... INTO OUTFILE now creates the file in the current database directory.

  * DROP TABLE now can take a list of tables.

  * Oracle synonym DESCRIBE (DESC).

  * Changes to make_binary_distribution.

  * Added some comments to installation instructions about configure's C++ link test.

  * Added --without-perl option to configure.

  * Lots of small portability changes.

Changes in release 3.20.9
-------------------------

  * ALTER TABLE didn't copy null bit. As a result, fields that were allowed to have NULL values were always NULL.

  * CREATE didn't take numbers as DEFAULT.

  * Some compatibility changes for SunOS.

  * Removed config.cache from old distribution.

Changes in release 3.20.8
-------------------------

  * Fixed bug with ALTER TABLE and multi-part keys.

Changes in release 3.20.7
-------------------------

  * New commands: ALTER TABLE, SELECT ... INTO OUTFILE and LOAD DATA INFILE.

  * New function: NOW().

  * Added new field file_priv to mysql/user table.

  * New script add_file_priv which adds the new field file_priv to the user table. This script must be executed if you want to use the new SELECT ... INTO and LOAD DATA INFILE ... commands with a version of MySQL earlier than 3.20.7.

  * Fixed bug in locking code, which made lock_test.pl test fail.

  * New files NEW and BUGS.

  * Changed select_test.c and insert_test.c to include config.h.

  * Added command status to mysqladmin for short logging.

  * Increased maximum number of keys to 16 and maximum number of key parts to 15.

  * Use of sub keys. A key may now be a prefix of a string field.

  * Added -k option to mysqlshow, to get key information for a table.

  * Added long options to mysqldump.

Changes in release 3.20.6
-------------------------

  * Portable to more systems because of MIT-pthreads, which will be used automatically if configure cannot find a -lpthreads library.

  * Added GNU-style long options to almost all programs. Test with program --help.

  * Some shared library support for Linux.

  * The FAQ is now in .texi format and is available in .html, .txt and .ps formats.

  * Added new SQL function RAND([init]).

  * Changed sql_lex to handle \0 unquoted, but the client can't send the query through the C API, because it takes a str pointer. You must use mysql_real_query() to send the query.

  * Added API function mysql_get_client_info().

  * mysqld now uses the N_MAX_KEY_LENGTH from nisam.h as the maximum allowed key length.

  * The following now works:

          mysql> SELECT filter_nr,filter_nr FROM filter ORDER BY filter_nr;

     Previously, this resulted in the error: Column: 'filter_nr' in order clause is ambiguous.

  * mysql now outputs '\0', '\t', '\n' and '\\' when encountering ASCII 0, tab, newline or '\' while writing tab-separated output. This is to allow printing of binary data in a portable format. To get the old behavior, use -r (or --raw).

  * Added german error messages (60 of 80 error messages translated).

  * Added new API function mysql_fetch_lengths(MYSQL_RES *), which returns an array of of column lengths (of type uint).

  * Fixed bug with IS NULL in WHERE clause.

  * Changed the optimizer a little to get better results when searching on a key part.

  * Added SELECT option STRAIGHT_JOIN to tell the optimizer that it should join tables in the given order.

  * Added support for comments starting with '--' in mysql.cc (Postgres syntax).

  * You can have SELECT expressions and table columns in a SELECT which are not used in the group part. This makes it efficient to implement lookups.  The column that is used should be a constant for each group because the value is calculated only once for the first row that is found for a group.

          mysql> SELECT id,lookup.text,sum(*) FROM test,lookup
                   WHERE test.id=lookup.id GROUP BY id;

  * Fixed bug in SUM(function) (could cause a core dump).

  * Changed AUTO_INCREMENT placement in the SQL query:

          INSERT into table (auto_field) values (0);

     inserted 0, but it should insert an AUTO_INCREMENT value.

  * mysqlshow.c: Added number of records in table. Had to change the client code a little to fix this.

  * mysql now allows doubled '' or "" within strings for embedded ' or ".

  * New math functions: EXP(), LOG(), SQRT(), ROUND(), CEILING().

Changes in release 3.20.3
-------------------------

  * The configure source now compiles a thread-free client library -lmysqlclient. This is the only library that needs to be linked with client applications.  When using the binary releases, you must link with -lmysql -lmysys -ldbug -lstrings as before.

  * New readline library from bash-2.0.

  * LOTS of small changes to configure and makefiles (and related source).

  * It should now be possible to compile in another directory using VPATH. Tested with GNU Make 3.75.

  * safe_mysqld and mysql.server changed to be more compatible between the source and the binary releases.

  * LIMIT now takes one or two numeric arguments. If one argument is given, it indicates the maximum number of rows in a result. If two arguments are given, the first argument indicates the offset of the first row to return, the second is the maximum number of rows. With this it's easy to do a poor man's next page/previous page WWW application.

  * Changed name of SQL function FIELDS() to ELT(). Changed SQL function INTERVALL() to INTERVAL().

  * Made SHOW COLUMNS a synonym for SHOW FIELDS. Added compatibility syntax FRIEND KEY to CREATE TABLE. In MySQL, this creates a non-unique key on the given columns.

  * Added CREATE INDEX and DROP INDEX as compatibility functions. In MySQL, CREATE INDEX only checks if the index exists and issues an error if it doesn't exist. DROP INDEX always succeeds.

  * mysqladmin.c: added client version to version information.

  * Fixed core dump bug in sql_acl (core on new connection).

  * Removed host, user and db tables from database test in the distribution.

  * FIELD_TYPE_CHAR can now be signed (-128 - 127) or unsigned (0 - 255) Previously, it was always unsigned.

  * Bug fixes in CONCAT() and WEEKDAY().

  * Changed a lot of source to get mysqld to be compiled with SunPro compiler.

  * SQL functions must now have a '(' immediately after the function name (no intervening space). For example, 'user(' is regarded as beginning a function call, and 'user (' is regarded as an identifier user followed by a '(', not as a function call.

Changes in release 3.20.0
-------------------------

  * The source distribution is done with configure and Automake. It will make porting much easier.  The readline library is included in the distribution.

  * Separate client compilation: the client code should be very easy to compile on systems which don't have threads.

  * The old Perl interface code is automatically compiled and installed. Automatic compiling of DBD will follow when the new DBD code is ported.

  * Dynamic language support: mysqld can now be started with Swedish or English (default) error messages.

  * New functions: INSERT(), RTRIM(), LTRIM() and FORMAT().

  * mysqldump now works correctly for all field types (even AUTO_INCREMENT). The format for SHOW FIELDS FROM tbl_name is changed so the Type column contains information suitable for CREATE TABLE.  In previous releases, some CREATE TABLE information had to be patched when recreating tables.

  * Some parser bugs from 3.19.5 (BLOB and TIMESTAMP) are corrected. TIMESTAMP now returns different date information depending on its create length.

  * Changed parser to allow a database, table or field name to start with a number or '_'.

  * All old C code from Unireg changed to C++ and cleaned up. This makes the daemon a little smaller and easier to understand.

  * A lot of small bug fixes done.

  * New INSTALL files (not final version) and some info regarding porting.

Changes in release 3.19.x
=========================

Changes in release 3.19.5
-------------------------

  * Some new functions, some more optimization on joins.

  * Should now compile clean on Linux (2.0.x).

  * Added functions DATABASE(), USER(), POW(), LOG10() (needed for ODBC).

  * In a WHERE with an ORDER BY on fields from only one table, the table is now preferred as first table in a multi-join.

  * HAVING and IS NULL or IS NOT NULL now works.

  * A group on one column and a sort on a group function (SUM(), AVG()...) didn't work together. Fixed.

  * mysqldump: Didn't send password to server.

Changes in release 3.19.4
-------------------------

  * Fixed horrible locking bug when inserting in one thread and reading in another thread.

  * Fixed one-off decimal bug.  1.00 was output as 1.0.

  * Added attribute 'Locked' to process list as info if a query is locked by another query.

  * Fixed full magic timestamp. Timestamp length may now be 14, 12, 10, 8, 6, 4 or 2 bytes.

  * Sort on some numeric functions could sort incorrectly on last number.

  * IF(arg,syntax_error,syntax_error) crashed.

  * Added functions CEILING(), ROUND(), EXP(), LOG() and SQRT().

  * Enhanced BETWEEN to handle strings.

Changes in release 3.19.3
-------------------------

  * Fixed SELECT with grouping on BLOB columns not to return incorrect BLOB info. Grouping, sorting and distinct on BLOB columns will not yet work as expected (probably it will group/sort by the first 7 characters in the BLOB). Grouping on formulas with a fixed string size (use MID() on a BLOB) should work.

  * When doing a full join (no direct keys) on multiple tables with BLOB fields, the BLOB was garbage on output.

  * Fixed DISTINCT with calculated columns.

MySQL での既知のエラーと欠けているデザイン
************************

  * MIT-pthread を使用するとき、他のディレクトリでビルド出来ません。これは MIT-pthread の変更を要求するため、我々は、これを修正しそうにないです。

  * BLOB values can't ``reliably'' be used in GROUP BY or ORDER BY or DISTINCT. これらの場合、 BLOB の比較の際には最初の max_sort_length バイト（デフォルト1024）だけが使用されます。これは mysqld の -O max_sort_length オプションで変更可能です。 A workaround for most cases is to use a substring: SELECT DISTINCT LEFT(blob,2048) FROM tbl_name.

  * Calculation is done with BIGINT or DOUBLE (both are normally 64 bits long). It depends on the function which precision one gets. The general rule is that bit functions are done with BIGINT precision, IF, and ELT() with BIGINT or DOUBLE precision and the rest with DOUBLE precision.  One should try to avoid using bigger unsigned long long values than 63 bits (9223372036854775807) for anything else than bit fields!

  * 全ての文字型のフィールド、BLOB と TEXT はのぞいて、は、検索されるときに最後についているスペースを自動で取り除きます。 CHAR 型ではこれは OK で、この特徴は ANSI SQL92 に従っていると見なされるでしょう。 MySQL のバグは、 VARCHAR でも同様に行ってしまうことです。

  * 一つのテーブルに ENUM と SET フィールドは 255 までしか持てません。

  * safe_mysqld re-directs all messages from mysqld to the mysqld log.  One problem with this is that if you execute mysqladmin refresh to close and reopen the log, stdout and stderr are still redirected to the old log. If you use --log extensively, you should edit safe_mysqld to log to 'hostname'.err instead of 'hostname'.log so you can easily reclaim the space for the old log by deleting the old one and executing mysqladmin refresh.

  * In the UPDATE statement, columns are updated from left to right. If you refer to a updated column, you will get the updated value instead of the original value. For example:

          mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1

     will update KEY with 2 instead of with 1.

  * You can't use temporary tables more than once in the same query.

          select * from temporary_table, temporary_table as t2;

  * Because MySQL allows you to work with table types that doesn't support transactions (and thus can't rollback data) some things behaves a little different in MySQL than in other SQL servers: (This is just to ensure that MySQL never need to do a rollback for a SQL command).  This may be a little akward at times as column values must be checked in the application, but this will actually give you a nice speed increase as it allows MySQL to do some optimizations that otherwice would be hard to do.

     If you set a colum to a wrong value, MySQL will instead of doing a rollback instead store the best possible value in the column.

       * If you try to store a value outside of the range in a numerical column, MySQL will instead store the smallest or biggest possible value in the column.

       * If you try to store a string, that doesn't start with a number, into a numerical column MySQL will store 0 into it.

       * If you try to to store NULL into a column that doesn't take NULL values, MySQL will store 0 or '' (empty string) in it instead. (This behavour can however be changed with the -DDONT_USE_DEFAULT_FIELDS compile option).

       * MySQL allows you to store some wrong date values into DATE and DATETIME columns. (Like 2000-02-31 or 2000-02-00). If the date is totally wrong, MySQL will store the special 0000-00-00 date value in the column.

       * If you set an enum to an not supported value, it will be set to the error value 'empty string', with numeric value 0.

  * If you execute a PROCEDURE on a query with returns an empty set then in some cases the PROCEDURE will not transform the columns.

The following is known bugs in earlier versions of MySQL:

  * You can get a hanged thread if you do a DROP TABLE on a table that is one among many tables that is locked with LOCK TABLES.

  * In the following case you can get a core dump:

      1. Delayed insert handler has pending inserts to a table.

      2. LOCK table with WRITE

      3. FLUSH TABLES

  * Before MySQL 3.23.2 an UPDATE that updated a key with a WHERE on the same key may have failed because the key was used to search for records and the same row may have been found multiple times:

          UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100;

     A workaround is to use:

          mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100;

     This will work because MySQL will not use index on expressions in the WHERE clause.

  * MySQL 3.23 より前では、全ての数値型で、少数部分が削られてしまいます。これは、そのフィールドが何桁の小数部を持つか、定義しなければならなかった、ということです。 全ての結果は10進の数で正しく返ってきました。

For platform-specific bugs, see the sections about compiling and porting.

MySQL に将来加えたいもの (The TODO)
**************************

このリストのすべては、それが終わるだろう順番に書かれています。もしあなたが優先順位に影響を及ぼしたければ、どうかライセンスかサポート登録して、我々にあなたがより速く欲しいものを言ってください。 See Licensing and Support.

近い将来に完了せねばならないもの
================

  * Fail safe replication.

  * Optimize, test and document transactions safe tables

  * 副問い合わせ。 select id from t where grp in (select grp from g where u > 100)

  * mysqld に、同時に多くのキャラクタ・セットをサポートさせる

  * もし他の disk に symlink されているテーブルに対して ALTER TABLE を実行した場合、一時テーブルをこの disk に作成するようにする

  * RENAME table as table, table as table [,...]

  * Allow users to change startup options.

  * FreeBSD and MIT-pthreads;  Do sleeping threads take CPU?

  * Check if locked threads take any CPU.

  * Change to use mkstemp() instead of tempnam() for system that supports the call. We need to add a my_mkstemp() function in mysys and also change the cache code to not create the filename until we do the actual open.

  * キーの部分での JOIN を許す (最適化問題)

  * Entry for DECRYPT().

  * .frm ファイルに FOREIGN キーの定義を記憶する。

  * サーバーサイドのカーソル

  * Check if lockd works with modern Linux kernels; If not, we have to fix lockd!  To test this, start mysqld with --enable-locking and run the different fork* test suits. They shouldn't give any errors if lockd works.

  * Allow SQL variables in LIMIT, like in LIMIT @a,@b.

  * 自動で DEFAULT 値をフィールドに追加しない。 DEFAULT を持たないフィールドを含まない  INSERT の使用はエラーにする

  * クエリーと結果のキャッシュ。 This should be done as a separated module that examines each query and if this is query is in the cache the cached result should be returned.  When one updates a table one should remove as few queries as possible from the cache. This should give a big speed bost on machines with much RAM where queries are often repeated (like WWW applications). One idea would be to only cache queries of type: SELECT CACHED ....

  * Fix libmysql.c to allow two mysql_query() commands in a row without reading results or give a nice error message when one does this.

  * BIT 型を 1 bit 取るように最適化 （今 BIT は一文字とります）

  * なぜいくつかの FreeBSD システムで MIT-pthreads ctime() が動かないか検証。

  * Check if locked threads take any CPU.

  * 更新に ORDER BY を追加。 This would be handy with functions like: generate_id(start,step).

  * TIMESTAMP と AUTO_INCREMENT フィールドを更新しないように、 IMAGE オプションを LOAD DATA INFILE に追加。

  * LOAD DATA INFILE に以下の文を理解させる：

          LOAD DATA INFILE 'file_name.txt' INTO TABLE tbl_name
          TEXT_FIELDS (text_field1, text_field2, text_field3)
          SET table_field1=concatenate(text_field1, text_field2), table_field3=23
          IGNORE text_field3

  * 本当の VARCHAR のサポート (MyISAM にはこのサポートが既にあります)

  * mysql から自動的に netscape に出力

  * LOCK DATABASES. (いろいろなオプション付きで)

  * NATURAL JOIN.

  * Change sort to allocate memory in ``hunks'' to get better memory utilization.

  * DECIMAL と NUMERIC 型は 指数表示の数字を読むことが出来ません：これを修正するには、 Field_decimal::store(const char *from,uint len) を再コードしなくてはなりません

  * Fix mysql.cc to do fewer malloc() calls when hashing field names.

  * 関数： ADD_TO_SET(value,set) と REMOVE_FROM_SET(value,set)

  * t1 JOIN t2 ON ... と t1 JOIN t2 USING ... の使用の追加。現在、 LEFT JOIN のみが使用できます。

  * unsigned long long 型の完全なサポート。

  * CASE 関数

  * show status にもっと多くの変数を。 INSERT/DELETE/UPDATE 文のカウント。レコードの読み込みと更新のカウント。 1テーブルでのSELECTとJOINを伴ったSELECTのカウント。 SELECT 中のテーブルの数のカウント。キーバッファの reaad/write のヒット数(理論値と実数)のカウント。 ORDER BY, GROUP BY, 一時テーブルの作成のカウント

  * もしクエリの途中で mysql を中断した場合、あなたは他から接続して走っているクエリを kill しなくてはなりません。最終的には、こういったことはサーバー内で検知されるように試みるべきです。

  * テーブルの情報のためのハンドラーインターフェースの追加。それをシステムテーブルとして使えるように。これはもしあなたがすべてのテーブルについて情報をリクエストした場合は少し遅くなるでしょう。 しかしとても柔軟性があります。基本的なテーブルへの SHOW INFO FROM tbl_name では実行されるべきです。

  * UNICODE のサポート

  * NATURAL JOIN.

  * Oracle like CONNECT BY PRIOR ... to search hierarchy structures.

  * RENAME DATABASE

  * mysqladmin copy database new-database.

  * Processlist は queries/thread の数を表示すべき。

  * DELETE と REPLACE オプションを UPDATE 文に追加。 ( これは更新中に起こったキーの重複エラーのあるレコードを全て削除するでしょう).

  * Change the format of DATETIME to store fractions of seconds.

  * ANSI92 と ODBC 3.0 型でかけている物全てを追加。

  * Change table names from empty strings to NULL for calculated columns.

  * Don't use 'Item_copy_string' on numerical values to avoid number->string->number conversion in case of: SELECT COUNT(*)*(id+0) FROM table_name GROUP BY id

  * Make it possible to use the new GNU regexp library instead of the current one (The GNU library should be much faster than the old one).

  * Change that ALTER TABLE doesn't abort clients that executes INSERT DELAYED.

  * Allow select a from crash_me left join crash_me2 using (a); In this case a is assumed to come from the crash_me table.

  * LOAD DATA INFILE 'file_name' INTO TABLE 'table_name' ERRORS TO err_table_name which would cause any errors/warnings to be logged into the err_table_name table. That table would have a structure like:

     line_number    - line number in data file
     error_message  - the error/warning message
     and maybe
     data_line      - the line from the data file

  * Fix that when columns referenced in an UPDATE clause contains the old values before the update started.

  * Allow update of varibles in UPDATE statements. For example: UPDATE TABLE foo SET @a=a+b,a=@a, b=@a+c

  * myisamchk, REPAIR and OPTIMIZE TABLE should be able to handle cases where the data and/or index files are symbolic links.

  * Add simulation of pread()/pwrite() on windows to enable concurrent inserts.

いつかは行うべきもの
==========

  * Implement function: get_changed_tables(timeout,table1,table2,...)

  * Atomic updates; This includes a language that one can even use for a set of stored procedures.

  * update items,month set items.price=month.price where items.id=month.id;

  * Change reading through tables to use memmap when possible. Now only compressed tables use memmap.

  * Add a new privilege 'Show_priv' for SHOW commands.

  * Make the automatic timestamp code nicer.  Add timestamps to the update log with SET TIMESTAMP=#;

  * Use read/write mutex in some places to get more speed.

  * Full foreign key support. One probably wants to implement a procedural language first.

  * Simple views (first on one table, later on any expression).

  * Automatically close some tables if a table, temporary table or temporary files gets error 23 (not enough open files).

  * When one finds a field=#, change all occurrences of field to #.  Now this is only done for some simple cases.

  * Change all const expressions with calculated expressions if possible.

  * Optimize key = expression. At the moment only key = field or key = constant are optimized.

  * Join some of the copy functions for nicer code.

  * Change sql_yacc.yy to an inline parser to reduce its size and get better error messages (5 days).

  * Change the parser to use only one rule per different number of arguments in function.

  * Use of full calculation names in the order part. (For ACCESS97)

  * UNION, MINUS, INTERSECT and FULL OUTER JOIN. (Currently only LEFT OUTER JOIN is supported)

  * Allow UNIQUE on fields that can be NULL.

  * SQL_OPTION MAX_SELECT_TIME=# to put a time limit on a query.

  * Make the update log to a database.

  * Negative LIMIT to retrieve data from the end.

  * Alarm around client connect/read/write functions.

  * Make a mysqld version which isn't multithreaded (3-5 days).

  * Please note the changes to safe_mysqld: according to FSSTND (which Debian tries to follow) PID files should go into /var/run/<progname>.pid and log files into /var/log. It would be nice if you could put the "DATADIR" in the first declaration of "pidfile" and "log", so the placement of these files can be changed with a single statement.

  * Better dynamic record layout to avoid fragmentation.

  * UPDATE SET blob=read_blob_from_file('my_gif') where id=1;

  * Allow a client to request logging.

  * Add use of zlib() for gzip-ed files to LOAD DATA INFILE.

  * Fix sorting and grouping of BLOB columns (partly solved now).

  * Stored procedures.  This is currently not regarded to be very important as stored procedures are not very standardized yet. Another problem is that true stored procedures make it much harder for the optimizer and in many cases the result is slower than before We will, on the other hand, add a simple (atomic) update language that can be used to write loops and such in the MySQL server.

  * Change to use semaphores when counting threads.  One should first implement a semaphore library to MIT-pthreads.

  * Don't assign a new AUTO_INCREMENT value when one sets a column to 0. Use NULL instead.

  * Add full support for JOIN with parentheses.

  * Reuse threads for systems with a lot of connections.

  * As an alternative for one thread / connection manage a pool of threads to handle the queries.

  * Allow one to get more than one lock with GET_LOCK.  When doing this, one must also handle the possible deadlocks this change will introduce.

Time is given according to amount of work, not real time. TcX's main business is the use of MySQL not the development of it. But because TcX is a very flexible company, we have put a lot of resources into the development of MySQL.

行う予定のない物
========

  * Nothing;  In the long run we plan to be fully ANSI 92 / ANSI 99 compliant.

他のシステムへの移植について
**************

A working Posix thread library is needed for the server. On Solaris 2.5 we use Sun PThreads (the native thread support in 2.4 and earlier versions are not good enough) and on Linux we use LinuxThreads by Xavier Leroy, Xavier.Leroy@inria.fr.

The hard part of porting to a new Unix variant without good native thread support is probably to port MIT-pthreads. See mit-pthreads/README and Programming POSIX Threads (http://www.humanfactor.com/pthreads/).

The MySQL distribution includes a patched version of Provenzano's Pthreads from MIT (see MIT Pthreads web page (http://www.mit.edu:8001/people/proven/pthreads.html)). This can be used for some operating systems that do not have POSIX threads.

It is also possible to use another user level thread package named FSU Pthreads (see FSU Pthreads home page (http://www.informatik.hu-berlin.de/~mueller/pthreads.html)). This implementation is being used for the SCO port.

See the thr_lock.c and thr_alarm.c programs in the mysys directory for some tests/examples of these problems.

Both the server and the client need a working C++ compiler (we use gcc and have tried SparcWorks). Another compiler that is known to work is the Irix cc.

To compile only the client use ./configure --without-server.

There is currently no support for only compiling the server, nor is it likly to be added unless someone has a good reason for it.

If you want/need to change any Makefile or the configure script you must get Automake and Autoconf. We have used the automake-1.2 and autoconf-2.12 distributions.

All steps needed to remake everything from the most basic files.

     /bin/rm */.deps/*.P
     /bin/rm -f config.cache
     aclocal
     autoheader
     aclocal
     automake
     autoconf
     ./configure --with-debug --prefix='your installation directory'

     # The makefiles generated above need GNU make 3.75 or newer.
     # (called gmake below)
     gmake clean all install init-db

If you run into problems with a new port, you may have to do some debugging of MySQL! See Debugging server.

Note: Before you start debugging mysqld, first get the test programs mysys/thr_alarm and mysys/thr_lock to work.  This will ensure that your thread installation has even a remote chance to work!

MySQL server のデバッグ
==================

もしあなたが MySQL のとても新しいある機能を使っている場合、 --skip-new (これは全く新しい、潜在的に危険な機能を無効にします) または  --safe-mode (これは問題を生じさせるかもしれない多くの最適化を無効にします) オプションで mysqld を実行させることができます。 See Crashing.

もし mysqld が起動しないようなら、 my.cnf が無いかチェックしてください。 my.cnf の引数は mysqld --print-defaults でチェックできます。また mysqld --no-defaults ... で起動することにより、 my.cnf を無視することが可能です。

もしあるとても特殊な問題があれば、あなたは、いつも MySQL をデバッグするよう試みることができます。 これを行うには、 MySQL を --with-debug オプション付きで configure しなくてはなりません。 MySQL がデバッギングを有効にしてコンパイルされているかを知るには、 mysqld --help とします。 もし --debug フラグがリストされていればデバッグが有効です。 mysqladmin ver も mysqld のバージョンをリストできます。 この場合は mysql ... -debug と、バージョン番号に表示されるでしょう。

gcc か egcs の場合、推奨する configure のラインは：

     CC=gcc CFLAGS="-O6" CXX=gcc CXXFLAGS="-O6 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug

これは libstdc++ ライブラリと C++ の例外による問題を避けることが出来るでしょう。 (many compilers have problems with C++ exceptions in threaded code).

If mysqld stops crashing when you compile it with --with-debug, you have probably found a compiler bug or a timing bug within MySQL.  In this case you can try to add -g to the CFLAGS and CXXFLAGS variables above and not use --with-debug. If mysqld now dies, you can at least attach to it with gdb or use gdb on the core file to find out what happened.

もし mysqld サーバーのクラッシュを直に引き起こすことができるなら、あなたはこのトレースファイルを作成することができます：

mysqld サーバーをトレースログファイル /tmp/mysql.trace オプションで起動。このログファイルはとても大きくなります。

mysqld --debug --log

か

mysqld --debug=d,info,error,query,general,where:O,/tmp/mysql.trace

これは重要なタグのみを出力します。

MySQL をデバッグで configure すると、自動で多くの安全な検査関数が enable になります。 これは  mysqld の状態をモニターできます。もしそれら関数がなにか ``予期せぬこと'' を発見したら、それらを stderr に書き出します。 これは safe_mysqld が受け取って error ログに書き出します！ このことはどういうことかというと、 MySQL に予期せぬことが起きた場合、まず最初にすべきことは、 MySQL をデバッグ有効にして configure することです！ （次に、もちろん、 mysql@lists.mysql.com にメールを送り、help を聞くことです。 全てのバグレポート、MySQL のバージョンに関連する質問は、 mysqlbug スクリプトを使用してください！）

ほとんどのシステムでは、もし mysqld がクラッシュするなら、 gdb から mysqld を起動させて多くの情報を得ることが可能です。

Linux 上でのいくつかの gdb バージョンでは、 mysqld スレッドのデバッグを可能にする場合、 run --one-thread を使用しなくてはなりません。この場合、一度にただ一つのactiveなスレッドだけを持つことになります。

It's very hard to debug MySQL under gdb if you do a lot of new connections the whole time as gdb doesn't free the memory for old threads.  You can avoid this problem by starting mysqld with -O thread_cache_size= 'max_connections +1'.  In most cases just using -O thread_cache_size= 5' will help a lot!

もし Linux 上で gdb 4.17.x を使用しているなら、 .gdb ファイルをいかにしたがって、カレントのディレクトリーにインストールすべきです：

     set print sevenbit off
     handle SIGUSR1 nostop noprint
     handle SIGUSR2 nostop noprint
     handle SIGWAITING nostop noprint
     handle SIGLWP nostop noprint
     handle SIGPIPE nostop
     handle SIGALRM nostop
     handle SIGHUP nostop
     handle SIGTERM nostop noprint

If you have problems debugging threads with gdb, you should download gdb 5.x and try this instead. The new gdb version has very improved thread handling!

以下は mysqld のデバッグ例です：

     shell> gdb /usr/local/libexec/mysqld
     gdb> run
     ...
     back   # mysqld がクラッシュした際、これを行います
     info locals
     up
     info locals
     up
     ...
     (until you get some information about local variables)

     quit

上記の出力を、 mysqlbug で作成したメールに含み、そして mysql@lists.mysql.com. に送ってください。

もし mysqld がハングするなら、 strace や /usr/proc/bin/pstack のようなシステムツールを使用して mysqld がどこでハングしているか調べることができます。

もし mysqld が CPU や メモリー を食い始めたり、``ハング'' したりするなら、 mysqladmin processlist status を使用して誰かが多くの時間のかかるクエリを実行しているか確かめることが出来ます。パフォーマンスの問題や新しいクライアントが接続できないときの問題ともしあなたが考えるなら、いくつかのウインドウで mysqladmin -i10 processlist status を実行するのはよい考えでしょう。

もし mysqld が死んだりハングしたりするなら、 mysqld を --log で起動すべきです。 再び mysqld が死んだら、あなたはログファイル中の、 mysqld を kill するクエリをチェックします。 mysqld を --log オプションで起動する前に、全てのテーブルを myisamchk でチェックすべきです。（前のクラッシュ時にテーブルが壊れているかもしれないので） See Maintenance.

もし mysqld --log でログファイルを使用するなら、'hostname' ログファイル、これはデータベースディレクトリにありますが、これをチェックし、問題を引き起こすクエリを見つけます。 mysqld が適切にインデックスを使用するのに時間がとてもかかる全ての SELECT 文を EXPLAIN で実行することを試みます。 See EXPLAIN. また、mysql コマンドラインでは出来なかった、複雑なクエリもテストすべきです。

もしエラーログファイル(hostname.err)中に mysqld restarted という文があるなら、 mysqld を失敗させるクエリを見つけます。もしこれが起きるなら、myisamchk (see Maintenance) で全てのテーブルをチェックし、 MySQL ログファイルにあるそのクエリをテストすべきです。もしそのようなクエリをみつけたなら、まず最初に最新の MySQL にアップグレードしてみてください。 もしそれでもだめで、かつ mysql メーリングリストのアーカイブにもなにも見つけることが出来なかったなら、 mysql@lists.mysql.com にバグレポートを出すべきです。 メーリングリストのアーカイブへのリンクは MySQL documentation page (http://www.mysql.com/doc.html).

もし不正なテーブルをえたり、 mysqld が常にいくつかの update コマンドで失敗するなら、以下のようにしてこのバグの再現をテストします：

  * mysqld daemon 停止 (mysqladmin shutdown で)

  * myisamchk -s database/*.MYI で全テーブルをチェック. myisamchk -r database/table.MYI で悪いテーブルを修正。

  * mysqld を --log-update でスタート. See Update log.

  * 壊れたテーブルを得た時、mysqld server を停止。

  * バックアップをリストア

  * mysqld server を --log-update なしで 起動。

  * mysql < update-log で再実行。  update log は MySQL データベースディレクトリに your-hostname.# という名前で保存されています。

  * これでもし再びテーブルがおかしくなるなら、 ISAM コード中の再現可能なバグを見つけたことになります！このテーブルと update log を ftp://www.mysql.com/pub/mysql/secret に FTP で put します。 われわれはこれをできる限り速く修正します！

mysqladmin debug コマンドは使用中のロック、使用しているメモり、クエリの使用の情報を、mysql ログファイルにいくつかダンプしますこれはいくつかの問題解決に役立ちます。 このコマンドは、 MySQL をデバッグ可能でコンパイルしていなくても、いくつかの役立つ情報も提供します。

いくつかのテーブルでだんだん遅くなる問題であるなら、 OPTIMIZE TABLE か myisamchk でテーブルを修復し、最適化を試みるべきです。遅いクエリは、 EXPLAIN でもチェックできます。 See Maintenance.

このマニュアルの OS 固有の問題 の節も読むべきです。 See Source install system issues.

もし Perl DBI を使用しているなら、 trace メソッド、あるいはDBI_TRACE 環境変数でデバッグ情報を有効にできます。 See Perl DBI Class.

Debugging a MySQL client
========================

To be able to debug a MySQL client with the integrated debug package, you should configure MySQL with --with-debug. See configure options.

Before running a client, you should set the MYSQL_DEBUG environment variable:

     shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace
     shell> export MYSQL_DEBUG

This causes clients to generate a trace file in /tmp/client.trace.

If you have problems with your own client code, you should attempt to connect to the server and run your query using a client that is known to work.  Do this by running mysql in debugging mode (assuming you have compiled MySQL with debugging on):

     shell> mysql --debug=d:t:O,/tmp/client.trace

This will provide useful information in case you mail a bug report. See Bug reports.

If your client crashes at some 'legal' looking code, you should check that your mysql.h include file matches your mysql library file. A very common mistake is to use an old mysql.h file from an old MySQL installation with new MySQL library.

Comments about RTS threads
==========================

I have tried to use the RTS thread packages with MySQL but stumbled on the following problems:

They use an old version of a lot of POSIX calls and it is very tedious to make wrappers for all functions. I am inclined to think that it would be easier to change the thread libraries to the newest POSIX specification.

Some wrappers are already written. See mysys/my_pthread.c for more info.

At least the following should be changed:

pthread_get_specific should use one argument. sigwait should take two arguments. A lot of functions (at least pthread_cond_wait, pthread_cond_timedwait) should return the error code on error. Now they return -1 and set errno.

Another problem is that user-level threads use the ALRM signal and this aborts a lot of functions (read, write, open...). MySQL should do a retry on interrupt on all of these but it is not that easy to verify it.

The biggest unsolved problem is the following:

To get thread-level alarms I changed mysys/thr_alarm.c to wait between alarms with pthread_cond_timedwait(), but this aborts with error EINTR.  I tried to debug the thread library as to why this happens, but couldn't find any easy solution.

If someone wants to try MySQL with RTS threads I suggest the following:

  * Change functions MySQL uses from the thread library to POSIX. This shouldn't take that long.

  * Compile all libraries with the -DHAVE_rts_threads.

  * Compile thr_alarm.

  * If there are some small differences in the implementation, they may be fixed by changing my_pthread.h and my_pthread.c.

  * Run thr_alarm. If it runs without any ``warning'', ``error'' or aborted messages, you are on the right track. Here follows a successful run on Solaris:

          Main thread: 1
          Tread 0 (5) started
          Thread: 5  Waiting
          process_alarm
          Tread 1 (6) started
          Thread: 6  Waiting
          process_alarm
          process_alarm
          thread_alarm
          Thread: 6  Slept for 1 (1) sec
          Thread: 6  Waiting
          process_alarm
          process_alarm
          thread_alarm
          Thread: 6  Slept for 2 (2) sec
          Thread: 6  Simulation of no alarm needed
          Thread: 6  Slept for 0 (3) sec
          Thread: 6  Waiting
          process_alarm
          process_alarm
          thread_alarm
          Thread: 6  Slept for 4 (4) sec
          Thread: 6  Waiting
          process_alarm
          thread_alarm
          Thread: 5  Slept for 10 (10) sec
          Thread: 5  Waiting
          process_alarm
          process_alarm
          thread_alarm
          Thread: 6  Slept for 5 (5) sec
          Thread: 6  Waiting
          process_alarm
          process_alarm

          ...
          thread_alarm
          Thread: 5  Slept for 0 (1) sec
          end

スレッドパッケージ間の違いは何？
================

MySQL は使用されるスレッドパッケージに非常に依存しています。そのため、MySQL に良いプラットフォームを選択する時には、スレッドパッケージが非常に重要です。

少なくとも3つのタイプのスレッドパッケージがあります：

  * シングルプロセス内のユーザスレッド。スレッド切替えはアラームで管理され、スレッドライブラリはロックを伴う非スレッド安全関数のすべてを管理します。動作中スレッドがデータを待つ必要がある場合、read, write そして select は、通常、他のスレッドに切替えるスレッド固有の select で管理されます。もしユーザ・スレッドパッケージが標準ライブラリ (FreeBSD と BSDI スレッド) に統合されているなら、スレッドパッケージのオーバーヘッドは、全ての非安全コールをマップしなければならないスレッドパッケージ(MIT-スレッド, FSU-スレッド, RTS スレッド) よりも少なくなります。他の環境(例えば SCO)では、全てのシステムコールはスレッド安全なので、マッピングはとても簡単に行なわれます(SCO 上の FSU-スレッド)。 Downside: 全てのマップされるコールは少し時間がかかり、全ての状況を処理可能にすることは、とても困難です。通常、スレッドパッケージによって処理できないシステムコールがいくつかあります (MIT-スレッドとソケットのように)。 スレッドスケジューリングは常に最適というわけではあ りません。

  * 別のプロセスないのユーザスレッド。スレッド切替えはカーネルによって行なわれ、全てのデータはスレッド間で共有されます。スレッドパッケージは、スレッ ド間のデータ共有を許可するために標準スレッドコールを管理します。 LinuxThreads はこの方法を使用しています。 Downside: 多くのプロセス。スレッド生成は遅いです。もし一つのスレッドが死ぬと、残りは通常ハングして残り、再起動前に それら全てを kill する必要があります。スレッド切替えはいくらか高価(expensive)です。

  * カーネルスレッド。スレッド切替えはスレッドライブラリかカーネルによって処理され、とても速いです。 全ては一つのプロセス内で行なわれますが、いくつかのシステムでは、ps が異なったスレッドを示します。もし一つのスレッドがアボートした場合、プロセス全体がアボートします。多くのシステムコールはスレッド安全で、オーバーヘッドはとても少ないです。 Solaris, HP/UX, AIX そして OSF1 がカーネルスレッドを持っています。

いくつかのシステムでは、カーネルスレッドは、システムライブラリ内で、ユーザレベルスレッドの統合によって管理されます。この場合、スレッド切替えはスレッドライブラリによってだけ行なわれ、カーネルは実際には 'thread aware' ではありません。

MySQL の正規表現の文法について
******************

A regular expression (regex) is a powerful way of specifying a complex search.

MySQL は正規表現の regular Henry Spencers 実装を使用します。そしてこれは POSIX 1003.2 に一致することが目的です。MySQL は拡張 バージョンを使用します。

これは詳細を省いた簡単なリファレンスです。さらに正確な情報は Henry Spencers regex(7) マニュアルを見てください。これはソース配布に含まれています。 See Credits.

正規表現は文字列の組み合わせて記述されます。もっとも簡単な場合は、非特殊文字の一文字です。例えば、 regexp hello は hello と適合し、 他には適合しません。

簡単でない正規表現は、1つの文字列以上に適合できるような、いくつかの特殊な構成を使用します。例えば、regexp hello|word は文字列 hello と文字列 word に適合します。

そしてさらに複雑な例 regexp B[an]*s は、文字列 Bananas, Baaaaas, Bs のどれか、そして B で始まり a や n が任意の数続き、s で終わるような他の文字列に適合します。

正規表現では、次の特殊文字/構成が使用できます：

^
     文字列全体の始まり。

          mysql> select "fo\nfo" REGEXP "^fo$";           -> 0
          mysql> select "fofo" REGEXP "^fo";              -> 1

$
     文字列全体の終り。

          mysql> select "fo\no" REGEXP "^fo\no$";         -> 1
          mysql> select "fo\no" REGEXP "^fo$";            -> 0

.
     任意の文字 (改行含む)。

          mysql> select "fofo" REGEXP "^f.*";             -> 1
          mysql> select "fo\nfo" REGEXP "^f.*";           -> 1

a*
     0個以上の文字 a の並び。

          mysql> select "Ban" REGEXP "^Ba*n";             -> 1
          mysql> select "Baaan" REGEXP "^Ba*n";           -> 1
          mysql> select "Bn" REGEXP "^Ba*n";              -> 1

a+
     文字 a が 1個以上並ぶ。

          mysql> select "Ban" REGEXP "^Ba+n";             -> 1
          mysql> select "Bn" REGEXP "^Ba+n";              -> 0

a?
     0 または 1個の文字 a。

          mysql> select "Bn" REGEXP "^Ba?n";              -> 1
          mysql> select "Ban" REGEXP "^Ba?n";             -> 1
          mysql> select "Baan" REGEXP "^Ba?n";            -> 0

de|abc
     de か abc にマッチ。

          mysql> select "pi" REGEXP "pi|apa";             -> 1
          mysql> select "axe" REGEXP "pi|apa";            -> 0
          mysql> select "apa" REGEXP "pi|apa";            -> 1
          mysql> select "apa" REGEXP "^(pi|apa)$";        -> 1
          mysql> select "pi" REGEXP "^(pi|apa)$";         -> 1
          mysql> select "pix" REGEXP "^(pi|apa)$";        -> 0

(abc)*
     文字列 abc の 0 回以上の並びにマッチ。

          mysql> select "pi" REGEXP "^(pi)*$";            -> 1
          mysql> select "pip" REGEXP "^(pi)*$";           -> 0
          mysql> select "pipi" REGEXP "^(pi)*$";          -> 1

{1}
{2,3}
     多くの発生に適合する regexp の記述する一般的な方法。 The is a more general way of writing regexps that match many occurrences of the previous atom.

     a*
          Can be written as a{0,}.

     a+
          Can be written as a{1,}.

     a?
          Can be written as a{0,1}.

     さらに正確には、1つの整数 i とコンマ無しを含む修飾が続くアトムは、厳密にアトムに適合する i 回の並びに適合します。整数 i とコンマを含む修飾が続くアトムは、アトムに適合する i 回以上の並びに適合します。整数 i と j を含む装飾が続くアトムは、アトムに適 合する i 回から j 回までの並びに適合します。

     両方の引数は 0 >= value <= RE_DUP_MAX (default 255) でないとい けません。そして、2つある場合、2番目は1番目よりも大きいか同じでないといけません。

[a-dX]
[^a-dX]
     a, b, c, d, X のどれかの文字 (^ を使用するとどれでもない文字) にマッチ。 ] 文字を含めるには、 [ のあとに続いてすぐに書く必要があります。

     - 文字を含めるには最初か最後に書く必要があります。 [0-9] は任意 の10進数値に適合します。 [] ペア内部の定義された意味を持たない全ての文字は、特殊な意味を持たず、それ自身にだけ適合します。

          mysql> select "aXbc" REGEXP "[a-dXYZ]";         -> 1
          mysql> select "aXbc" REGEXP "^[a-dXYZ]$";       -> 0
          mysql> select "aXbc" REGEXP "^[a-dXYZ]+$";      -> 1
          mysql> select "aXbc" REGEXP "^[^a-dXYZ]+$";     -> 0
          mysql> select "gheis" REGEXP "^[^a-dXYZ]+$";    -> 1
          mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$";   -> 0

[[.characters.]]
     照合要素(collating element)の文字の並び。並びは括弧表現リストの一つの要素です。複数文字の照合要素を含む括弧表現は一つ以上の文字に適合します。例えば、照合並びが ch 照合要素を含む場合、正規表現 [[.ch.]]*c は chchcc の最初の5文字に適合します。

[=character_class=]
     同等のクラス。その一つと等しい全ての照合要素の文字の並びを表します。それ自身も含みます。

     例えば、o と (+) が同等クラスのメンバである場合、 [[=o=]], [[=(+)=]], [[=(+)=]] は全て同義語です。同等クラスは範囲の終了位置にはなりません。

[:character_class:]
     括弧表現の内部で、[: と :] で括られた文字クラスの名前は、そのクラスに属する全ての文字のリストを表します。標準文字クラス名は:

     alnum   digit   punct
     alpha   graph   space
     blank   lower   upper
     cntrl   print   xdigit

     これらは ctype(3) マニュアルページに記載されている文字クラスを表します。ロケールが他のを提供することもあります。文字クラスは範囲の終了位置としては使えません。

          mysql> select "justalnums" REGEXP "[[:alnum:]]+";       -> 1
          mysql> select "!!" REGEXP "[[:alnum:]]+";               -> 0

[[:<:]]
[[:>:]]
     それぞれ、単語の始めと終りの空文字列に適合します。単語は、単語文字が前後にない単語文字の並びとして定義されます。単語文字は alnum 文字 (ctype(3) で定義されます) と下線(underscore ； _)です。

          mysql> select "a word a" REGEXP "[[:<:]]word[[:>:]]";      -> 1
          mysql> select "a xword a" REGEXP "[[:<:]]word[[:>:]]";     -> 0

     mysql> select "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1

UNIREG とは何か？
************

UNIREG は我々の tty インタフェースビルダです。これは我々の (MySQL で使用される) ISAM への低レベル接続に使用します。これがとても速いためです。これは 1979 年から (UNIX 上で C は 1986 年から) 存在していました。

UNIREG は次のコンポーネントを持ちます:

  * 一つのテーブルの参照。更新/照会に。

  * 複数のテーブルの参照 (1スクロール範囲で)。

  * テーブルの生成 (MySQL では作成できない沢山の項目タグで)。これは (tty で の) WYSIWYG です。スクリーンと UNIREG プロンプトを項目ごとにデザインできます。

  * レポート生成。

  * 沢山のユーティリティ (テキストファイルへのテーブルの高速エキスポート/インポー ト、テーブル内容の解析...)。

  * 強力な複数テーブルの更新 (我々は頻繁にこれを使用します)。 BASIC に似た言語で多 くの機能を持っています。

  * 動的な言語(現在はスウェーデン語とフィンランド語)。誰かが英語バージョンを欲しいのなら、翻訳しないといけないいくつかのファイルがあります。

  * 対話的にまたはバッチで更新を実行する機能。

  * Emacs に似たキー定義。キーボードマクロ付き。

  * 全部で 800k のバイナリ。

  * convform ユーティリティ。異なる文字セット間で .frm とテキストファイルを変換します。

  * mpack_isam ユーティリティ。 ISAM テーブルをパックします(50-80% 小さくできます)。このテーブルは普通のテーブルと同じように MySQL で読み込みできます。 1 レコー ドだけ圧縮解除 / アクセスする必要があります。 BLOB や TEXT 項目の操作と更新は(まだ)できません。

我々は、UNIREG インタフェースで多くの我々の製品データベースを更新し、 MySQL (そしていくつかの特殊な場合、UNIREG レポート生成プログラム) を通して Web ページを提供します。

UNIREG は 3M のディスク領域を使用し、少なくとも次のプラットフォーム上で動作します: SUN OS 4.x, Solaris, Linux, HP/UX, ICL Unix, DNIX, SCO そし て MSDOS。

UNIREG は現在スウェーデン語とフィンランド語でのみ有効です。

UNIREG の価格は 10,000 スウェーデン kr (約 1500$ US) です。ただし、これはサポートを含みます。 UNIREG はバイナリで配布されます (しかし全ての ISAM ソースは MySQL 内に見つけられます)。通常、我々は顧客のサイトにて顧客用にバイナリをコンパイルします。

新しい開発は MySQL に集中しています。

The MySQL server license for non Microsoft operating systems
************************************************************

MySQL FREE PUBLIC LICENSE
(Version 4, March 5, 1995)

Copyright (C) 1995, 1996 TcX AB & MySQL Finland AB & Detron HB
Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN
All rights reserved.

NOTE: This license is not the same as any of the GNU Licenses published by the Free Software Foundation. Its terms are substantially different from those of the GNU Licenses. If you are familiar with the GNU Licenses, please read this license with extra care.

This License applies to the computer program known as "MySQL".  The "Program", below, refers to such program, and a "work based on the Program" means either the Program or any derivative work of the Program, as defined in the United States Copyright Act of 1976, such as a translation or a modification. The Program is a copyrighted work whose copyright is held by TcX Datakonsult AB and MySQL Finland AB and Detron HB.

This License does not apply when running "MySQL" on any Microsoft operating system. Microsoft operating systems include all versions of Microsoft Windows NT and Microsoft Windows.

BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.

 1. Licenses.

     Licensor hereby grants you the following rights, provided that you comply with all of the restrictions set forth in this License and provided, further, that you distribute an unmodified copy of this License with the Program:

      a. You may copy and distribute literal (i.e., verbatim) copies of the Program's source code as you receive it throughout the world, in any medium.

      b. You may modify the Program, create works based on the Program and distribute copies of such throughout the world, in any medium.

 2. Restrictions.

     This license is subject to the following restrictions:

      a. Distribution of the Program or any work based on the Program by a commercial organization to any third party is prohibited if any payment is made in connection with such distribution, whether directly (as in payment for a copy of the Program) or indirectly (as in payment for some service related to the Program, or payment for some product or service that includes a copy of the Program "without charge"; these are only examples, and not an exhaustive enumeration of prohibited activities). However, the following methods of distribution involving payment shall not in and of themselves be a violation of this restriction:

           A. Posting the Program on a public access information storage and retrieval service for which a fee is received for retrieving information (such as an on-line service), provided that the fee is not content-dependent (i.e., the fee would be the same for retrieving the same volume of information consisting of random data).

           B. Distributing the Program on a CD-ROM, provided that the files containing the Program are reproduced entirely and verbatim on such CD-ROM, and provided further that all information on such CD-ROM be redistributable for non-commercial purposes without charge.

      b. Activities other than copying, distribution and modification of the Program are not subject to this License and they are outside its scope. Functional use (running) of the Program is not restricted, and any output produced through the use of the Program is subject to this license only if its contents constitute a work based on the Program (independent of having been made by running the Program).

      c. You must meet all of the following conditions with respect to the distribution of any work based on the Program:

           A. If you have modified the Program, you must cause your work to carry prominent notices stating that you have modified the Program's files and the date of any change;

           B. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole and at no charge to all third parties under the terms of this License;

           C. If the modified program normally reads commands interactively when run, you must cause it, at each time the modified program commences operation, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty). Such notice must also state that users may redistribute the Program only under the conditions of this License and tell the user how to view the copy of this License included with the Program. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.);

           D. You must accompany any such work based on the Program with the complete corresponding machine-readable source code, delivered on a medium customarily used for software interchange. The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable code. However, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable code;

           E. If you distribute any written or printed material at all with the Program or any work based on the Program, such material must include either a written copy of this License, or a prominent written indication that the Program or the work based on the Program is covered by this License and written instructions for printing and/or displaying the copy of the License on the distribution medium;

           F. You may not impose any further restrictions on the recipient's exercise of the rights granted herein.

               If distribution of executable or object code is made by offering the equivalent ability to copy from a designated place, then offering equivalent ability to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source code along with the object code.

 3. Reservation of Rights.

     No rights are granted to the Program except as expressly set forth herein. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

 4. Other Restrictions.

     If the distribution and/or use of the Program is restricted in certain countries for any reason, Licensor may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

 5. Limitations.

     THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS NO WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

The MySQL license for Microsoft operating systems
*************************************************

MySQL shareware license for Microsoft operating systems
(Version 1, September 4, 1998)

Copyright (C) 1998 TcX AB & MySQL Finland AB & Detron HB
Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN
All rights reserved.

This License applies to the computer program known as "MySQL".

This License applies when running MySQL on any Microsoft operating system. Microsoft operating systems include all versions of Microsoft Windows NT and Microsoft Windows.

YOU SHOULD CAREFULLY READ THE FOLLOWING TERMS AND CONDITIONS BEFORE USING, COPYING OR DISTRIBUTING MySQL. BY USING, COPYING AND DISTRIBUTING MySQL, YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR USING, COPYING AND DISTRIBUTING MySQL OR WORKS BASED ON IT.  NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO USE, COPY OR DISTRIBUTE MySQL OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT USE, COPY OR DISTRIBUTE MySQL.

 1. Evaluation and License Registration.

     This is an evaluation version of MySQL for Win32. Subject to the terms below, you are hereby licensed to use MySQL for evaluation purposes without charge for a period of 30 days. If you use MySQL after the 30 day evaluation period the registration and purchase of a MySQL license is required.

     The price for a MySQL license is currently 200 US dollars and email support starts from 200 US dollars/year. Quantity discounts are available. If you pay by credit card, the currency is EURO (The European Unions common currency) so the prices will differ slightly.

     The easiest way to register or find options about how to pay for MySQL is to use the license form at TcX's secure server at https://www.mysql.com/license.htmy. This can be used also when paying with credit card over the Internet.

     Other applicable methods for paying are SWIFT payments, cheques and credit cards.

     Payment should be made to:

          Postgirot Bank AB
          105 06 STOCKHOLM, SWEDEN

          TCX DataKonsult AB
          BOX 6434
          11382 STOCKHOLM, SWEDEN

          SWIFT address: PGSI SESS
          Account number: 96 77 06 - 3

     Specify: license and/or support and your name and email address.

     In Europe and Japan, EuroGiro (that should be cheaper) can be used to the same account.

     If you want to pay by cheque make it payable to "MySQL Finland AB" and mail it to the address below.

          TCX DataKonsult AB
          BOX 6434
          11382 STOCKHOLM, SWEDEN

     For more information about commercial licensing, please contact:

          David Axmark
          Kungsgatan 65 B
          753 21 UPPSALA
          SWEDEN
          Voice Phone +46-18-10 22 80     GMT 9-21. Swedish and English spoken
          Fax +46-8-729 69 05             Email *much* preferred.
          E-Mail: mysql-licensing@mysql.com

     For more about the license prices and commercial support, like email support, please refer to the MySQL manual. See Cost. See Support.

     The use of MySQL or any work based on MySQL after the 30-day evaluation period is in violation of international copyright laws.

 2. Registered version of MySQL.

     After you have purchased a MySQL license we will send you a receipt by paper mail. You are allowed to use MySQL or any work based on MySQL after the 30-days evaluation period. The use of MySQL is, however, restricted to one physical computer, but there are no restrictions on concurrent uses of MySQL or the number of MySQL servers run on the computer.

     We will also email you an address and password for a password-protected WWW page that always has the newest MySQL-Win32 version. Our current policy is that a user with the MySQL license can get free upgrades. The best way to ensure that you get the best possible support is to purchase commercial support!

 3. Registration for use in education and university or government-sponsored research.

     You may obtain a MySQL license for the use in education and university or government-sponsored research for free. In that case, send a detailed application for licensing MySQL for such use to the email address mysql-licensing@mysql.com.

     The following information is required in the application:

       * The name of the school or institute.

       * A short description of the school or institute and of the type of education, resarch or other functions it provides.

       * A detailed report of the use of MySQL in the institution.

     In this case you will be provided with a license that entitles you to use MySQL in a specified manner.

 4. Distribution.

     Provided that you verify that you are distributing an evaluation or educational/research version of MySQL you are hereby licensed to make as many literal (i.e., verbatim) copies of the evaluation version of MySQL and documentation as you wish.

 5. Restrictions.

     The client code of MySQL is in the Public Domain or under the GPL (for example the code for readline) license.  You are not allowed to modify, recompile, translate or create derivative works based upon any part of the server code of MySQL.

 6. Reservation of Rights.

     No rights are granted to MySQL except as expressly set forth herein. You may not copy or distribute MySQL except as expressly provided under this License. Any attempt otherwise to copy or distribute MySQL is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

 7. Other Restrictions.

     If the distribution and/or use of MySQL is restricted in certain countries for any reason, the Licensor may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

 8. Limitations.

     MySQL IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS NO WARRANTY FOR MySQL, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF MySQL IS WITH YOU.  SHOULD MySQL PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL THE LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE MySQL AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE MySQL (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF MySQL TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.