Unix上のMYSQLで大文字でTableを作成後にlower_case_table_names=1とした場合に、大文字のTableが検索できない。
概要
OSがUnixかつ大文字でTableを作成後に大文字小文字を区別しないとした場合に、大文字のTableが検索できなくなります。(RedhatとCentOSで現象を確認、Windows7で発生しないことを確認)
詳細
MySQLでは大文字小文字の区別を行うかどうかは「lower_case_table_names」の設定を行うことで変更が可能です。
MySQLでのテーブルとデータベース名の保存方法はlower_case_table_namesシステム変数に影響されます。これはmysqld起動時に設定できます。 lower_case_table_namesは以下のテーブルに示された値をとり得ます。Unixでは、lower_case_table_namesのデフォルト値は 0で、Windowsでは1、Mac OS Xでは2となります。
http://dev.mysql.com/doc/refman/5.1/ja/identifier-case-sensitivity.html
上記の通り、Unixのデフォルト値は0で大文字と小文字を区別します。
mysql> show variables where variable_name='lower_case_table_names'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_table_names | 0 | +------------------------+-------+ 1 row in set (0.00 sec) mysql> show tables; Empty set (0.00 sec) mysql> create table HOGE(HUGA VARCHAR(10)); Query OK, 0 rows affected (0.01 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | HOGE | +----------------+ 1 row in set (0.00 sec) mysql> insert into HOGE(HUGA) value ('PIYO'); Query OK, 1 row affected (0.00 sec) mysql> select * from HOGE; +------+ | HUGA | +------+ | PIYO | +------+ 1 row in set (0.00 sec) mysql> select * from hoge; ERROR 1146 (42S02): Table 'test.hoge' doesn't exist
このように「HOGE」テーブルが存在する状態で、大文字小文字を区別しない設定に変更してみます。
変更するためにはmy.cnfに「lower_case_table_names=1」を加えます。
ちなみにmy.cnfの優先順位は↓の通り。
Linux系のMySQLでは、
http://yoku0825.blogspot.jp/2012/11/mycnf.html
/etc/my.cnf -> /etc/mysql/my.cnf -> SYSCONFDIR/my.cnf -> $MYSQL_HOME/my.cnf -> defaults-extra-fileで指定されたファイル -> $HOME/.my.cnf -> 直接渡したオプション
の順番で読み込まれる。
で、この状態で「HOGE」テーブルを検索してみます。
mysql> show variables where variable_name='lower_case_table_names'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_table_names | 1 | +------------------------+-------+ 1 row in set (0.00 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | HOGE | +----------------+ 1 row in set (0.00 sec) mysql> select * from HOGE; ERROR 1146 (42S02): Table 'test.hoge' doesn't exist mysql> select * from hoge; ERROR 1146 (42S02): Table 'test.hoge' doesn't exist
このように大文字でも小文字でも取得できなくなります。
「lower_case_table_names=1」の説明としては↓とありました。ルックアップ時ってどういうことですか??
テーブル名はディスク上に小文字で記憶され、名前比較では大文字小文字は区別されません。MySQLでは、保管およびルックアップ時に全てのテーブル名が小文字に変換されます。このオプションはデータベース名やテーブルエイリアスにも適用されます。
http://dev.mysql.com/doc/refman/5.1/ja/identifier-case-sensitivity.html
回避策
回避策としては「lower_case_table_names=0」の状態でTable名を小文字に変更するという方法しかみつかりませんでした。
何か他に方法がありましたら教えて下さい。
mysql> show variables where variable_name='lower_case_table_names'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_table_names | 0 | +------------------------+-------+ 1 row in set (0.00 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | HOGE | +----------------+ 1 row in set (0.00 sec) mysql> rename table HOGE to hoge; Query OK, 0 rows affected (0.00 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | hoge | +----------------+ 1 row in set (0.00 sec)
ちなみに、小文字のviewを作成したらどうかと試してみましたが、やはり区別がつかないようでエラーが出ました。
mysql> show variables where variable_name='lower_case_table_names'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_table_names | 0 | +------------------------+-------+ 1 row in set (0.00 sec) mysql> create view hoge as select * from HOGE; Query OK, 0 rows affected (0.00 sec) mysql> select * from hoge; +------+ | HUGA | +------+ | PIYO | +------+ 1 row in set (0.00 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | HOGE | | hoge | +----------------+ 2 rows in set (0.00 sec)
my.cnfに「lower_case_table_names=1」を加えて再起動。
mysql> show variables where variable_name='lower_case_table_names'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_table_names | 1 | +------------------------+-------+ 1 row in set (0.00 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | HOGE | | hoge | +----------------+ 2 rows in set (0.01 sec) mysql> select * from hoge; ERROR 1462 (HY000): `test`.`hoge` contains view recursion mysql> select * from HOGE; ERROR 1462 (HY000): `test`.`hoge` contains view recursion