utf8とutf8mb4の違いMariaDB(MySQL)以外のデータベースではutf8をutf8とutf8mb4に区別しているのは聞いたことがないので調べてみたのですが、どうもMySQLは歴史的な事情で1文字3バイトまでしか格納できないutf8と4バイトまで格納できるutf8mb4に分かれているとのこと。0213の第3~4水準文字の極一部※1と絵文字(😊とか)は1文字4バイト使うのでutf8mb4が必須です。レガシーなシステムは別として今後作るシステムでは文字セットはutf8mb4で良いでしょう。Server/Oracle/PostgreSQLはそこそこ使っていたものの、MySQLはあまり触ったことがなかったため、趣味で掲示板システムを開発した際、MySQLを使ったことがあります。DBを構築して運営開始してしまったのですが、ログを見るとなぜか定期的に文字コードエラーが発生している......。掲示板で書き込まれる文字をDBに格納するときにエラーが発生しているため、それを別のテキストファイルにログとして記録することで調査したところ、ようやく絵文字でエラーが発生しているのだとわかりました。昔は機種依存文字を使うべきではないだのなんだのとユーザー側が気を使うのが当たり前の時代もありましたが、今は2018年です。そりゃ絵文字くらい掲示板に書き込む人がいても不思議じゃないですよね。変更するだけで対応できました。照合順序が適用される順序MariaDB(MySQL)にはサーバーの照合順序、データベースの照合順序、テーブルの照合順序、カラムの照合順序と、それぞれに照合順序が指定できるので頭の中がこんがらがりそうですが、別に難しいことはありません。testdb;とだけ入力して実行した場合はサーバーの照合順序がデータベースに設定される、というだけの話しなのです。無理にサーバーとデータベースの照合順序を合わせなければ!とか考えなくて良いんですね。レンタルサーバーとかの場合、サーバー側の照合順序はutf8_general_ciに設定されていて、ユーザー側では触れない、とか普通にあるじゃないですか。utf8mb4_general_ci;とか明示的に指定してあげれば良いのです。場合によってはデータベースが1つしか使えない、その照合順序もレンタルサーバー側で決められている、というケースもあります。テーブルを作る際に照合順序を指定してあげれば良いのです。utf8mb4_general_ciとunicode_ciとbinの違いcollate句を使えばデータベース、テーブル、カラムそれぞれに照合順序を指定することができますし、select文にすらcollate句は使えます。実際にそれぞれの照合順序がどんな動きになるのか試すのも簡単。utf8mb4_bin;こんなselect文を実行して、1が表示されれば一致、0が表示されれば不一致ということです。上記の例ではutf8mb4_general_ciとutf8mb4_unicode_ciでは1、utf8mb4_binでは0が返ってきますので、前の2つは大文字小文字を区別しない、最後のbinは大文字小文字を区別する、とわかるわけです。×=不一致フォントによってはちょっとわかりづらいでしょうか。5行目の「a」と「A」は半角小文字のaと全角大文字のAを比較しています。general_ciでは不一致ですが、unicode_ciでは一致していますね。6行目の「+」と「+」はプラス記号の半角と全角で、こちらも同様です。最後の2行は漢数字の「一(いち)」と長音記号「ー」ですが、これはさすがにunicode_ciでも不一致でした。以外なのは「1」と「1」がunicode_ciでは一致するあたりでしょうか。このようにunicode_ciでは半角・全角を問わず、それどころか「ハ」「バ」も一致するため、「ハハ」と「ババ」と「パパ」が一致するなんて不具合だ!などと叫ぶ人もいるくらいです。ビックカメラとビッグカメラが一致するのは便利、と考えるケースもあると思うので、用途次第で使い分ければ良いんじゃないですかね。utf8mb4_general_ciがデフォルトなんだからそれでも構わないと思いますし、例えばユーザーIDを登録するようなテーブルでは大文字小文字を区別しないutf8mb4_general_ciのほうが重複チェックが楽なのかも知れません。掲示板やメールのようなシステムで本文の部分は出来るだけあいまいな検索をしたい、という要件がある場合はそこだけutf8mb4_unicode_ciを使うのも良いでしょうね。ぼくがutf8mb4_binを使いたがる理由は寿司ビール問題という冗談のような問題のためです。寿司ビール問題とは寿司ビール問題とか呼ばれはじめたのはTwitterでつぶやかれたのがきっかけだったと思いますが、絵文字の寿司(🍣)とビール(🍺)がMySQLだと同一とみなされる、という話しです。utf8mb4_bin;実際、こんなSQL文を流してみれば一目瞭然なのですが、utf8mb4_general_ciやunicode_ciだと🍣と🍺が一致しちゃいます。これ、バグじゃなくて正式な仕様らしいんですよね。4.0.0という仕様に準拠していて、絵文字は同じ重みが設定されているとか。メインにして、大文字小文字の処理は自前で書くかなぁと思い始めたり。漢数字の並び順について厳密には照合順序とはあまり関係ない話ですが、ソートに関することなので一応触れておきます。これもバグではなく、Unicodeだと文字コードがそういう順序で登録されているからどうしようもないんですね。部首の画数順に登録されたとかなんとか。このへんはMySQLに限らず、PHPだろうと他の言語だろうとUnicodeを使っている以上、配列に入れてソートしてみると同じ順になります。使ったとしてもダメです。順に登録されているので、数字順にならないことに変わりはありません。結局のところ、漢数字は漢字であって、漢字を文字コードでソートするというのがよくないってことなのでしょう。漢字をソートしたいならよみがな付けようよ、と。いうのは住所のよみがな項目を作ってそちらに「1ちょうめ」「2ちょうめ」「3ちょうめ」と入れ、ソートする際はよみがな項目を使うのがスマートだと思います。ユーザーに入力させるのではなく、登録実行時に自動的に漢数字を数値に変換して保存してあげると素敵ですね。そんな感じでしょうか。arrayを使うとスマートに書けそうですが、本題から外れるので別の機会に。データが出来上がってしまっていてどうしても、ど~~~してもSQL文だけでやりたい、という場合はストアドファンクションとか使った実装ですかねー。実際そういった要件があがってきて、スマートじゃないなーと思いつつも対応した記憶があります。このへんはさすがに照合順序の話しから脱線しすぎますので、機会があればストアドファンクションの書き方と合わせて別の記事にするかもしないかも。文字コードについては1記事ではとても書ききれないくらい複雑なので、興味のある方、特に職業としてデータベースに携わっている方はきちんとした日本語処理に関する本を一冊は読んで頂きたい。ぼくがデータベースエンジンの開発に携わっていた頃にぼろぼろになるまで読み込んだ本があるのですが、20年近く前に出版された本なのでさすがに今となっては技術書というよりは歴史書に近いかも知れません。良い本なので機会があれば読んでほしい。よると5万文字以上の漢字をもつ日本語をどのように扱うのか試行錯誤してきた歴史があります。Unicodeが登場したとき、1文字をすべて16ビットにすれば65535文字も使えるから世界中の文字コードを扱える!という謳い文句だったのですが、正直日本の技術者は失笑していたと思います。全部入れろとは言わないけれど、ちょっと珍しい漢字を登録すると日本語だけでも12000文字くらいになります。いって、全部の文字を32ビットにするとデータ量が爆発的に増えます。いくらコンピューターの進化が早いとは言っても、節約できるところは節約していかないとどれだけディスク容量や通信回線が太くなっても賄いきれません。して1~4バイトの可変長であるUTF8が普及したわけですが、これにも問題点がないわけじゃありません。英数字については従来どおり1文字1バイトで済むから良いものの、それ以外に至っては本来2バイトで済むところが3~4バイトになっているわけですし、可変長ということは頭から順番に読み込んでいかないと文字の切り取り操作もできません。UTF8が主流だとは思いますが、いつかUTF32の固定長が当たり前の時代がくるのかも知れませんね。..................をしようと思ったのですが、前提となる02021-02-16SQLiteでNULLと空文字が入った列のソート順を思い通りに操る方法データベースのソート順においてNULLや空文字でハマるケースってけっこう多いですよね。Serverはセットアップ済みですが、趣味でもPHPをいじりたくなり、どうせならApacheではなくnginxを使ってみようかと思い立ちました。コメント投稿直後ならコメントの編集/削除が可能です。※24時間経過するか、新しく投稿した場合は古い投稿の編集や削除は出来ません。※ブラウザでCookieが受け入れられない場合はこの機能は使えません。非公開にチェックを入れたコメントは管理人のみ閲覧できます。コメント投稿のガイドライン誰もが閲覧できるコメント欄ですので個人が特定できる情報等は書き込まないようにしましょう。他人のHPやブログの文章を掲載する場合は著作権法第32条「引用」の条件を満たすかご確認ください。誹謗中傷にあたる表現などは場合によっては法的な責任を問われる可能性があるためご注意ください。とっちらか~るTOP。