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時間近くはまってしまった・・・・