日向夏特殊応援部隊

俺様向けメモ

varcharとutf8

ちとvarcharのutf8を誤解してました。

CREATE TABLE bar (
  id int(11) NOT NULL default '0',
  name varchar(4) default NULL,
  PRIMARY KEY  (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

こんな風にテーブル作った際に、マルチバイトだろうが半角英数字だろうが4文字と扱われます。
てっきりバイト換算だと思ってた。

ヒント:スペースを UTF8 で保存するには、CHAR ではなく VARCHAR を使用してください。 そのようにしないと、MySQL では CHAR(10) CHARACTER SET utf8 カラムに対して 30 バイトを確保しなければなりません。これは、使用可能な最大長が 30 バイトであるためです。

これが多分ソースかなぁ。

#!/usr/bin/perl

use strict;
use warnings;

our $seq = 0;
our @chars = ('a' .. 'i');
our @multibyte_chars = ('あ', 'い', 'う', 'え', 'お');

use DBI;

my $dbh = DBI->connect('dbi:mysql:database=test', 'root');
my $sth = $dbh->prepare('INSERT INTO bar(id, name) VALUES(?, ?)');

for (my $i = 0; $i < scalar @chars; $i++) {
    $seq++;
    my $char = join("" => @{chars}[0 .. $i]);

    $sth->execute($seq, $char);
}

for (my $i = 0; $i < scalar @multibyte_chars; $i++) {
    $seq++;
    my $char = join("" => @{multibyte_chars}[0 .. $i]);

    $sth->execute($seq, $char);
}

コードが凄いDRYじゃないのはもう気にしない事にしてw


さて実行結果。

mysql> select * from bar;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | a            |
|  2 | ab           |
|  3 | abc          |
|  4 | abcd         |
|  5 | abcd         |
|  6 | abcd         |
|  7 | abcd         |
|  8 | abcd         |
|  9 | abcd         |
| 10 | あ           |
| 11 | あい         |
| 12 | あいう       |
| 13 | あいうえ     |
| 14 | あいうえ     |
+----+--------------+

勝手にtruncateされますね。されないで怒るoptionとかありそうだけど今日はここまで(誰?