フィールドを Unique にする方法
mysql> alter table 対象テーブル add unique (対象フィールド);
作業ログ(フィールドサイズが 999 バイトを超えていたら)
今回 support テーブルの uri フィールドをユニーク化しようとしたが、
mysql> alter table support add unique (uri);
ERROR 1071 (42000): Specified key was too long; max key length is 999 bytes
となってしまった。定義を調べると、
mysql> show fields from support;
+---------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| uri | varchar(512) | NO | MUL | | |
| title | varchar(1024) | NO | MUL | | |
| content | mediumtext | YES | | NULL | |
| updated | timestamp | NO | | CURRENT_TIMESTAMP | |
+---------+---------------+------+-----+-------------------+----------------+
512だが、UTF-8なので超えてしまっているのだろう。
実際には数文字しか入っていないので別のフィールド uri2 を作って、そこに値をコピーしてからユニーク化して、元の列を削除してリネームすることにした。
127なら4倍しても999バイトには届かないので、varchar(127) で定義する。
mysql> alter table support add column uri2 varchar(127);
Query OK, 20799 rows affected (1 min 0.37 sec)
Records: 20799 Duplicates: 0 Warnings: 0
uri フィールドから uri2 フィールドに値をコピーする。
mysql> update support set uri2 = uri;
Query OK, 20799 rows affected (6 min 30.64 sec)
Rows matched: 20799 Changed: 20799 Warnings: 0
uri フィールドを削除する。
mysql> alter table support drop uri;
Query OK, 20799 rows affected (1 min 0.60 sec)
Records: 20799 Duplicates: 0 Warnings: 0
uri2 フィールドをユニークにする。
mysql> alter table support add unique (uri2);
Query OK, 20799 rows affected (1 min 1.66 sec)
Records: 20799 Duplicates: 0 Warnings: 0
uri2 から uri フィールド名を変更する(id フィールドの後ろに移す)。
mysql> alter table support change column \`uri2\` \`uri\` varchar(127) after id;
Query OK, 20799 rows affected (1 min 0.41 sec)
Records: 20799 Duplicates: 0 Warnings: 0
mysql> show fields from support;
+---------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| uri | varchar(127) | YES | UNI | NULL | |
| title | varchar(1024) | NO | MUL | | |
| content | mediumtext | YES | | NULL | |
| updated | timestamp | NO | | CURRENT_TIMESTAMP | |
+---------+---------------+------+-----+-------------------+----------------+
5 rows in set (0.00 sec)
実は列名を変更するときに定義も変更できる(というか指定する)ことに気づいた。
ということで本当は、
mysql> alter table support change column \`uri\` \`uri\` varchar(127);
mysql> alter table support add unique (uri);
だけでいけたかもしれない。