H2DBのMySQLモードでは重複INDEX名に注意
DBの1種にH2DBというものがあります。
MySQLやPostgreSQLと同様にサーバモードで使うこともできますが、組み込み型・インメモリ型として使うこともできるため、色々な場面で使うことができます。
自分はWebアプリのUnitTestに使っています。インメモリ型で起動してテーブル作成してテストデータ投入して、テストコード実行で使う、というような流れです。
MySQL互換モードがあるけれど過信は禁物
H2DBにはMySQL互換モードというものがあって、JDBC接続文字列の末尾に;MODE=MYSQLと付けるとMySQLっぽい感じで動くようになります。
ですが、残念ながら完璧ではないようで、DB内で同一名称のINDEXを作成できないようです。
実際にやってみるとこうなります。
まずはMySQLの場合です。MySQLではテーブルさえ違えば同一名称INDEXは問題ありません。
mysql> create table FOO(ID INT PRIMARY KEY, VALUE INT, KEY INDEX_NAME_A (VALUE));
Query OK, 0 rows affected (0.04 sec)
mysql> create table BAR(ID INT PRIMARY KEY, VALUE INT, KEY INDEX_NAME_A (VALUE));
Query OK, 0 rows affected (0.02 sec)
FOOとBARで同一名称のINDEX_NAME_Aがありますが問題ありません。
H2DBはというと・・・
sql> create table FOO(ID INT PRIMARY KEY, VALUE INT, KEY INDEX_NAME_A (VALUE))
0 row(s) affected in 43 ms
sql> create table BAR(ID INT PRIMARY KEY, VALUE INT, KEY INDEX_NAME_A (VALUE))
[2014-10-05 14:08:35] [42S11][42111] インデックス "INDEX_NAME_A" はすでに存在します
Index "INDEX_NAME_A" already exists; SQL statement:
create table BAR(ID INT PRIMARY KEY, VALUE INT, KEY INDEX_NAME_A (VALUE)) [42111-175]
java.sql.SQLException: インデックス "INDEX_NAME_A" はすでに存在します
Index "INDEX_NAME_A" already exists; SQL statement:
create table BAR(ID INT PRIMARY KEY, VALUE INT, KEY INDEX_NAME_A (VALUE)) [42111-175]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
at org.h2.message.DbException.get(DbException.java:172)
at org.h2.message.DbException.get(DbException.java:149)
at org.h2.command.ddl.CreateIndex.update(CreateIndex.java:66)
at org.h2.command.ddl.CreateTable.update(CreateTable.java:169)
at org.h2.command.CommandContainer.update(CommandContainer.java:79)
at org.h2.command.Command.executeUpdate(Command.java:253)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:181)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:156)
in RemoteStatementImpl.execute(RemoteStatementImpl.java:61)
at com.sun.proxy.$Proxy136.execute(Unknown Source)
in JdbcEngine.executeQueryInner(JdbcEngine.java:385)
これだけのことで2時間近くはまってしまった・・・・