# 日報(2024-01-13) mariadb で table の collation を create table のタイミングで指定する

# 背景

ORM が嫌いで、何かあった時を思うといまいち怖くてどうしても信用できないので、JSON 型を好んで使ってます

こんな感じで

CREATE TABLE IF NOT EXISTS tablename (
	ID       VARCHAR(16) PRIMARY KEY, 
	Attr     JSON,
	Sys      JSON,
	CHECK (JSON_VALID(Attr) and JSON_VALID(Sys))
)

アプリで使うデータ一切を Attr にまとめて、生成や更新の日時とかを Sys にまとめて使ってます

ある時、LeR という ID で登録しようとしたら

id already exist

あれれと思って検索しても LeR はないのですが LER という ID はありました、というかなんで LeR で検索してるのに LER が表示されての?あ、case insensitive か!

とりあえず database のデフォルトを見てみると

show create database tablename
    -> ;
+--------------+-----------------------------------------------------------------------------------------------------+
| Database  | Create Database                                                                                     |
+--------------+-----------------------------------------------------------------------------------------------------+
| tablename | CREATE DATABASE `tablename` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ |
+--------------+-----------------------------------------------------------------------------------------------------+

utf8mb4 はググると詳しく説明してくれているサイトがたくさんでてくるのですが、歴史的な経緯があってややこしい名前をしているようですがようするに utf8ですよね で、utf8mb4_general_ci が COLLATE で、語尾の _ci が case insensitive を示してます。正解ですね

ちなみに table の collation を確認すると

SHOW FULL COLUMNS FROM tablename;
+-------+-------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation          | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| ID    | varchar(16) | utf8mb4_general_ci | NO   | PRI | NULL    |       | select,insert,update,references |         |
| Attr  | longtext    | utf8mb4_bin        | YES  |     | NULL    |       | select,insert,update,references |         |
| Sys   | longtext    | utf8mb4_bin        | YES  |     | NULL    |       | select,insert,update,references |         |
+-------+-------------+--------------------+------+-----+---------+-------+---------------------------------+---------+

ID が case insensitiveutf8mb4_general_ci なのですが JSON の Attr と Sys は case sensitiveutf8mb4_bin なんですね

# create table で collation を変える

collation を指定して database を作り直すのは巻き添えが多すぎてちょっと大事なのですが、alter table で変更しなきゃいけない程でもない開発中なので、collation に utf8mb4_bin を指定して table を作り直します

CREATE TABLE IF NOT EXISTS tablename (
	ID       VARCHAR(16) PRIMARY KEY, 
	Attr     JSON,
	Sys      JSON,
	CHECK (JSON_VALID(Attr) and JSON_VALID(Sys))
)  COLLATE utf8mb4_bin

で、collation を確認すると

+-------+-------------+-------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation   | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+-------------+------+-----+---------+-------+---------------------------------+---------+
| ID    | varchar(16) | utf8mb4_bin | NO   | PRI | NULL    |       | select,insert,update,references |         |
| Attr  | longtext    | utf8mb4_bin | YES  |     | NULL    |       | select,insert,update,references |         |
| Sys   | longtext    | utf8mb4_bin | YES  |     | NULL    |       | select,insert,update,references |         |
+-------+-------------+-------------+------+-----+---------+-------+---------------------------------+---------+

case sensitive になりました

# collation

さて、collation ですが英語苦手な私は DB の文脈以外では見たことがない言葉なのですが、DB の文脈だとよく照合順序 みたいな訳語を見るのですが元々どういうニュアンスでどういう所で使ってた言葉なんだろと好奇心をもったのですが、辞書を引くと「照合、校合」とかっこいいんだけど意味のわからない言葉でよくわかりません

こういう時に英英辞典はわかりやすい言葉で説明してくれていることが多く ケンブリッジ (opens new window) の米語辞典だと

to collect and arrange in correct order the sheets of a document

つまり正しい順序で並べるって意味なんですね

# 参考文献


Last Updated: 2024/4/11 0:47:12