この記事の内容
PostgreSQL から RDBMS を使い始めた私が、MySQL を使うようになって「なんだこれ」とハマってしまった仕様について紹介します。
第3位: エンコーディングに utf8 と utf8mb4 がある
カラム(テーブル・データベース)のエンコーディングには、3バイトまでしか格納できない "utf8" と、4バイトを格納できる "utf8mb4" があります。"utf8" では「𠮷」や絵文字などの4バイト文字を扱うことができません。
このように別のエンコーディングになっているのには歴史的経緯があるものと推測しますが、"utf8mb4" というエンコーディングの存在を知らないと「utf8 なのにいったいどういうことなんだ」と戸惑うことになります。
※MySQL 8.0.1 からは "utf8mb4" がデフォルトのエンコーディングになりました。
第2位: 大文字と小文字を区別しない
MySQL のデフォルトの照合順序は utf8_general_ci であり、"ci" つまり case-insensitive(大文字と小文字を区別しない)ということになります。
> SELECT foo FROM bar WHERE foo='A';
+-----+
| foo |
+-----+
| a |
| A |
+-----+
カラムの照合順序を utf8_bin に変更したり、カラムに BINARY 属性を付けたり、SQL に BINARY 演算子を付けてキャストしたりすると区別されるようになります。
※ちなみに、SQLServer もデフォルトが Japanese_CI_AS になっているようです。
第1位: VARCHAR(n) の列に n 文字を超える文字列を入れてもエラーにならない
VARCHAR(1) の列に "ZA" を入れようとするとエラーにならず、切り詰められて "Z" が格納されます。
これでは「"ZA" が格納されなかった」ことに気づかないため、「エラーにしてくれれば、意図した文字列が格納されていないことに気づくのに……」となります。
sql_mode で STRICT_TRANS_TABLES または STRICT_ALL_TABLES を有効にすることで、これをエラーになるようにすることができます。
まとめ
MySQL を使いだして十数年ですが、いまだにうっかり忘れて「おや?」となることがあります。
いろいろな RDBMS を使い分けるのであれば、それぞれの特徴を把握して対応できる脳になるしかないですね。