Go to the first, previous, next, last section, table of contents.


MySQL はどのように標準互換か?

MySQL の ANSI SQL92 に対する拡張

次は便利な MySQL の拡張です。他の SQL データベースにはおそらく 見られません。これを使用した場合、そのコードは他の SQL サーバに移行でき なくなるので注意してください。

MySQL に無い機能

次の機能が MySQL の現在のバージョンにはありません。新しい拡張の 優先度については、次を参考にしてください: The MySQL Todo list. これはこのマニュアル中の Todo リストの最新バー ジョンです。 「List of things we want to add to MySQL in the future (The TODO).」節参照 。

Sub-selects

次は MySQL では働きません:

SELECT * from table WHERE id IN (SELECT id from table2)

MySQL は INSERT ... SELECT...REPLACE ... SELECT... だ けをサポートします。独立した sub-selects はおそらく 3.22.0 で有効になり ます。しかし今は他の文脈内で関数 IN() を使用できます。

SELECT INTO TABLE

MySQL はまだ SELECT ... INTO TABLE.... をサポートしません。現 在の MySQL は SELECT ... INTO OUTFILE... だけをサポートします。 これは基本的に同じことです。

トランザクション

トランザクションはサポートされません。MySQL は間もなく、アトミッ クオペレーション(atomic operations)をサポートします。これはトランザクショ ンに似ていますが、ロールバックはありません。アトミックオペレーションでは、 insert/select/whatever コマンドの束を作成できます。そして、他のスレッド が邪魔しないことが保証されます。この文脈では、通常ロールバックは必要では ありません。現在、LOCK TABLES/UNLOCK TABLES コマンドの助けでこれ を行なうことができます。 「LOCK TABLES 構文」節参照

トリガ

トリガはサポートされません。計画されている更新言語はストアドプロシジャを 操作できますが、トリガは除きます。トリガは通常、それが必要とされない時の 全てのクエリについても、全てをあまりにも遅くします。

Foreign Keys

MySQL 内での FOREIGN KEY 構文は、他の SQL ベンダの CREATE TABLE コマンドとの互換のためだけに存在します: これは何も行 ないません。ON DELETE .. がない FOREIGN KEY 構文は、目的の 作成のために主に使われます。いくつかの ODBC アプリケーションは、自動的に WHERE 節を提供するために、これを使用しますが、しかしこれは通常簡 単に無効にできます。FOREIGN KEY は時々強制チェックとして使用され ます。しかし、テーブルに正しい順で行が挿入される場合、このチェックは実際 には不要です。いくつかのアプリケーションがそれが存在することを要求するた め MySQL はこれらのコマンドだけをサポートします(しかし働きませ ん!)。

MySQL では、FOREIGN KEY を持つテーブルからレコードを削除する時 に approative DELETE ステートメントをアプリケーションに追加するこ とで、ON DELETE ... が実装されていないという問題を回避できます。 実際には、これは速く(いくつかの場合はより速く)そして FOREIGN KEY の使用よりもさらに可搬性があります。

Foreign key は人生をとても困難にするものです。なぜなら、foreign key 定義 はデータベースに置く必要があり、それの実装は、移動,コピーそして削除され 得るファイルの使用の全ての '良いアプローチ' は破棄されることを意味します。

近い将来、少なくとも情報が救われ、そして mysqldump と ODBC によって取り 出されるように、我々は FOREIGN KEY を拡張します。

Some reasons NOT to use FOREIGN KEYS

There are so many problems with the FOREIGN KEYs that we don't know where to start.

The only nice aspect of foreign key is that it gives ODBC and some other client programs the ability to see how a table is connected and use this to show connection diagrams and to help building applicatons.

MySQL will soon store the FOREIGN KEY definitions so that a client can ask and receive an answer how the original connection was made. The current .frm file format does not have any place for it.

ビュー

MySQL はビューをサポートしません。しかしこれは TODO にあります。

コメント開始としての --

他のいくつかの SQL データベースは、-- をコメントの開始とします。 MySQL# をコメント開始文字とします。mysql コマ ンドラインツールが -- で始まる全ての行を削除したとしてもです。 MySQL では C コメントスタイル /* これはコメント */ も使 用できます。 「Comment 構文」節参照

MySQL はこの退化したコメントスタイルをサポートしません。なぜな ら、次のコードのようなものを使って自動的に生成される SQL クエリで、多く の問題を持つためです:

UPDATE table_name SET credit=credit-!payment!

これは !payment! の代わりに、自動的に支払の値を挿入します。

'payment' が負の場合に何が起きると思いますか?

1--1 は正しい SQL なので、我々は '--' をコメント開始と見なすことはひどい ことだと思います。

SQL プログラムのテキストファイルが -- コメントを含んでいる場合、 次を使用すべきです:

replace " --" " #" < text-file-with-funny-comments.sql | mysql database.

instead of the normal

mysql database < text-file-with-funny-comments.sql

次の方法でも、コマンドファイル中の --# コメントに変更 できます:

replace " --" " #" -- text-file-with-funny-comments.sql

それらを戻すには:

replace " #" " --" -- text-file-with-funny-comments.sql

MySQL が準拠している標準

Entry level SQL92. ODBC level 0-2.

互換のためだけに存在している機能

BLOBTEXT 型の制限

BLOB または TEXT 上で GROUP BY または ORDER BY したい場合は、項目を固定長オブジェクトにする必要があります。これを行 なう標準的な方法は、SUBSTRING 関数です。これをしない場合、ソート 時には最初の max_sort_length (default=1024) だけが対象です。

SELECT comment from table order by substring(comment,20);

COMMIT-ROLLBACK なしでうまくやる方法

MySQL は COMMIT-ROLLBACK をサポートしません。COMMIT-ROLLBACK で の問題は、それを効率的に操作するために、MySQL が現在使用してい るものとは完全に異なったテーブルの形式が要求されることです。 MySQL は、自動的にテーブルをクリーンアップする拡張スレッドも必 要とし、ディスク使用量はさらに大きくなります。これは MySQL を現 在の 2〜4 倍遅くしてしまいます。MySQL が既存の他の全ての SQL デー タベースよりもこんなに速い(概して少なくとも 2〜3 倍速い)理由の一つは、 COMMIT-ROLLBACK が欠けていることです。

今、我々は SQL サーバ言語(ストアドプロシジャのようなもの)の実装にさらに 賛成です。これで、本当に COMMIT-ROLLBACK を必要とするのはめったにありま せん。これはさらに良い性能も与えるでしょう。

トランザクションを必要とするループは、通常は LOCK TABLES の助けで コード化でき、そして fly 上でレコードの更新時にはカーソルは必要としませ ん。

TODO 上にトランザクションとカーソルがありますが、全く優先されていません。 それが実装される場合は、CREATE TABLE のオプションとしてです。これ は COMMIT-ROLLBACK はそのテーブルだけで働き、そのテーブルだけが遅くなるということを 意味します。

我々 TcX で本当に必要としているのは、100% 標準のデータベースではなくて、 本当に速いデータベースです。速度低下なしでそれらを実装する方法を見つけた ときには、我々はそれを行なうでしょう。今は行なうべきさらに重要なことが多 くあります。今の我々の優先度については TODO をチェックしてください。高レ ベルのサポートを持つ顧客はこれを変えることができ、再び優先順位づけが行な われます。

現在の問題は実際には ROLLBACK です。ROLLBACK なしでも LOCK TABLES で行なうことができます。ROLLBACK をサポートす るためには、更新される全ての古いレコードを格納し、ROLLBACK が発行 された場合に開始位置に全てを戻すように、MySQL を変更しなければ なりません。単純な場合には、これを行なうには難しくありません(現在の isamlog をこれに使用します)。しかし、ALTER/DROP/CREATE TABLEROLLBACK をしたい場合、すべてを実装するのは困難です。

ROLLBACK の使用の回避のために、次を行なうことができます:

  1. LOCK TABLES ...
  2. 条件のテスト。
  3. 全て OK なら更新。
  4. UNLOCK TABLES

これは普通は速いですが、常にではありません。これが処理できないのは、誰か がプロセスを kill する場合だけです。

1回のオペレーション中で何かを更新する関数も使用できます。全ての関連した 更新、そして/または、実際に変更された項目だけの更新により、とても能率的 なアプリケーションを得られます。

例えば、いくつかの顧客情報で更新を行なっている時、我々は変更された顧客デー タだけを更新し、変更されていないデータだけをテストします。また、変更され たデータに依存するデータがオリジナルの行内で変更されます。変更のテストは UPDATE ステートメント内の WHERE 節で行われます。レコードが 更新されなかった時は、我々はクライアントにメッセージ: "Some of the data you have changed has been changed by another user" を与え、そしてそれか ら古い行と新しい行をウィンドウ内で表示します。ユーザは顧客レコードのどち らのバージョンを使用すべきかを決定できます。

これは 'column locking' に似たものを我々に与えますが、実際には十分です。 なぜなら、我々は関連情報を持つ項目だけを更新するからです。これは、典型的な 更新ステートメントが次のように見えるということを意味します:

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+'new_money' where
customer_id=id and address='old address' and phone='old phone';

見ての通り、これはとても能率的で、他のクライアントが 'money_he_owes_us' または 'pay_back' の量を変更したとしても、これは働きます。

多くの場合、ユーザは ROLLBACK そして/または LOCK TABLES が いくつかのテーブルでユニークな識別子を管理することを望みます。 AUTO_INCREMENT 項目と MySQL API 関数 mysql_insert_id の使用によって、これはさらに能率的に処理できます。 「最後に挿入された行のユニーク ID をどのように得られるか?」節参照

TcX では、我々はいつでもその回りでコード可能なので、我々は行レベルロック を必要としていません。本当に行ロックを必要とする場合があることは知ってい ます。しかしこれは非常に少ないです。行レベルロックを望むのなら、次のよう にして行なえます:

UPDATE table_name SET row_flag=1 WHERE id=ID;

行が見つかり、オリジナルドキュメント内で row_flag が 1 でない場合、MySQL は affected rows = 1 を返します。TODO 上に、アプリケーションレベ ルロックを実装したい人のための GET_LOCKRELEASE_LOCK が あります。


Go to the first, previous, next, last section, table of contents.