H2 Logo
English Japanese
検索:

Highlight keyword(s)
ホーム
クイックスタート
インストール
チュートリアル
特徴
パフォーマンス
進歩したトピックス
JaQu
ダウンロード

参照
SQL文法
関数
データ型
Javadoc
PDFドキュメント
Error Analyzer

付録
ビルド
歴史とロードマップ
Links
FAQ
ライセンス

 

特徴

特徴一覧
Limitations
他のデータベースエンジンと比較する
H2 in Use
接続モード
データベースURL概要
エンベッド (ローカル) データベースに接続
メモリオンリーデータベース
暗号化ファイルと共にデータベースへ接続する
データベースファイルロック
すでに存在する場合のみ、データベースを開く
データベースを終了する
未知の設定を無視
接続が開始された時に他の設定を変更する
ログインデックスの修正
カスタムファイル アクセスモード
複数の接続
データベースファイルレイアウト
ログとリカバリー
互換性
Auto-Reconnect
Automatic Mixed Mode
トレースオプションを使用する
Using Other Logging APIs
読み取り専用データベース
Read Only Databases in Zip or Jar File
バイナリーとテキストストレージフォーマット
ディスクスペースが少ない状況での正しい取り扱い
computed column / ベースインデックスの機能
多次元インデックス
パスワードを使用する
ユーザー定義の関数とストアドプロシージャ
トリガー
データベースをコンパクトにする
キャッシュの設定

特徴一覧

主な特徴

  • 非常に高速なデータベースエンジン
  • 無料、ソースコード付き
  • Javaで記載
  • 標準規格のSQL、JDBC APIをサポート
  • エンベッドモードとサーバーモード、クラスタリングをサポート
  • 強力なセキュリティ機能
  • The PostgreSQL ODBC driver can be used
  • Multi version concurrency

追加された特徴

  • ディスクベースデータベース、またはインメモリデータベースと、テーブル、読み取り専用データベースをサポート、テンポラリテーブル
  • トランザクションをサポート (トランザクション分離の serializable (直列化))、2フェーズコミット
  • 複数の接続、テーブルレベルのロック
  • コストベースオプティマイザ、複雑なクエリーのために遺伝的アルゴリズムを使用、zero-administration
  • スクロール可能result setと更新可能result setをサポート、大きなresult set、外部結果ソート、 関数はresult setを返す
  • 暗号化されたデータベース (AES または XTEA), SHA-256 パスワード暗号化、暗号化関数、SSL

SQLサポート

  • 複数のスキーマ、インフォメーションスキーマをサポート
  • 参照整合性 / カスケードでの外部キー制約、チェック制約
  • 内部結合と外部結合、サブクエリー、読み取り専用ビューとインラインビュー
  • トリガーと Java関数 / ストアドプロシージャ
  • 多数の組み込み関数、XMLとlossless data compression (可逆圧縮) を含む
  • 大きなオブジェクト (BLOB/CLOB) とArrayを含む、広い範囲のデータ型
  • シーケンスとautoincrement column、computed column、(関数ベースのインデックスに使用できます)
  • ORDER BY, GROUP BY, HAVING, UNION, LIMIT, TOP
  • Collationをサポート、users、roles
  • HSQLDB、MySQLとPostgreSQLのための互換モード

セキュリティの特徴

  • SQLインジェクション問題の解決を含む
  • SHA-256とsaltを使ってユーザーパスワードが本物であることを証明する
  • ユーザーパスワードは決してプレーンテキストでネットワーク上に送信されることはない (たとえ不安定な接続を使用していたとしても)
  • AES-256とXTEA暗号化アルゴリズムを使用することで、全てのデータベースファイル (データのバックアップを取るのに使用できるスクリプトファイルを含む) を暗号化できる
  • リモートJDBCドライバは、SSL/TLS上のTCP/IP接続をサポート
  • 組み込みwebサーバーは、SSL/TLS上の接続をサポート
  • Stringの代わりにchar arrayを使うことで、パスワードをデータベースに送信可能

他の特徴とツール

  • 省スペース (1MBより小さい)、少ないメモリが必要条件
  • Multiple index types (b-tree, tree, hash)
  • 多次元のインデックスをサポート
  • CSV (comma separated values) ファイルサポート
  • リンクテーブルと組み込み仮想 "range" テーブルのサポート
  • EXPLAIN PLANをサポート、 洗練されたトレースオプション
  • パフォーマンスを向上させるために、データベースの終了を遅らせるか割り込みを抑制する
  • Webベースのコンソールアプリケーション (英語、ドイツ語、部分的にフランス語とスペイン語) が自動完備
  • データベースはSQLスクリプトファイルを生成
  • データファイルのコンテンツを移動することができるリカバリーツールを含む
  • Support for variables (for example to calculate running totals)
  • prepared statementの自動再編集
  • 少数のデータベースファイル、バイナリー、テキストストレージ形式を使用、ディスクスペースが少ない状況での正しい取り扱い
  • 各レコードのためのチェックサムと、データ整合性のためのログエントリーを使用
  • 十分なテスト済み (高いコードカバー率、ランダムストレステスト)

Limitations

For the list of limitations, please have a look at the road map page at: http://groups.google.com/group/h2-database/web/roadmap


他のデータベースエンジンと比較する

特徴 H2 Derby HSQLDB MySQL PostgreSQL
Pure Java 対応 対応 対応 非対応 非対応
エンベッドモード (Java) 対応 対応 対応 非対応 非対応
パフォーマンス (エンベッド) 速い 遅い 速い 該当なし 該当なし
In-Memory Mode 対応 非対応 対応 非対応 非対応
トランザクション分離 対応 対応 非対応 対応 対応
コストベースオプティマイザ 対応 対応 非対応 対応 対応
クラスタリング 対応 非対応 非対応 対応 対応
暗号化データベース 対応 対応 非対応 非対応 非対応
リンクテーブル 対応 非対応 Partially *1 Partially *2 非対応
ODBCドライバ 対応 非対応 非対応 対応 対応
フルテキストサーチ 対応 非対応 非対応 対応 対応
User-Defined Datatypes 対応 非対応 非対応 対応 対応
データベースごとのファイル 少 多 少 多 多
テーブルレベルロック 対応 対応 非対応 対応 対応
Row Level Locking Yes *9 対応 非対応 対応 対応
Multi Version Concurrency 対応 非対応 非対応 非対応 対応
Role Based Security 対応 Yes *3 対応 対応 対応
Updatable Result Sets 対応 Yes *7 非対応 対応 対応
Sequences 対応 非対応 対応 非対応 対応
Limit and Offset 対応 非対応 対応 対応 対応
Temporary Tables 対応 Yes *4 対応 対応 対応
Information Schema 対応 No *8 No *8 対応 対応
Computed Columns 対応 非対応 非対応 非対応 Yes *6
Case Insensitive Columns 対応 非対応 対応 対応 Yes *6
Custom Aggregate Functions 対応 非対応 非対応 対応 対応
フットプリント (jar/dll size) ~1 MB *5 ~2 MB ~600 KB ~4 MB ~6 MB

*1 HSQLDB supports text tables.
*2 MySQL supports linked MySQL tables under the name 'federated tables'.
*3 Derby support for roles based security and password checking as an option.
*4 Derby only supports global temporary tables.
*5 The default H2 jar file contains debug information, jar files for other databases do not.
*6 PostgreSQL supports functional indexes.
*7 Derby only supports updatable result sets if the query is not sorted.
*8 Derby and HSQLDB don't support standard compliant information schema tables. *9 H2 supports row level locks when using multi version concurrency.

DerbyとHSQLDB

After an unexpected process termination (for example power failure), H2 can recover safely and automatically without any user interaction. For Derby and HSQLDB, some manual steps are required ('Another instance of Derby may have already booted the database' / 'The database is already in use by another process').

DaffodilDbとOne$Db

このデータベースの開発は止まっているようです。最後のリリースは2006年2月でした。

McKoi

このデータベースの開発は止まっているようです。最後のリリースは2004年8月でした。


H2 in Use

For a list of applications that work with or use H2, see: Links .


接続モード

以下の接続モードがサポートされています:

  • Embedded mode (local connections using JDBC)
  • Remote mode (remote connections using JDBC or ODBC over TCP/IP)
  • Mixed mode (local and remote connections at the same time)

エンベッドモード

In embedded mode, an application opens a database from within the same JVM using JDBC. This is the fastest and easiest connection mode. The disadvantage is that a database may only be open in one virtual machine (and class loader) at any time. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently, or on the number of open connections.

The database is embedded in the application

Remote Mode

When using the remote mode (sometimes called server mode or client/server mode), an application opens a database remotely using the JDBC or ODBC API. A server needs to be started within the same or another virtual machine (or on another computer). Many applications can connect to the same database at the same time. The remote mode is slower than the embedded mode, because all data is transferred over TCP/IP. As in all modes, both persistent and in-memory databases are supported. There is no limit on the number of database open concurrently, or on the number of open connections.

The database is running in a server; the application connects to the server

Mixed Mode

The mixed mode is a combination of the embedded and the remote mode. The main application connects to a database in embedded mode, but also starts a server so that other applications (running in different virtual machines) can concurrently access the same data. The embedded connections are as fast as if the database is used in just the embedded mode, while the remote connections are a bit slower.

The database and the server is running inside the application; another application connects remotely

データベースURL概要

This database supports multiple connection modes and connection settings. This is achieved using different database URLs. Settings in the URLs are not case sensitive.

トピック URLフォーマットと例
エンベッド (ローカル) 接続 jdbc:h2:[file:][<path>]<databaseName>
jdbc:h2:~/test
jdbc:h2:file:/data/sample
jdbc:h2:file:C:/data/sample (Windowsのみ)
インメモリ (プライベート) jdbc:h2:mem:
インメモリ (名付ける) jdbc:h2:mem:<databaseName>
jdbc:h2:mem:test_mem
TCP/IPを使用したリモート jdbc:h2:tcp://<server>[:<port>]/<databaseName>
jdbc:h2:tcp://localhost/~/test
jdbc:h2:tcp://dbserv:8084/~/sample
SSL/TLSを使用したリモート jdbc:h2:ssl://<server>[:<port>]/<databaseName>
jdbc:h2:ssl://secureserv:8085/~/sample;
暗号化ファイルの使用 jdbc:h2:<url>;CIPHER=[AES|XTEA]
jdbc:h2:ssl://secureserv/~/testdb;CIPHER=AES
jdbc:h2:file:~/secure;CIPHER=XTEA
ファイルロックメソッド jdbc:h2:<url>;FILE_LOCK={NO|FILE|SOCKET}
jdbc:h2:file:~/quickAndDirty;FILE_LOCK=NO
jdbc:h2:file:~/private;CIPHER=XTEA;FILE_LOCK=SOCKET
すでに存在する場合は起動のみ jdbc:h2:<url>;IFEXISTS=TRUE
jdbc:h2:file:~/sample;IFEXISTS=TRUE
VMが終了した時、データベースを終了しない jdbc:h2:<url>;DB_CLOSE_ON_EXIT=FALSE
ユーザー名、及びパスワード jdbc:h2:<url>[;USER=<username>][;PASSWORD=<value>]
jdbc:h2:file:~/sample;USER=sa;PASSWORD=123
ログインデックスの修正 jdbc:h2:<url>;LOG=2
jdbc:h2:file:~/sample;LOG=2
デバックトレースの設定 jdbc:h2:<url>;TRACE_LEVEL_FILE=<level 0..3>
jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3
未知の設定を無視 jdbc:h2:<url>;IGNORE_UNKNOWN_SETTINGS=TRUE
カスタムファイル アクセスモード jdbc:h2:<url>;ACCESS_MODE_LOG=rws;ACCESS_MODE_DATA=rws
Database in or Zip File jdbc:h2:zip:<zipFileName>!/<databaseName>
jdbc:h2:zip:~/db.zip!/test
Compatibility Mode jdbc:h2:<url>;MODE=<databaseType>
jdbc:h2:~/test;MODE=MYSQL
Auto-Reconnect jdbc:h2:<url>;AUTO_RECONNECT=TRUE
jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE
Automatic Mixed Mode jdbc:h2:<url>;AUTO_SERVER=TRUE
jdbc:h2:~/test;AUTO_SERVER=TRUE
他の設定の変更 jdbc:h2:<url>;<setting>=<value>[;<setting>=<value>...]
jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3

エンベッド (ローカル) データベースに接続

The database URL for connecting to a local database is jdbc:h2:[file:][<path>]<databaseName> . The prefix file: is optional. If no or only a relative path is used, then the current working directory is used as a starting point. The case sensitivity of the path and database name depend on the operating system, however it is recommended to use lowercase letters only. The database name must be at least three characters long (a limitation of File.createTempFile). To point to the user home directory, use ~/, as in: jdbc:h2:~/test.


メモリオンリーデータベース

特定の使用方法では (例: rapid prototyping、テスト、高パフォーマンスオペレーション、読み取り専用データベース)、データは持続する (変化する) 必要は全くないかもしれません。このデータベースは、データが持続しない際にメモリオンリーモードをサポートします。

一部ケースでは、メモリオンリーデータベースへの接続はひとつの接続のみ必要とされます。これは、開かれるデータベースがプライベートだということを意味しています。このケースでは、データベースURLは jdbc:h2:mem: です。同じ仮想マシン内で二つの接続が開いているというのは、二つの異なった (プライベートの) データベースが開いているという意味です。

時々、複数の接続が同じメモリオンリーデータベースを必要とします。このケースでは、データベースのURLに名前が含まれていなければなりません。例: jdbc:h2:mem:db1 この方法での同じデータベースのアクセスは、同じ仮想マシンとClassLoader環境内でのみ動作します。

TCP/IPまたは、SSL/TLSを使用して、メモリオンリーデータベースに間接的に (または、同じマシンの複数のプロセスから) 接続することも可能です。データベースURLの例: jdbc:h2:tcp://localhost/mem:db1 (プライベートデータベースを間接的に使用することも可能です)

By default, when the last connection to a in-memory database is closed, the contents are lost. This can be disabled by adding ;DB_CLOSE_DELAY=-1 to the database URL. That means to keep the contents of an in-memory database as long as the virtual machine is alive, use jdbc:h2:mem:test;DB_CLOSE_DELAY=-1


暗号化ファイルと共にデータベースへ接続する

ファイルを暗号化して使用するためには、暗号化アルゴリズム ("cipher") とファイルパスワードを指定することが必要です。アルゴリズムは、接続パラメータを使用することで指定される必要があります。二つのアルゴリズムがサポートされています: XTEAとAES です。ファイルパスワードは、ユーザーパスワードの前のパスワードフィールドで指定されます。ファイルパスワードとユーザーパスワードの間に、シングルスペースを加えることが必要です; ファイルパスワードそのものにはスペースは含まれません。ファイルパスワードは (ユーザーパスワードも同様) 大文字と小文字を区別しています。こちらがパスワードの暗号化されたデータベースに接続するための例です:

Class.forName("org.h2.Driver");
String url = "jdbc:h2:~/test;CIPHER=AES";
String user = "sa";
String pwds = "filepwd userpwd";
conn = DriverManager.
    getConnection(url, user, pwds);

データベースファイルロック

データベースが開かれるときはいつも、データベースが使用中であると他のプロセスに合図するためにロックファイルが作成されます。もしデータベースが閉じられるか、データベースを開いたプロセスが終了するなら、ロックファイルは削除されます。

以下のファイルロックメソッドが提供されます:

  • デフォルトメソッドは "file" で、データベースファイルを保護するために、watchdogスレッドを使用します。watchdogは、ロックファイルをそれぞれ秒単位で読み込みます。
  • 二つめのメソッドは "socket" で、サーバーソケットを開きます。ソケットメソッドは、ロックファイルを秒単位で読むことを必要としていません。ソケットメソッドは、データベースファイルがひとつの (いつも同じ) コンピューターのみによってアクセスされる場合にのみ使用されます。
  • ファイルロッキングなしでデータベースを開始することも可能です; このケースでは、データベースファイルを保護するのはアプリケーション次第です。

異なったファイルロックメソッドでデータベースを開くには、"FILE_LOCK" パラメータを使用します。以下のコードは "socket" ロックメソッドのデータベースを開きます:

String url = "jdbc:h2:~/test;FILE_LOCK=SOCKET";

以下のコードは、データベースにロックファイルを全く作らないよう強要させます。これは、データ破損を導く可能性のある、同じデータベースを開くことができる他のプロセスのように、安全ではないということに注意して下さい:

String url = "jdbc:h2:~/test;FILE_LOCK=NO";

アルゴリズムについての詳しい情報は、進化したトピックス のファイルロックプロトコルをご覧下さい。


すでに存在する場合のみ、データベースを開く

デフォルトでは、アプリケーションが DriverManager.getConnection(url,...) を呼び出し、URLで指定されたデータベースがまだ存在しない時、 新しい (空の) データベースが作成されます。ある状況では、もしすでにデータベースが存在するのであれば、新しいデータベースの作成を制限して、データベースを開くだけにした方がよいでしょう。;ifexists=true をURLに追加することによって可能になります。このケースでは、もしデータベースがまだ存在していなければ、接続しようとした時に例外が投げられます。接続は、データベースがすでに存在する時のみ成功します。完全なURLは次のようです:

String url = "jdbc:h2:/data/sample;IFEXISTS=TRUE";

データベースを終了する

データベースの遅延終了

通常、データベースへの最後の接続が閉じられた時、データベースが終了されます。一部状況では、例えば、可能ではない時に接続をつなげたままにしておくことは、アプリケーションを減速させます。SQLステートメントの SET DB_CLOSE_DELAY <seconds> でデータベースの自動終了を遅らせるか、または無効にすることができます。secondsには、最後の接続が閉じられた後データベースを接続したままの状態に保つため、秒数を指定します。例えば、次のステートメントはデータベースを10秒間開かれた状態に保ちます:

SET DB_CLOSE_DELAY 10

値の-1は、データベースは決して自動的に閉じられないということを意味します。値の0はデフォルトで、最後の接続が終了した時データベースが終了するということを意味します。この設定は永続的で、管理者のみが設定することができます。データベースのURL内で値を設定することが可能です: jdbc:h2:~/test;DB_CLOSE_DELAY=10


VMが終了した時、データベースを終了しない

デフォルトでは、データベースは最後の接続が閉じられた時に終了されます。しかし、最後の接続が決して閉じられなければ、仮想マシンが正常に終了する時にデータベースは閉じられます。これはshutdown hookを使うことによって行われます。一部状況では、データベースはこのケースで終了されてはいけません。例えば、仮想マシンが終了している時にデータベースがまだ使われている場合です (例として、シャットダウンプロセスをデータベースに保存するため)。このケースでは、データベースURLでデータベースの自動終了を無効にすることが可能です。最初の接続は (ひとつはデータベースを開始するもの) データベースURLにオプションを設定する必要があります (設定を後で変更することは不可能です)。VMが終了する時、データベースの終了を無効にするためのデータベースURLです:

String url = "jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE";

ログインデックスの修正

通常、インデックスファイルの変更はパフォーマンスのために記録されません。データベースを開いた時に、インデックスファイルが破損しているか、無くなっていたら、データから作り直されます。停電、またはプログラムの異常終了のため、データベースが正しく終了されなかった時、インデックスファイルは破損されます。一部状況では、例えば、非常に大きなデータベースを使用している時 (数百MB以上)、インデックスファイルが再作成されるのにはとても時間がかかります。それらの状況では、インデックスファイルの変更を記録しておいた方がよいでしょう。そうすることによって、破損されたインデックスファイルの回復が速くなります。ログインデックスの修正を可能にするためには、jdbc:h2:~/test;LOG=2 のように、URLに LOG=2 を追加して下さい。接続する時に、この設定が指定されます。このオプションを使用する時、データベースのアップデートパフォーマンスは低下するでしょう。


未知の設定を無視

データベースに接続する時、いくつかのアプリケーションが (例えば、OpenOffice.org Base) いくつかの追加パラメータを渡します。なぜそれらのパラメータが渡されるのかは知られていません。PREFERDOSLIKELINEENDS と IGNOREDRIVERPRIVILEGES はパラメータの例で、それらは、OpenOffice.orgとの互換性を改良するために単に無視されます。もしデータベースに接続する時、アプリケーションが他のパラメータを渡していたら、通常データベースは、 パラメータはサポートされていません、という例外を投げます。データベースURLに ;IGNORE_UNKNOWN_SETTINGS=TRUE を追加することで、このようなパラメータを無視することが可能です。


接続が開始された時に他の設定を変更する

すでに記述された設定に加えて (暗号、ファイルロック、データベースの存在、ユーザー、パスワード)、他のデータベースの設定は、データベースURLの中で渡すことができます。SET setting valueステートメントを接続直後に実行するのと同じように 、setting=value をURLの最後に追加します。このデータベースによってサポートされている設定の一覧は、SQL文法のドキュメントをご覧下さい。


カスタムファイル アクセスモード

Usually, the database opens log, data and index files with the access mode 'rw', meaning read-write (except for read only databases, where the mode 'r' is used). To open a database in read-only mode if the files are not read-only, use ACCESS_MODE_DATA=r. Also supported are 'rws' and 'rwd'. The access mode used for log files is set via ACCESS_MODE_LOG; for data and index files use ACCESS_MODE_DATA. These settings must be specified in the database URL:

String url = "jdbc:h2:~/test;ACCESS_MODE_LOG=rws;ACCESS_MODE_DATA=rws";

詳細は 永続性問題 をご覧下さい。 多くのオペレーティングシステムでは、アクセスモード "rws" において、データがディスクに書かれていることを保証しません。


複数の接続

同時に複数のデータベースを開く

アプリケーションは、同じデータベースへの複数の接続を含め、複数のデータベースを同時に開くことができます。開くデータベースの数は、利用可能なメモリによってのみ制限されています。

>同じデータベースへの複数の接続: クライアント/サーバー

異なったプロセス、またはコンピューターから同時に同じデータベースにアクセスしたい場合、クライアント/サーバー モードを使用することが必要です。このケースでは、ひとつのプロセスがサーバーとして動作し、他のプロセスは (同様に他のコンピューターに属することができます) TCP/IP (または改善されたセキュリティ用のTCP/IPの上のSSL/TLS) を通してサーバーに接続します。

マルチスレッドサポート

このデータベースは安全なマルチスレッドです。これは、アプリケーションがマルチスレッドならば、データベースへの同時アクセスに関して心配する必要がない、ということを意味しています。本質的に、同じデータベースへのほとんどのリクエストは同時に動きます。アプリケーションは、同時に同じデータベースにアクセスするマルチスレッドを使用することができますが、ひとつのスレッドが処理時間の長いクエリーを実行しているなら、他のスレッドは待つ必要があります。

ロック、ロックタイムアウト、デッドロック

データの一貫した状態をそれぞれの接続に与えるために、データベースはテーブルレベルでのロックを使用します。二種類のロックがあります: リードロック (共有ロック) とライトロック (排他ロック) です。もし、接続がテーブルから読み込みたい場合で、テーブルにライトロックがない場合に、リードロックをテーブルに追加します。もしライトロックがあれば、この接続はロックを解除するために他の接続を待ちます。接続が指定された時間までにロックを取得できなければ、ロックタイムアウトの例外が投げられます。

通常、SELECTステートメントはリードロックを生成します。これはサブクエリーも含まれます。データを修正するステートメントはライトロックを使用します。SELECT ... FOR UPDATE ステートメントを使用して、データの修正がなくても排他的にテーブルをロックすることも可能です。COMMITとROLLBACKステートメントは全ての周知のロックを解除します。SAVEPOINTとROLLBACK TO SAVEPOINTコマンドはロックに影響を及ぼしません。ロックはオートコミットモードに変更した時、オートコミットの接続がtrueにセットされた時 (この状態がデフォルトです) にも解除され、ロックはそれぞれのステートメントの後に解除されます。これは、どのステートメントでどんな種類のロックが生成されるかの概観です:

ロックの種類 SQLステートメント
Read SELECT * FROM TEST
CALL SELECT MAX(ID) FROM TEST
SCRIPT
Write SELECT * FROM TEST WHERE 1=0 FOR UPDATE
Write INSERT INTO TEST VALUES(1, 'Hello')
INSERT INTO TEST SELECT * FROM TEST
UPDATE TEST SET NAME='Hi'
DELETE FROM TEST
Write ALTER TABLE TEST ...
CREATE INDEX ... ON TEST ...
DROP INDEX ...

SQLコマンド SET LOCK_TIMEOUT <milliseconds> を使用して、ロックタイムアウトの例外が投げられるまでの秒数を、それぞれの接続ごとに別々に設定することができます。SQLコマンド SET DEFAULT_LOCK_TIMEOUT <milliseconds> を使用して、初期のロックタイムアウト (新しい接続に使用されるタイムアウト) を設定することができます。デフォルトのロックタイムアウトは永続的です。


データベースファイルレイアウト

永続的なデータベースのために作成された多くのファイルがあります。一部のデータベースを除いて、全てのテーブルと (または) インデックスが自身のファイル内に保存されているわけではありません。その代りに、通常次のファイルのみが作成されます: データファイル、インデックスファイル、ログファイル、データベースロックファイル (データベースが使われている間のみ存在します)。それに加えて、ファイルはそれぞれの大きなオブジェクト (CLOB/BLOB) のために作成されます。各ライナーインデックスのためのファイル、大きなresult setのためのテンポラリーファイルです。データベーストレースオプションが有効の場合、トレースファイルが作成されます。次のファイルはデータベースによって作成されます:

ファイル名 説明 ファイル数
test.data.db データファイル
全てのテーブルのデータを含む
フォーマット: <database>.data.db
データベースごとに1ファイル
test.index.db インデックスファイル
全ての (btree) インデックスのデータを含む
フォーマット: <database>.index.db
データベースごとに1ファイル
test.0.log.db ログファイル
ログファイルはリカバリーのために使われる
フォーマット: <database>.<id>.log.db
データベースごとに0ファイル以上
test.lock.db データベースロックファイル
データベースが開かれている時のみ存在
フォーマット: <database>.lock.db
データベースごとに1ファイル
test.trace.db トレースファイル
トレース情報を含む
フォーマット: <database>.trace.db
ファイルが大きすぎる場合、<database>.trace.db.old に改名される
データベースごとに1ファイル
test.14.15.lob.db 大きなオブジェクト
BLOB、またはCLOBのデータを含む
フォーマット: <database>.<tableid>.<id>.lob.db
オブジェクトごとに1ファイル
test.123.temp.db テンポラリーファイル
テンポラリーblob、または大きなresult setを含む
フォーマット: <database>.<session id>.<object id>.temp.db
オブジェクトごとに1ファイル
test.7.hash.db ハッシュインデックスファイル
ライナーハッシュインデックスのデータを含む
フォーマット: <database>.<object id>.hash.db
ライナーハッシュインデックスごとに1ファイル

データベースファイルの移動と改名

データベースの名前と位置は、データベース名の中には保存されません。

データベースが閉じられている間、ファイルは他のディレクトリに移動することができ、同様にファイル名を変えることもできます (全てのファイルが同じ名前で始まる必要があります)。

ファイルにはプラットホーム固有のデータがないので、問題なく他のオペレーティングシステムに移動することができます。

バックアップ

データベースが閉じられている時、データベースファイルのバックアップをとることが可能です。インデックスファイルはバックアップをとる必要はありません。なぜなら、インデックスファイルは冗長なデータを含み、もしファイルが存在しなければ自動的に再作成されるからです。

データベースが動作している間にバックアップデータをとるために、SQLコマンド SCRIPTを使うことができます。


ログとリカバリー

データベースでデータが修正され、それらの変更がコミットされた時はいつでも、変更はディスクに記録されます (インメモリオブジェクトを除いて)。データファイル自体への変更は通常、ディスクアクセスを最適化するために後で書かれています。もし電源異常があった場合、データファイルとインデックスファイルはアップデートされません。しかし、変更がログファイルに書かれていれば、次回データベースを開いた時に、ログファイルに書かれた変更は自動的に再び適用されます。

インデックスファイルのアップデートはデフォルトでは記録されないことに注意して下さい。もしデータベースが開かれて、リカバリーが必要だとされたら、インデックスファイルは最初から作り替えられます。

通常、データベースごとにたったひとつのログファイルがあります。このファイルは、データベースが正常に終了されるまで増大し、削除されます。また、ファイルが大きくなりすぎたら、データベースは別のログファイルに交換します (より大きなIDで)。CHECKPOINT コマンドを使用することによって、ログの切り替えを強制することが可能です。

checksumのレコードが合わないために (例えば、別のアプリケーションからファイルが編集された場合) データベースファイルが破損したら、データベースをリカバリーモードで開くことができます。このケースでは、データベースのエラーは記録されますが、投げられません。データベースはスクリプトまでバックアップをとり、可能な限り早く再構築します。データベースをリカバリーモードで開くために、jdbc:h2:~/test;RECOVER=1 のように、RECOVER=1 を含むデータベースURLを使用します。この場合、インデックスは再構築され、サマリー (アロケーションテーブルのオブジェクト)は読まれないため、データベースを開くのに時間がかかります。


互換性

All database engines behave a little bit different. Where possible, H2 supports the ANSI SQL standard, and tries to be compatible to other databases. There are still a few differences however:

In MySQL text columns are case insensitive by default, while in H2 they are case sensitive. However H2 supports case insensitive columns as well. To create the tables with case insensitive texts, append IGNORECASE=TRUE to the database URL (example: jdbc:h2:~/test;IGNORECASE=TRUE).

互換モード

For certain features, this database can emulate the behavior of specific databases. Not all features or differences of those databases are implemented. Here is the list of currently supported modes and the difference to the regular mode:

PostgreSQL Compatibility Mode

To use the PostgreSQL mode, use the database URL jdbc:h2:~/test;MODE=PostgreSQL or the SQL statement SET MODE PostgreSQL .

  • Concatenation of a NULL with another value results in NULL. Usually, the NULL is treated as an empty string if only one of the operators is NULL, and NULL is only returned if both values are NULL.
  • When converting a floating point number to a integer, the fractional digits should not be truncated, but the value should be rounded.
  • The system columns 'CTID' and 'OID' should be supported.
  • For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null.

MySQL Compatibility Mode

To use the MySQL mode, use the database URL jdbc:h2:~/test;MODE=MySQL or the SQL statement SET MODE MySQL .

  • When inserting data, if a column is defined to be NOT NULL and NULL is inserted, then a 0 (or empty string, or the current timestamp for timestamp columns) value is used. Usually, this operation is not allowed and an exception is thrown.
  • When converting a floating point number to a integer, the fractional digits should not be truncated, but the value should be rounded.
  • The identifiers should be returned in lower case.
  • Creating indexes in the CREATE TABLE statement should be supported.
  • For aliased columns, ResultSetMetaData.getColumnName() and getTableName() return the real column and table name.

HSQLDB Compatibility Mode

To use the HSQLDB mode, use the database URL jdbc:h2:~/test;MODE=HSQLDB or the SQL statement SET MODE HSQLDB .

  • Concatenation of a NULL with another value results in NULL. Usually, the NULL is treated as an empty string if only one of the operators is NULL, and NULL is only returned if both values are NULL.
  • When converting the scale of decimal data, the number is only converted if the new scale is smaller then current scale. Usually, the scale is converted and 0s are added if required.
  • When using unique indexes, multiple rows with NULL in one of the columns are allowed by default. However many databases view NULL as distinct in this regard and only allow one row with NULL.
  • For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null.

MS SQL Server Compatibility Mode

To use the MS SQL Server mode, use the database URL jdbc:h2:~/test;MODE=MSSQLServer or the SQL statement SET MODE MSSQLServer .

  • Identifiers may be quoted using square brackets as in [Test].
  • When using unique indexes, multiple rows with NULL in one of the columns are allowed by default. However many databases view NULL as distinct in this regard and only allow one row with NULL.
  • For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null.

Derby Compatibility Mode

To use the Derby mode, use the database URL jdbc:h2:~/test;MODE=Derby or the SQL statement SET MODE Derby .

  • When using unique indexes, multiple rows with NULL in one of the columns are allowed by default. However many databases view NULL as distinct in this regard and only allow one row with NULL.
  • For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null.

Oracle Compatibility Mode

To use the Oracle mode, use the database URL jdbc:h2:~/test;MODE=Oracle or the SQL statement SET MODE Oracle .

  • When using unique indexes, multiple rows with NULL in one of the columns are allowed by default. However many databases view NULL as distinct in this regard and only allow one row with NULL.
  • For aliased columns, ResultSetMetaData.getColumnName() returns the alias name and getTableName() returns null.

Auto-Reconnect

The auto-reconnect feature causes the JDBC driver to reconnect to the database if the connection is lost. The automatic re-connect only occurs when auto-commit is enabled; if auto-commit is disabled, an exception is thrown.

Re-connecting will open a new session. After an automatic re-connect, variables and local temporary tables definitions (excluding data) are re-created. The contents of the system table INFORMATION_SCHEMA.SESSION_STATE contains all client side state that is re-created.


Automatic Mixed Mode

Multiple processes can access the same database without having to explicitly start the server. To do that, append ;AUTO_SERVER=TRUE to the database URL. In this case, the first connection to the database is made in embedded mode, and additionally a server is started. If the database is already open in another process, the server mode is used.

When using this feature, auto-reconnect is enabled as well.

The application that opens the first connection to the database uses the embedded mode, which is faster than the server mode. Therefore the main application should open the database first if possible. A server is started on a random port. This server allows remote connections, however only to this database. In addition to the user name and password, the client sends the random key that is stored in .lock.db file to the server.


トレースオプションを使用する

アプリケーション内の問題を見つけるために、時々、何のデータベースオペレーションがどこで実行されているかを知るのは良い方法です。このデータベースは次のトレースの特徴を提供します:

  • System.out と (または) ファイルをトレースする
  • トレースレベル OFF、ERROR、INFO と DEBUG をサポート
  • トレースファイルの最大サイズの設定が可能
  • Javaコード生成が可能
  • 手動でファイルを作成することによって、ランタイムでトレースが可能

トレースオプション

トレースオプションを可能にする簡単な方法は、データベースURLにトレースオプションを設定することです。二つの設定があり、ひとつは、System.out (TRACE_LEVEL_SYSTEM_OUT) トレーシングで、もうひとつはファイルトレーシング(TRACE_LEVEL_FILE)です。トレースレベルは、0 が OFF、1 が ERROR (デフォルト)、2 が INFO で 3 が DEBUGです。両方のレベルがDEBUGに設定されたデータベースURLです:

jdbc:h2:~/test;TRACE_LEVEL_FILE=3;TRACE_LEVEL_SYSTEM_OUT=3

トレースレベルは、SQLコマンド SET TRACE_LEVEL_SYSTEM_OUT level (System.out トレーシング) または SET TRACE_LEVEL_FILE level (ファイルトレーシング) を実行することによってランタイムで変更できます。例:

SET TRACE_LEVEL_SYSTEM_OUT 3

トレースファイルの最大サイズを設定

高いトレースレベルを使用する時、トレースファイルは早くサイズが非常に大きくなります。SQLステートメント SET TRACE_MAX_FILE_SIZE maximumFileSizeInMB を実行することによりファイルのサイズを制限することができます。ログファイルが制限を超えたら、ファイルは ".old" にファイル名を変えて、新しいファイルが作成されます。もしもうひとつの .oldファイルが存在する場合は、それは削除されます。デフォルトの設定は16 MBです。例:

SET TRACE_MAX_FILE_SIZE 1

Javaコード生成

トレースレベルをINFOかDEBUGに設定した時、同様にJavaのソースコードが生成されるので、問題はより簡単に再生されます。トレースファイルはこのようなものです:

...
12-20 20:58:09 jdbc[0]:
/**/dbMeta3.getURL();
12-20 20:58:09 jdbc[0]:
/**/dbMeta3.getTables(null, "", null, new String[]{"TABLE", "VIEW"});
...

Javaのソースコードを得るために、 /**/ のない行を取り除く必要があります。 Windowsでの簡単な方法は:

find "**" test.trace.db > Trace.java

その後、コンパイルされる前にTrace.javaファイルを完全にする必要があります。例:

import java.sql.*;
public class Trace { public static void main(String[]a)throws Exception {
Class.forName("org.h2.Driver");
...
}}

また、トレースファイルに載せられていないため、ユーザー名とパスワードが設定されている必要があります。

手動でファイルを作成し、ランタイムでトレースオプションを可能にする

時々、アプリケーション、またはデータベースのURLを変えられない、変えたくない場合があります。このような場合に、ランタイムであっても (データベースの接続が開かれている間) トレースモードを可能にできる方法がまだあります。必要なことは、データベースファイルが保存されているディレクトリに特別なファイルを作るだけです。データベースエンジンは、このファイルが存在する場合に (ステートメントが実行されている間のみ) 4秒ごとにチェックしています。このファイル名は、データベース名 プラス ".trace.db.start" です。この特徴はデータベースが暗号化されている場合は無効になります。

例: データベース名が "test"の場合、 トレーシングを開始するファイルは "test.trace.db.start"です。データベースエンジンは、このファイルを見つけた時、ファイルを削除しようとします。スタートファイルを使用することでトレースが可能になるなら、トレースレベルはデータベースに対して永続的ではなく、トレースはデータベースに接続する以前のレベルに戻されます。しかし、スタートファイルが読み取り専用なら、データベースエンジンはファイルを削除することができず、接続するときはいつもトレースモードになります。


Using Other Logging APIs

By default, this database uses its own native 'trace' facility. This facility is called 'trace' and not 'log' within this database to avoid confusion with the transaction log. Trace messages can be written to both file and System.out. In most cases, this is sufficient, however sometimes it is better to use the same facility as the application, for example Log4j. To do that, this database support SLF4J.

SLF4J is a simple facade for various logging APIs and allows to plug in the desired implementation at deployment time. SLF4J supports implementations such as Logback, Log4j, Jakarta Commons Logging (JCL), JDK 1.4 logging, x4juli, and Simple Log.

To enable SLF4J, set the file trace level to 4 in the database URL:

jdbc:h2:~/test;TRACE_LEVEL_FILE=4

Changing the log mechanism is not possible after the database is open, that means executing the SQL statement SET TRACE_LEVEL_FILE 4 when the database is already open will not have the desired effect. To use SLF4J, all required jar files need to be in the classpath. If it does not work, check in the file <database>.trace.db for error messages.


読み取り専用データベース

データベースファイルが読み取り専用なら、同様にデータベースも読み取り専用です。このデータベースで新しいテーブルを作成したり、データを追加したり変更したりすることはできません。SELECTステートメントのみ許可されています。読み取り専用データベースを作成するには、データベースを終了してログファイルを小さくします。ログファイルを削除してはいけません。そして、オペレーティングシステムを使用してデータベースファイルを読み取り専用にします。これでデータベースを開くと、読み取り専用になっています。アプリケーションが、データベースが読み取り専用であることを判断する方法は二つあります: Connection.isReadOnly() を呼ぶか、SQLステートメント CALL READONLY() を実行します。


Read Only Databases in Zip or Jar File

To create a read-only database in a zip, first create a regular persistent database, and then create a backup. If you are using a database named 'test', an easy way to do that is using the Backup tool or the BACKUP SQL statement:

BACKUP TO 'data.zip'

The database must not have pending changes, that means you need to close all connections to the database, open one single connection, and then execute the statement. Afterwards, you can log out, and directly open the database in the zip file using the following database URL:

jdbc:h2:zip:~/data.zip!/test

Databases in a zip file are read-only. The performance for some queries will be slower than when using a regular database, because random access in zip files is not supported (only streaming). How much this affects the performance depends on the queries and the data. The database is not read in memory; so large databases are supported as well. The same indexes are used than when using a regular database.


バイナリーとテキストストレージフォーマット

このデータベースエンジンは、バイナリーとテキストストレージフォーマットの両方をサポートしています。バイナリーはより高速ですが、テキストストレージフォーマットは同様に役立つ場合があります。例えば、データベースエンジンをデバッグする場合です。データベースがすでに存在するなら、ストレージフォーマットは自動的に推奨されます。新しいデータベースはデフォルトでバイナリーストレージフォーマットで作られます。テキストストレージフォーマットで新しいデータベースを作成するには、データベースURLに、パラメータ STORAGE=TEXT が含まれていなければなりません。例: jdbc:h2:~/test;STORAGE=TEXT


ディスクスペースが少ない状況での正しい取り扱い

データベースは、利用可能なディスクスペースが少なくなっている状況に対処することができます。データベースを開始する時はいつも、"emergency space" ファイルが作られ (サイズは 1 MB)、利用可能なスペースがもうない場合には、ファイルは小さくなります。利用可能なスペースが 128 KB以下になった場合、データベースは特別な読み取り専用モードになり、全ての書き込み操作はもはや許可されません: この時点から全ての書き込み操作は、"No disk space available" を例外に投げます。通常のオペレーションモードに戻るためには、最初にデータベースへの全ての接続を終了し、スペースを空ける必要があります。

早くからディスクスペースの少ない状況を把握するために、データベースイベントリスナーをインストールすることは可能です (ディスクスペースが 1MB のみ利用可能な時)。SQLステートメント SET DATABASE_EVENT_LISTENER を使用します。フォームのURLを使用して、接続時にリスナーを設定することが可能です jdbc:h2:~/test;DATABASE_EVENT_LISTENER='com.acme.DbListener' (クラス名の周りの引用文は必要です)。APIのDatabaseEventListenerもご覧下さい。

破損したデータベースを開く

boot info (始動時に実行されるSQLスクリプト) が破損しているため、データベースを開くことができない場合、データベースイベントリスナーを指定することでデータベースを開くことができます。例外は記録されますが、データベースの開始は続行します。


computed column / ベースインデックスの機能

インデックスの機能は、このデータベースによって直接サポートはされていませんが、computed columnsを使用することによって、簡単にエミュレートすることができます。例えば、カラムのupper-caseバージョンのインデックスが必要なら、原形のカラムのupper-caseバージョンのcomputed columnを作成し、このカラムにインデックスをつけます:

CREATE TABLE ADDRESS(
  ID INT PRIMARY KEY,
  NAME VARCHAR,
  UPPER_NAME VARCHAR AS UPPER(NAME)
);
CREATE INDEX IDX_U_NAME ON ADDRESS(UPPER_NAME);

値は生成されているので、データを挿入する時、カラムのupper-caseバージョンのための値を指定する必要はありません (許可されていません)。 しかし、テーブルを呼ぶ時、このカラムを使用することはできます。:

INSERT INTO ADDRESS(ID, NAME) VALUES(1, 'Miller');
SELECT * FROM ADDRESS WHERE UPPER_NAME='MILLER';

多次元インデックス

効率的な多次元の (空間的) 領域のクエリーを実行するためにツールを提供します。このデータベースは専門的な空間的インデックス (R-Tree またはより小さいもの) をサポートしていません。代わりに、B-Treeインデックスが使われています。それぞれのレコードに対して、多次元のキーは、単数範囲 (スカラー) の値に変換 (位置づけ) されます。この値は、space-filling curve (空間充填曲線) で位置を指定します。

現在、Z-order (N-order または Morton-order とも呼ばれています) が使用されています; Hilbert curveも使用できますが、実装はより複雑です。多次元の値を変換するアルゴリズムは、bit-interleavingと呼ばれています。B-Treeインデックス (通常は computed columnを使用します)を使用することで、スカラーの値はインデックスをつけられます。

最初のカラムにインデックスを使用する上で、メソッドは徹底的なパフォーマンスの改良をもたらすことができます。データと次元の数によりますが、改良は通常、factor 5よりも高いものです。指定された多次元の範囲から、ツールはSQLクエリーを生成します。使用されたメソッドは、データベースに依存しておらず、ツールは簡単に他のデータベースに移植することができます。ツールの使用方法の例は、TestMultiDimension.java で提供されているサンプルコードをご覧下さい。


パスワードを使用する

安全なパスワードを使用する

弱いパスワードは、暗号化やセキュリティプロトコルに取るに足らず、解読されてしまうことを覚えておいて下さい。辞書で見つけられるようなパスワードは使用しないでください。また、数字を付け足してもそのようなパスワードは安全にはなりません。良いパスワードを作る方法は、覚えやすい、文章の最初の文字を使う、大文字と小文字を使う、特別な文字が含まれているものを作る、です。例:

i'sE2rtPiUKtT (もしトリックを知っていれば、このパスワードは覚えやすいものです)

パスワード: Stringの代わりにChar Arraysを使用する

Java Stringは不変のオブジェクトであり、アプリケーションによって安全に壊されることはできません。Stringの作成後、Stringは少なくともガベージコレクションになるまで、コンピューターのメインメモリ内にとどまるでしょう。ガベージコレクションはアプリケーションによって制御されず、ガベージコレクションであっても、データはまだメモリにとどまっているでしょう。パスワードが含まれるメモリの一部をディスクと取り換えることも可能でしょう (十分でないメインメモリも使用可能のため)。

アタッカーはオペレーティングシステムのスワップファイルにアクセスするでしょう。したがって、パスワードを保存するために、Stringの代わりにchar arrayを使用するのは良い方法です。char arrayは使用後クリアにされるので (0で埋められます)、パスワードはスワップファイルに保存されません。

このデータベースは、ユーザーパスワードとファイルパスワードを認証するために、Stringの代わりにchar arrayを使用することをサポートしています。次のコードはこのように使用されます:

Class.forName("org.h2.Driver");
String url = "jdbc:h2:~/simple";
String user = "sam";
char[] password =
{'t','i','a','S','&',E','t','r','p'};
Properties prop = new Properties();
prop.setProperty("user", user);
prop.put("password", password);
Connection conn = null;
try {
    conn = DriverManager.
      getConnection(url, prop);
} finally {
    Arrays.fill(password, 0);
}

このサンプルでは、パスワードはアプリケーションでのハードコードで、もちろん安全ではありません。しかし、Java Swingはchar arrayを使用してパスワードを得る方法をサポートしています (JPasswordField)。

ユーザー名 と (または) パスワードをURLで認証する

ユーザー名を Connection conn = DriverManager. getConnection("jdbc:h2:~/test", "sa", "123"); のように切り離されたパラメータとして認証する代わりに、URLそのもので Connection conn = DriverManager. getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123"); ユーザー名 (と (または) パスワード)を提供することができます。URL内の設定は、切り離されたパラメータとして認証させる設定より優先されます。


ユーザー定義の関数とストアドプロシージャ

組み込み関数に加えて、このデータベースはユーザー定義のJava関数をサポートしています。同様に、このデータベースではJava関数はストアドプロシージャとして使用されています。関数は、使用される前に宣言 (登録) されていなければなりません。static Javaメソッドのみサポートされています; クラスとメソッドの両方が public である必要があります。Javaメソッドの例:

package org.h2.samples;
...
public class Function {
    public static boolean isPrime(int value) {
        return new BigInteger(String.valueOf(value)).isProbablePrime(100);
    }
}

Java関数は、CREATE ALIAS と呼ばれるデータベースに登録されていなければなりません:

CREATE ALIAS IS_PRIME FOR "org.h2.samples.Function.isPrime"

完全なサンプルアプリケーションは src/test/org/h2/samples/Function.java をご覧下さい。

データタイプマッピング関数

"int" のような non-nullable (NULL可能ではない) パラメータを受け入れる関数は、パラメータのうちひとつがNULLであるなら呼ばれないでしょう。このケースでは、NULLの値は結果として使用されます。このケースで関数を呼び出したいのなら、"int" の代わりに "java.lang.Integer" を使用する必要があります。

接続を必要とする関数

もしJava関数の最初のパラメータが java.sql.Connection なら、データベースへの接続は与えられています。返す前にこの接続を閉じる必要はありません。

例外を投げる関数

関数が例外を投げたら、現在のステートメントはロールバックされ、例外はアプリケーションに投げられます。

Result Setを返す関数

関数はresult setを返します。このような関数はCALLステートメントと一緒に呼ばれます:

public static ResultSet query(Connection conn, String sql) throws SQLException {
    return conn.createStatement().executeQuery(sql);
}

CREATE ALIAS QUERY FOR "org.h2.samples.Function.query";
CALL QUERY('SELECT * FROM TEST');

SimpleResultSetを使用する

result setを返す関数は、SimpleResultSetツールを使用して最初からこのresult setを作成することができます:

import org.h2.tools.SimpleResultSet;
...
public static ResultSet simpleResultSet() throws SQLException {
    SimpleResultSet rs = new SimpleResultSet();
    rs.addColumn("ID", Types.INTEGER, 10, 0);
    rs.addColumn("NAME", Types.VARCHAR, 255, 0);
    rs.addRow(new Object[] { new Integer(0), "Hello" });
    rs.addRow(new Object[] { new Integer(1), "World" });
    return rs;
}

CREATE ALIAS SIMPLE FOR "org.h2.samples.Function.simpleResultSet";
CALL SIMPLE();

関数をテーブルとして使用する

result setを返す関数はテーブルのようになれます。しかし、このケースでは関数は少なくとも二回は呼ばれます: 最初はカラム名を集めるために構文解析している間です (コンパイル時に未知のところでパラメータはNULLに設定)。そして、データを取得するためにステートメントを実行している間です (これが結合なら繰り返されます)。関数がカラム一覧を取得するためだけに呼ばれたのなら、関数を認証する接続URLは jdbc:columnlist:connection です。そうでなければ、接続URLは jdbc:default:connection です。

public static ResultSet getMatrix(Integer id) throws SQLException {
    SimpleResultSet rs = new SimpleResultSet();
    rs.addColumn("X", Types.INTEGER, 10, 0);
    rs.addColumn("Y", Types.INTEGER, 10, 0);
    if(id == null) {
        return rs;
    }
    for(int x = 0; x < id.intValue(); x++) {
        for(int y = 0; y < id.intValue(); y++) {
            rs.addRow(new Object[] { new Integer(x), new Integer(y) });
        }
      }
    return rs;
}

CREATE ALIAS MATRIX FOR "org.h2.samples.Function.getMatrix";
SELECT * FROM MATRIX(3) WHERE X>0;

トリガー

このデータベースは、行が更新、挿入、または削除された前後に呼ばれるJavaトリガーをサポートしています。トリガーは複雑な一貫性チェックか、データベース内の関連したデータをアップデートするのに使用されます。マテリアライズドビューをシミュレートするためにトリガーを使用することも可能です。完全なサンプルアプリケーションは src/test/org/h2/samples/TriggerSample.java をご覧下さい。Javaトリガーは、インターフェイス org.h2.api.Trigger を実装しなければなりません:

import org.h2.api.Trigger;
...
public class TriggerSample implements Trigger {
    public void init(String triggerName, String tableName) {
    }
    public void fire(Connection conn,
            Object[] oldRow, Object[] newRow)
            throws SQLException {
    }
}

他のテーブルのクエリーかデータのアップデートに接続を使用することができます。トリガーはその時データベースで定義されている必要があります:

CREATE TRIGGER INV_INS AFTER INSERT ON INVOICE
  FOR EACH ROW CALL "org.h2.samples.TriggerSample"

トリガーはSQL Exceptionを投げることによって、変更を禁止させることができます。


データベースをコンパクトにする

データベースファイルの空のスペースは自動的に再利用されます。インデックスを再構築するもっとも簡単な方法は、データベースが閉じられている間に .index.db ファイルを削除します。しかし、一部状況では (例えば、データベースの多数のデータを削除した後)、データベースのサイズを縮小したい場合があります (データベースをコンパクトにする)。そのためのサンプルです:

public static void compact(String dir, String dbName,
        String user, String password) throws Exception {
    String url = "jdbc:h2:" + dir + "/" + dbName;
    String file = "data/test.sql";
    Script.execute(url, user, password, file);
    DeleteDbFiles.execute(dir, dbName, true);
    RunScript.execute(url, user, password, file, null, false);
}

サンプルアプリケーション org.h2.samples.Compact もご覧下さい。データベースのバックアップを作るのと、スクリプトからデータベースを再構築するのにSCRIPT / RUNSCRIPT コマンドを使用することができます。


キャッシュの設定

データベースは最も頻繁に使われるデータやインデックスページをメインメモリに保存します。キャッシュに使用されるメモリ量を CACHE_SIZE 設定を使用して変更することができます。この設定は、データベース接続URL (jdbc:h2:~/test;CACHE_SIZE=131072) か、ランタイムにSET CACHE_SIZE を使用してサイズを変更できます。

このデータベースは二つのcache page replacement algorithms (キャッシュページ置換アルゴリズム) をサポートしています: LRU (デフォルト) と2Qです。LRUは、キャッシュがいっぱいになったら、頻繁に使用されていないページをキャッシュから削除します。2Qアルゴリズムは少し複雑で、基本的に二つのクエリーが使用されます。2Qアルゴリズムはテーブルスキャンに、より抵抗がありますが、LRUと比較してオーバーヘッドは少し高めです。キャッシュアルゴリズム 2Qを使用するためには、フォームのデータベースURL jdbc:h2:~/test;CACHE_TYPE=TQ を使用します。キャッシュアルゴリズムは、一度データベースが開かれたら変更することはできません。

読んだり書いたりしたページや、現在使用されているキャッシュアルゴリズムの情報を得るためには、SELECT * FROM INFORMATION_SCHEMA.SETTINGS を呼びます。データとインデックスファイルに読み書きしたページ数が書かれています。