がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

(VARBINARYの代わりとしての)COLLATE utf8mb4_bin

いやまぁそのまんまなのですが。

ちょいと故ありましてLaravel触ってるんですが、あの子、デフォでVARBINARY扱う手段ないんですよねぇ……。

DB::statement('ALTER TABLE (以下略

とかで「可能」なのは理解しているんですが、それも「ど~なのよ?」的な。

で。
おいちゃんがVARBINARYを使いたい、一つは「utf8mb4で文字列の長さがINDEXとかPKとか*1」なんですが。
もう一つが「大文字と小文字を等しいとかマジですか? 馬鹿なの? ○○の?」ってあたり。
gallu.hatenadiary.jp
gallu.hatenadiary.jp
gallu.hatenadiary.jp
辺りをご参照の事。

で、「大文字小文字は違うもの」だけなら「COLLATE utf8mb4_bin」でいける、のと、これだとLaravelでも一応取り扱える、ので、軽く実験君。

用意その1。

CREATE TABLE `t1` (
  `id` SERIAL,
  `email` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'email',
  UNIQUE KEY `unique_t1_email` (`email`),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='ユーザテーブル';

CREATE TABLE `t2` (
  `id` SERIAL,
  `email` varchar(255) NOT NULL COMMENT 'email',
  UNIQUE KEY `unique_t2_email` (`email`),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ユーザテーブル';

実験。

INSERT INTO t1(email) VALUES('gallu@example.com');
INSERT INTO t1(email) VALUES('Gallu@example.com');

INSERT INTO t2(email) VALUES('gallu@example.com');
INSERT INTO t2(email) VALUES('Gallu@example.com');

mysql> INSERT INTO t1(email) VALUES('gallu@example.com');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO t1(email) VALUES('Gallu@example.com');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO t2(email) VALUES('gallu@example.com');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO t2(email) VALUES('Gallu@example.com');
ERROR 1062 (23000): Duplicate entry 'Gallu@example.com' for key 't2.unique_t2_email'

うん予想通り。

一応、再実験くん。

CREATE TABLE `t3` (
  `id` SERIAL,
  `email` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'email',
  UNIQUE KEY `unique_t3_email` (`email`),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ユーザテーブル';

mysql> INSERT INTO t3(email) VALUES('gallu@example.com');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO t3(email) VALUES('Gallu@example.com');
Query OK, 1 row affected (0.00 sec)

うん。
んで、Laravelだと

$table->collation = 'utf8mb4_bin';

で、(カラムには無理だけどテーブルには)貼り付けられる。

という、多分「ってもおいちゃん自身は使うことねぇんだろうなぁ」的Tipsの検証をしたので、一応、めも。

*1:"MySQL INDEX VARCHAR 長さ" とかでググって