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
。
BINARY
属性であなたのフィールドを宣言すべきです。これは、MySQL
サーバホストの上で使用される ASCII 順に従って比較が実行されるようになり
ます。
db_name.tbl_name
構文を使用して違うデータベースのテーブルにアクセスできます。
いくつかのSQLサーバーは同様の機能を提供しますが、これを User space
でコールします。
MySQL は以下のようなテーブルスペースをサポートしません:
create table ralph.my_table...IN my_tablespace
.
LIKE
が許されます。
SELECT
ステートメント内の INTO OUTFILE
と
STRAIGHT_JOIN
の使用。 「7.14 SELECT
構文」節参照.
EXPLAIN SELECT
。
CREATE TABLE
ス
テートメント内の INDEX
または KEY
の使用。
「7.7 CREATE TABLE
構文」節参照.
CREATE TABLE
での TEMPORARY
か IF NOT EXISTS
の使用。
COUNT(DISTINCT list)
の使用。
ALTER TABLE
ステートメント内の CHANGE col_name
, DROP col_name
,
DROP INDEX
の使用。
「7.8 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
と互換があります。 「7.18 LOAD DATA INFILE
構文」節参照.
OPTIMIZE TABLE
ステートメント。
「7.10 OPTIMIZE TABLE
構文」節参照.
SHOW
ステートメント。
「7.23 SHOW
構文 (テーブルやフィールドなどについての情報を得る)」節参照.
SET OPTION
ステートメント。 「7.28 SET OPTION
構文」節参照.
GROUP BY
部に全てのフィールドを持つ必要はありません。
This gives better performance for some very specific, but quite normal
queries.
「7.4.13 GROUP BY
節の関数」節参照.
||
と &&
演算子を、C プログラミング言語
のように、論理和と論理積を意味すると理解します。MySQL では
||
と OR
、&&
と AND
は同義語です。この良い構
文のため、MySQL は ANSI SQL の文字列結合演算子 ||
をサポー
トしません。CONCAT()
を代わりに使用してください。CONCAT()
は任意の数の引数を使用できるので、||
演算子の使用を
MySQL に変換するのは簡単です。
CREATE DATABASE
または DROP DATABASE
.
「7.5 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()
関数。
「22.4.29 mysql_insert_id()
」節参照.
REGEXP
または NOT REGEXP
。
CONCAT()
または CHAR()
。
MySQL では、これらの関数は任意の数の引数を取ることができます。
BIT_COUNT()
, CASE
, ELT()
,
FROM_DAYS()
, FORMAT()
, IF()
, PASSWORD()
,
ENCRYPT()
, md5()
, ENCODE()
, DECODE()
,
PERIOD_ADD()
, PERIOD_DIFF()
, TO_DAYS()
, or
WEEKDAY()
functions.
TRIM()
を使用できます。ANSI SQL は一文字
の削除だけをサポートします。
GROUP BY
関数 STD()
, BIT_OR()
そして BIT_AND()
。
DELETE
+ INSERT
の代わりの REPLACE
の使用。
「7.17 REPLACE
構文」節参照.
FLUSH flush_option
構文。
:=
でステートメント内での変数の設定が可能:
The possiblity to set variables in a statement with :=
:
SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg FROM test_table; SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
--ansi
オプションつきで mysqld を開始すると、その MySQL の
振舞いが変わります。
||
は OR
ではなく文字列結合です。
"
は(MySQL `
引用文字に似た)識別子引用文字になり、
文字列引用文字ではありません。
REAL
は DOUBLE
の同義語ではなく FLOAT
の同義語になり
ます。
我々は MySQL を ANSI SQL 標準と ODBC SQL 標準に従うように試みてい ますが、いくつかのケースで MySQL は何か違いがあります:
--
は空白が続く場合だけコメントになります。 「5.4.7 コメント開始としての `--'」節参照。
VARCHAR
フィールドでは、値が格納される時に末尾の空白が削除されます。
「F MySQL での既知のエラーと欠けているデザイン」節参照。
CHAR
フィールドは黙って VARCHAR
フィール
ドに変更されます。 「7.7.1 暗黙のフィールド定義変更」節参照。
REVOKE
を発行する必
要があります。 「7.29 GRANT
と REVOKE
構文」節参照.
NULL AND FALSE
will evaluate to NULL
and not to FALSE
.
This is because we don't think it's good to have to evaluate a lot of
extra conditions in this case.
次の機能が MySQL の現在のバージョンにはありません。新しい拡張の 優先度については、次を参考にしてください the MySQL TODO list。これはこのマニュアル中の TODO リストの最新バー ジョンです。 「G MySQL に将来加えたいもの (The TODO)」節参照。
次は 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 にサポートされるまで、この状況には2
つの選択肢があります。
最初の選択肢は、手続きプログラミング言語(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
が使用できます。
「7.16 INSERT
構文」節参照.
MySQL は現在トランザクションをサポートするため、次の議論は非トラ
ンザクション安全テーブル型を使用する場合にだけ有効です。 「7.26 COMMIT/ROLLBACK
構文」節参照。
``なぜ 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. 「8.4 BDB or Berkeley_db tables」節参照.
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 がストアドプロシジャを得る時を知るには、 「G MySQL に将来加えたいもの (The TODO)」節 を参照 してください。
注意: SQL の外部キーはテーブルを結合するためには使用できませんが、指示の
完全性の検査のために良く使用されます。SELECT
ステートメントで複数
テーブルから結果を得たい場合、テーブルの結合によってこれを行ないます!
SELECT * from table1,table2 where table1.id = table2.id;
「7.15 JOIN
構文」節参照. 「9.3.5 Using 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
チェックは役に立ちませ
ん。通常は、正しいテーブルに正しい順でレコードを挿入するためです。
外部キーの良い面は、ODBC と他のいくつかのクライアントプログラムに、どの ようにテーブルが接続されるかを見る機能を与え、これを使用して接続図を示し、 生成アプリケーションの手助けをすることだけです。
MySQL は間もなく、クライアントがどのようにオリジナル接続が作成
されたかを問い合わせ、回答を受けられるように FOREIGN KEY
定義を格
納します。現在の `.frm' ファイル形式にはそれを置く場所はありません。
MySQL はビューをサポートしません。しかしこれは TODO にあります。
他のいくつかの SQL データベースは、`--' をコメントの開始のために使
用します。MySQL は `#' をコメント開始文字とします。
mysql
コマンドラインツールが `--' で始まる全ての行を削除した
としてもです。MySQL では C コメントスタイル /* これはコメ
ント */
も使用できます。 「7.32 コメント 構文」節参照。
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
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
. 「7.26 COMMIT/ROLLBACK
構文」節参照.
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
の使用の回避のために、次の方法を使用することができます:
LOCK TABLES ...
をアクセスしたいテーブルの全てをロックするために
使用します
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
の使用によって、さらに効率的に処理できます。
「22.4.29 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;
Go to the first, previous, next, last section, table of contents.