つかびーの技術日記

(情報)工学修士, 元SIer SE, 現Web系 SEの技術blogです。Scala, Java, JS, TS, Python, Ruby, AWS, GCPあたりが好きです。

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

 - H2DB, MySQL