Oracle Berkeley DBに関してよくある質問

 

 

Berkeley DBデータベースとはどのようなものですか。 リレーショナル(SQL)データベース表と同じですか。

はい。Berkeley DBデータベースは、概念上、1つのリレーショナル・データベースです。 また、キーと値のペアを、表に含まれる1つのとみなすこともできます。この場合、は、アプリケーションによってキーまたは値内ににエンコードされたデータになります。

マルチプロセスのBerkeley DBアプリケーションを設計する際、監視プロセスを含める必要がありますか。

Berkeley DB Programmer's Reference Guideの次の項に、このトピックに関する詳しい説明が記載されています。これら2つの項をよく読んでください。

アプリケーション情報をデータベースまたはデータベース環境ハンドルと関連付ける方法を教えてください。

C APIを使用する場合、各DBハンドルおよびDB_ENVハンドルには、アプリケーション固有の情報を参照するために使用されるapp_privateフィールドが含まれています。 詳しくは、db_createおよびdb_env_createのドキュメントを参照してください。

C++ APIまたはJava APIで、もっとも簡単にアプリケーション固有のデータとハンドルを関連付ける方法は、DbハンドルおよびDbEnvハンドルのサブクラスを作成する方法です。たとえば、DbのサブクラスとしてMyDbを作成します。 タイプMyDbのオブジェクトでは、引き続きBerkeley DB APIメソッドを使用できるため、任意の追加データまたはメソッドをMyDbクラスに追加できます。 Db引数またはDbEnv引数をとるコールバックAPI(たとえば、Db.set_bt_compare()メソッド)を使用している場合、これらは常に、ユーザーが作成するDbオブジェクトまたはDbEnvオブジェクトとともに呼び出されます。 そのため、常にMyDbオブジェクトを使用する場合は、コールバック関数の最初の引数をMyDb(C++では、(MyDb*))にキャストできます。これで、自分のデータ・メンバーまたはメソッドにアクセスできます。

Berkeley DBのExport Control Classification Number(ECCN)は何番ですか。

Berkeley DBには、オプションで強力な暗号化サポートが含まれています。暗号化ソフトウェアの輸出入や使用、または技術詳細の伝達は世界の一部地域では違法となります。暗号法を含んでいるBerkeley DBのリリースを自国に輸入する、または何らかの方法でそのソース・コードを再配布する場合は、適用される輸出入法規および使用に関する法律に細心の注意を払うことを強く推奨します。 上記の懸念がある場合、暗号化コードの含まれていないNC(非暗号化)バージョンのBerkeley DB製品をダウンロードすることを推奨します。

WindowsでMFCを使用してプロジェクトを作成するとき、あるいはoledb.hを含むコードをコンパイルするとき、コンパイル・エラーが発生します。なぜですか。

Berkeley DBのヘッダー・ファイルdb.hとMicrosoftのヘッダー・ファイルoledb.hには、シンボルDBTYPEが定義されています。このシンボルの使い方をどちらかのヘッダー・ファイルで変更すると、既存のコードが破壊されます。

この問題が発生したときは、まずもっとも簡単な解決方法を試してください。すなわち、どのソース・ファイルでも、この2つのヘッダー・ファイルを同時に使用することがないようにソース・コードを整理します。つまり、Berkeley DBとMicrosoftのOLE DBライブラリの使用を切り分けて、両者がコード内で混在しないようにします。

その後、db.hまたはoledb.hのどちらかを選択して、両者を1つのソース内で同時に使用しないようにします。

それができない場合、つまり、2つのヘッダー・ファイルを同時に使用する必要がある場合は、以下の手順に従って、いずれかの#include行をラップするようにします。

ソース・コード内のoledb.hがインクルードされている行を見つけます。この行は自動的に生成されるstdafx.hインクルード・ファイルに含まれていることもあります。そのヘッダー・ファイルが本当に必要かどうかを判断します。本当に必要な場合は、インクルード行を変更します。変更前には次のようになっているとします。

#include <oledb.h>

これを、以下のように変更します。

/* Work around DBTYPE name conflict with Berkeley DB */
#define DBTYPE MS_DBTYPE
#include <oledb.h>
#undef DBTYPE

変更後に、MicrosoftのDBTYPEを使用する必要がある場合は、MS_DBTYPEという名前で参照します。 Cアプリケーションの場合は、db.hのinclude行を同様にラップします。 ただし、この方法でdb_cxx.hをラップすることはできません。 Berkeley DBに対してC++インタフェースを使用している場合は、oledb.hとdb_cxx.hの混合を避けるか、上述のようにoledb.hのinclude行をラップする必要があります。

lockers、locks、lockオブジェクトを使い果たした場合はどうすれば良いですか。

Berkeley DBの環境では、lockers、locks、およびlockオブジェクトが一定の個数を超えないかどうか監視しています。したがって、これらのリソースを使い切ってしまう可能性が常にあります。割り当てられるlockリソースの上限は、データベース環境の作成時に設定されます。ですから、上限値を変更するには、lockers、locks、またはlockオブジェクトの数を増やして、環境を再構築する必要があります。 詳しくは、Berkeley DB Programmer's Reference GuideのConfiguring locking: sizing the systemの項を参照してください。

Berkeley DBからエラー番号12または22が返されました。これはどういう意味ですか。

アプリケーションのBerkeley DB APIをコールする方法が間違っているか、不十分なリソースでデータベース環境を構成しています。Berkeley DBライブラリは、汎用的なエラーを返す、または抽象的な例外をスローする場合は常に詳細なエラー・メッセージを出力します。Berkeley DBへのアプリケーション・コールが失敗する理由がわからない場合、最初の手順は常に、詳細なエラー・メッセージを確認することです。メッセージを読めばほとんどの場合、問題が明らかになります。 詳しくは、Berkeley DB Programmer's Reference GuideのRun-time error informationの項を参照してください。Berkeley DBでは、エラー・ネームスペースがどのように分割されるのかを理解しておくのも役立ちます。 歴史のあるdbm、ndbm、およびhsearchインタフェースを除き、Berkeley DBではエラーの値を返すためにグローバル変数のerrnoは使用しません。Berkeley DBのすべての関数の戻り値は、以下の3つのカテゴリに分類されます。

  • 戻り値0は、操作が正常終了したことを示します。
  • 0より大きい戻り値は、システム・エラーが発生したことを示します。システムから戻されるerrno値は、関数から戻される値です。たとえば、Berkeley DBの関数がメモリを割り当てられない場合、その関数からの戻り値はENOMEMとなります。
  • 0未満の戻り値は、システム障害は発生していないが、無条件の正常終了でもない状態を示します。たとえば、データベースからキーとデータのペアを取得するルーチンは、データベースに該当するキーとデータのペアがない場合、DB_NOTFOUNDを返します。データベースにキーとデータのペアが存在する場合は、0が返されます。

Berkeley DBの関数から戻される値はすべて、errnoで想定される値と競合するのを避けるために0未満になっています。具体的には、Berkeley DBでは、可能なエラーの値として、-30,800から-30,999が予約されています。アプリケーションの関数をBerkeley DBの関数からコールできる、ごく一部のBerkeley DBインタフェースでは、障害時にアプリケーション固有の戻り値が返されます。そのような障害の戻り値は、Berkeley DBインタフェースを最初にコールした関数に返されます。エラーの原因が不明確になるのを避けるためには、Berkeley DBのエラー・ネームスペースから離れたエラーの値を使用する必要があります。 また、Berkeley DBがdb_strerror関数から返すエラー番号に関連付けられているメッセージ文字列はいつでも取得できます。 db_strerror関数は、ANSI C X3.159-1989(ANSI C)のstrerror(3)関数のスーパーセットです。 エラー番号が0以上の場合は、システム関数strerror(3)から戻される文字列が返されます。 エラー番号が0より小さい場合は、対応するBerkeley DBのライブラリ・エラーに適したエラー文字列が返されます。

ディスク領域の不足によってデータベースが破損する可能性がありますか。

Berkeley DBはディスク領域不足のエラーが発生しても稼働を続けることができますが、それには、アプリケーションでの処理をトランザクションで保護する必要があります。アプリケーションは、更新操作をトランザクション内で実行していない場合、ディスク領域不足エラーから回復できません。そのため、ディスク領域が不足すると、データベースが破損する可能性があります。

1つの物理ファイルに複数のデータベースを格納すると、データベースが破損する可能性がありますか。

データベースの破損とみなされる問題は、通常、2つのデータベース・ハンドルで基盤となるデータベース環境が共有されていないことに起因します。 詳しくは、Berkeley DB Programmer's Reference GuideのOpening multiple databases in a single fileの項を参照してください。

アプリケーションの終了時に多数のディスク・アクティビティが発生するのはなぜですか。

Berkeley DBアプリケーションがデータベース・ハンドルを破棄するためにデータベース・ハンドルのクローズ・メソッドをコールする場合、キャッシュ内のダーティ・ページがバッキング・データベース・ファイルにデフォルトで書き込まれます。 この動作を変更するには、Db.closeに対してDB_NOSYNCフラグを指定します(Java APIを使用している場合は、Database.closeメソッドに対してnoSyncフラグを指定)。このフラグを設定すると、ハンドルのクローズ・メソッドはキャッシュ内のダーティ・ページを無視します。多くのアプリケーションでは、データベース・ハンドルのクローズ・メソッドがコールされたときに、キャッシュのダーティ・ページをフラッシュする必要はありません。永続性のためにトランザクションまたはレプリケーションを使用するアプリケーションでは、トランザクションのメカニズムによりデータの損失は発生しないので、ダーティ・ページをフラッシュする必要はありません。また、データベース環境が削除されそうにならない限り、キャッシュからダーティ・ページをフラッシュする必要はありません。プロセスは、キャッシュに保持されているダーティ・ページをフラッシュすることなく、データベース環境に加わり、離れることができます。データベース環境が再びアクセスされることがない場合のみ、ダーティ・ページをバッキング・ファイルにフラッシュする必要があります。

unable to initialize mutex: Function not implementedエラーが発生する原因を教えてください。

Berkeley DBアプリケーションでこのエラーが発生するもっとも一般的な理由は、システムがBerkeley DBによって構成された基礎となるミューテックスをコールし、それがシステムで使用できないためにENOSYSを返すからです(これは、Function not implementedメッセージと関連付けられているシステム・エラーです)。一般的にこのエラーは、Berkeley DBライブラリ・ビルドがPOSIXミューテックスを使用するように構成されており、POSIXミューテックスがこのシステムで使用できない場合、またはライブラリがPOSIXミューテックスを使用可能な別のシステムで構成された後で、POSIXミューテックスを使用できないシステムに物理的に移動された場合に発生します。 このエラーは、Linuxシステムで発生することがあります。これは、一部のLinuxシステムでは、POSIXミューテックスのサポートがCライブラリ構成にあり、オペレーティング・システムにはないため、または、システムにあるPOSIXミューテックスのサポートがイントラプロセス・ミューテックスのためだけのものであり、インタープロセス・ミューテックスのものではないためです。 このエラーを回避するには、次のように--with-mutex=MUTEX構成フラグを使用して、Berkeley DBが使用するミューテックス実装を明示的に指定します。

    --with-mutex=MUTEX
        To force Berkeley DB to use a specific mutex implementation,
        configure with --with-mutex=MUTEX, where MUTEX is the mutex
        implementation you want. For example,
    --with-mutex=x86/gcc-assembly will configure Berkeley DB to use
        the x86 GNU gcc compiler based test-and-set assembly mutexes.
        This is rarely necessary and should be done only when the
        default configuration selects the wrong mutex implementation. A
        list of available mutex implementations can be found in the
        distribution file dist/aclocal/mutex.ac


APIを正しく使用しているように見える場合でも、Berkeley DBの操作によってEINVALなどのエラーが返されるのはなぜですか。

このような問題は通常、メモリを初期化していない場合に発生します。 Berkeley DB APIを呼び出す前にDBTオブジェクトの初期化を行う責任は、アプリケーション側にあります。 DBTを使用する前に、DBTのすべての要素を0に初期化してから、使用する要素を明示的に設定する必要があります。 また、この現象が生じる別の理由として、アプリケーションがDB->openメソッドまたはDB_ENV->openメソッドにDB_THREADフラグを指定せずに、フリー・スレッド方式でBerkeley DBハンドルを使用している場合があります。 複数のスレッド間で1つのハンドルを共有する場合は常に、このハンドルのオープン時にDB_THREADを指定する必要があります。この現象が生じるもう1つの理由としては、アプリケーションがロックを取得せずにデータベースに同時にアクセスしている場合が考えられます。Berkeley DB Data Store製品にはロック機能はありません。そのため、アプリケーションが独自にデータベースへのアクセスをシリアライズして、破損を回避する必要があります。Berkeley DB Concurrent Data Store製品およびBerkeley DB Transactional Data Store製品にはデータベースのロック機能がありますが、ロック機能はユーザーが構成する必要があります。

Berkeley DBデータベースは、整数サイズやバイト・オーダーが異なるアーキテクチャ間で移植可能ですか。

はい、可能です。 32ビット・マシンと64ビット・マシン間、およびリトル・エンディアン・マシンとビッグ・エンディアン・マシン間でデータベースを移行できます。 詳しくは、Berkeley DB Programmer's Reference GuideのSelecting a byte orderの項を参照してください。

データベース環境のチェックポイント機能により、データベース・アクセスが中断またはブロックされたり、パフォーマンスが低下したりすることがありますか。

チェックポイントによって、Berkeley DBデータベース環境へのアクセスがブロックされることはありません。制御スレッドは、チェックポイント中もデータベースの読取りおよび書込みを継続できます。ただし、チェックポイントによって大量のI/Oが発生する可能性がある場合、ほかの制御スレッドの操作が遅くなり、アクセスがブロックされているように感じることがあります。 DB_ENV->memp_trickleメソッドを使用すると、チェックポイントで実行する必要があるI/Oを分散できます(DB_ENV->memp_trickleメソッドにより、指定した割合のページがキャッシュ内でクリーンな状態で保持されます)。 また、DB_ENV->memp_set_max_writeメソッドを使用して、DBライブラリによってスケジュールされる順次書込み操作の数を制限することもできます。 DB_ENV->memp_set_max_writeメソッドは、データベース・キャッシュをフラッシュするすべてのメソッド(チェックポイントやDB->syncなどのその他のメソッド)に作用します。

LSN values are past the end of the logというメッセージは何を意味していますか。

LSNはlog sequence number(ログ順序番号)の略語です。 このメッセージが表示される場合、transactional database environment cannot be recoveredというメッセージも表示される場合があります。 ログ・ファイルにはトランザクションに関する情報が含まれています。このメッセージが表示される場合、アプリケーションまたはその他のプロセスやシステムがデータベースのログ順序番号(LSN)を正しくリセットせずに、ログ・ファイルの一部(または全部)を削除している可能性があります。 ログ・ファイルは、db_archiveユーティリティまたはDB_ENV->log_archiveメソッドで明示的に許可されている場合を除き、絶対に削除しないでください。それらのインタフェースで、すべての既存ログ・ファイルの削除が許可されることはありません。 また、アプリケーションがあるトランザクション環境でデータベース・ファイルを作成した後で、そのファイルを別のトランザクション環境に移動している可能性があります。バルク・データベース・ロードを行う場合などに、データベースを非トランザクション環境で作成した後で、トランザクション環境に移動することは可能ですが、一度トランザクション環境で使用されたデータベースは、まずデータベースのログ順序番号をリセットしてからでないと、別の環境に移動できません。 詳しくは、DB_ENV->lsn_resetメソッドのドキュメントを参照してください。

トランザクション・アプリケーションで異常に多数のデッドロックが発生するのはなぜですか。

このような動作を説明する理由として、次のような一般的な理由が考えられます。

  • アプリケーションが一貫性のない順番でデータベース・オブジェクトを取得している可能性があります。制御スレッドが常に同じ順番でオブジェクトを取得するようにすると、デッドロックの頻度が減少します。
  • データを読み取り、変更してから書き込む操作を頻繁に行っている場合、無意識のうちに大量のデッドロックを引き起こしていることになります。 {{DB->get()}}}コールにはDB_RMWフラグを指定するようにしてください。
  • さらに、分離レベルを削減することで、アプリケーションが遭遇するデッドロックの数を大幅に減らせます。 詳しくは、Berkeley DB Programmer's Reference GuideのIsolationの項とDegrees of isolationの項を参照してください。

Unable to allocate memory for transaction detailというメッセージは何を意味していますか。

このエラーは、Berkeley DB用に構成されたアクティブなトランザクションの最大数に達したという意味です。より多くのアクティブなトランザクションをサポートするようにBerkeley DB環境を構成する必要があります。データベース環境でトランザクションに使用可能なすべてのメモリが使用中の場合、トランザクションを実行するためのコールは、いくつかのアクティブなトランザクションが完了しない間は失敗します。デフォルトでは、データベース環境は最低20のアクティブなトランザクションをサポートするように構成されます。 詳しくは、Berkeley DB Programmer's Reference GuideのConfiguring transactionsの項を参照してください。

DB_AUTO_COMMITフラグをデータベース・カーソルとともに使用する方法を教えてください。

DB_AUTO_COMMITフラグは、カーソルには適用されません。カーソル操作用のトランザクションが必要な場合は、明示的なトランザクションを作成して使用する必要があります。

Berkeley DBでは、NFS、SAN、またはその他のリモート・ファイル・システム、共有ファイル・システム、ネットワーク・ファイル・システムをデータベースおよびデータベース環境に使用できますか。

Berkeley DBは、SAN(およびその他の既知のファイル・システム・タイプ)とともに十分に機能しますが、複数のマシンから任意のファイル・システムにアクセスを試みる場合、そのファイル・システムを共有のリモート・ファイル・システムとして扱っていることになり、Berkeley DBで問題が生じる原因となります。 詳しくは、Berkeley DB Programmer's Reference GuideのRemote filesystemsの項を参照してください。共有ファイル・システム、リモート・ファイル・システム、ミューテックス、およびキャッシュの一貫性に関しては次の2つの問題があります。

ミューテックスの場合:リモート・ファイルのプロセス・メモリへのマッピングを許可するリモート・ファイル・システムの場合、リモート・ファイル・システム経由でアクセスされるデータベース環境のディレクトリは、複数のクライアント(つまり、複数のコンピュータ)から同時に使用できません。商用のリモート・ファイル・システムで、リモートマウント・ファイルに対して、一貫性のある分散共有メモリをサポートしているものはありません。その結果、各マシンにはこれらの共有領域ファイルの異なるバージョンが表示されることになり、定まらない動作をすることになります。たとえば、マシンAがリモート・ファイル・システムのデータベース環境をオープンし、マシンBも同様にオープンした後、マシンAがそのリモート・ファイル・システムにバックアップされているミューテックスを取得した場合、そのミューテックスはマシンBを正しくシリアライズできません。これは、両方のマシンが1つのデータ構造を同時に変更している可能性があり、その結果、想像できるあらゆる悪い現象がデータベースに起こりうるということです。

キャッシュの場合:データベース、ログ・ファイル、および一時ファイルは、リモート・ファイル・システムで標準のPOSIXファイル・システム・セマンティクスが完全にサポートされている限り、リモート・ファイル・システムに置くことができます(これが原因で、アプリケーションによるパフォーマンスの低下が生じることがあります)。さらに、リモート・ファイル・システムの読取り専用データベースは、複数のシステムから同時にアクセスできます。ただし、リモート・ファイル・システムの変更可能なデータベースに複数のシステムから同時にアクセスするのは困難(または不可能)です。この理由は、Berkeley DBライブラリが変更されたデータベース・ページをキャッシュし、それらの変更されたページがバッキング・ファイルに書き込まれる場合、すべてがアプリケーションの制御下で行われるわけではないからです。2つのシステムがデータベース・ページをリモート・ファイル・システムに同時に書き込む場合、結果としてデータベースが破損します。1つのシステムがデータベース・ページをリモート・ファイル・システムに書き戻し、同時に別のシステムがページを読み取る場合、結果としてリーダーにコア・ダンプが出力されます。たとえば、マシンAがデータベースのページ5を読み取り(ページ5はページ6を参照)、マシンBがデータベースのページ6に書き込んでから、マシンAがデータベースのページ6を読み取る場合、マシンAには一貫性のないページ5と6が存在することになります。この結果、正しくないまたは一貫性のないデータがアプリケーションに戻され、さらにはコア・ダンプに出力されることになります。このシナリオでは、コア・ダンプおよび一貫性のないデータはリーダーにのみ限定して出力されるため、アプリケーションの中にはそれを受け入れるものもあります。もちろん、Berkeley DB以外のデータベースへのアクセスをシリアライズすることは可能ですが、システム全体のパフォーマンスに大幅な影響を与えることになります。そのため、Berkeley DBは、ネットワーク・ファイル・システムまたはSANのいずれかで使用可能な共有ディスク上のデータベース環境に対する複数システムの同時アクセスを完全にサポートするようには設計されていません。

Berkeley DBでは、データをRAWディスクのパーティションに格納できますか。

Berkeley DBは、RAWディスクのパーティションを使用するようには設計されていません。理由は以下のとおりです。

  • 1つ目は、RAWディスクのパーティションを使用するには、専用のアーカイブ、チューニング、およびその他のデータベース管理ツールが必要になる点です。これは、物理データベースや他のファイルにアクセスするためのツールは簡単に作成できないためです。Berkeley DBの設計では、データベース管理に既存のツールを使用することは許可されています(たとえば、ホット・バックアップのための、POSIX cp、tar、またはpaxユーティリティの使用)。その結果、ローカル環境への緊密な統合を実現しています。これは、Berkeley DBのライセンスを行っているサード・パーティのソフトウェア・ベンダーにとっても利点となります。ベンダーは、非標準のアーカイブ・プロシージャまたはツールが必要となることや、同様のものを作成して顧客に提供することを望まないからです。別の理由は、RAWパーティションを拡張するのは困難または不可能であるため、データベースのインストール・サイズを変更するのが非常に難しくなる点です。Berkeley DBと同様に、ファイル・システムを使用する場合、別のパーティションまたはディスクをマウントするだけで済みます(Berkeley DBデータベースのアプリケーションは、多くのデータベース製品とは異なり、使用可能なディスク領域がない場合でも稼働し続けることができます。これは、他のアプリケーションがディスク領域不足でもBerkeley DBアプリケーションを実行できるため、ディスク領域不足に対する回復力をBerkeley DBに備える必要があったためです)。
  • 2つ目は、RAWパーティションはあまりパフォーマンスの向上に貢献していないという点です。少なくとも現代的なオペレーティング・システムにおいてはあまり影響がありません。事前書込みロギング・データベース・システムにおけるトランザクションのパフォーマンスは、通常、ログ・ファイルの書込みによって制限されます。ログ・ファイルは順番に書き込まれ、ファイルを順番に書き込むことで、ファイル・システムのオーバーヘッドが最小限に抑えられます。操作の待機時間の観点から、Berkeley DBは、キャッシュで読込みまたは書込みができない場合のみファイル・システムにアクセスします。確かに、ワーキング・セットが使用可能なキャッシュに収まらないデータセットも存在しますが、多くはありません。つまり、Berkeley DBをRAWパーティションに移植しても、ワーキング・セットがキャッシュに収まっているアプリケーションのパフォーマンスは向上しません。システムに数百GBのキャッシュを設置できれば、かなり大きなワーキング・セットを処理できます。
  • 3つ目は、RAWパーティションのファイルに名前を付けたり、ファイルにブロックを割り当てたり、ファイルを拡張したりするには大量の追加コードが必要になる点です。ファイル・システムに非常によく似たレイヤーを作成する必要があり、Berkeley DBのフットプリントを大幅に増やすことになります。また、コードは継続的な移植やパフォーマンスのチューニングを必要とします。Berkeley DB が独自のファイル・システムに実装されている場合、新しいドライバの追加、ディスク・パフォーマンスの最適化作業に時間をかける必要があり、それらは、当社が専門とする分野ではなく、付加価値を提供できる分野でもありません。既存のアーキテクチャの場合、顧客はBerkeley DBを新しいハードウェアで稼働させられるかどうかを心配する必要はありません。稼働するとわかっているのです。さらに、Berkeley DBは、基礎となるファイル・システムをチューニングする、または新しいファイル・システムを新しい種類のディスク(たとえば、ソリッドステート・ディスク、NVRAMディスク、または新しいRAIDデバイス)に対して展開する場合に、自動的により良いパフォーマンスを実現します。

いくつか理由を述べましたが、RAWパーティションへの移植に対する強力な1つの反対理由は、ダブル・バッファリング(Berkeley DBデータベース・ページのコピーが、Berkeley DBキャッシュとオペレーティング・システムのバッファ・キャッシュの両方に保持されている状態)を回避することにあります。現代のオペレーティング・システムでは、Berkeley DBキャッシュとの間で直接コピーを出し入れするようにI/Oを構成できるため、OSバッファ・キャッシュとダブル・バッファリングを回避できます。RAWパーティションにデータベースを作成するには、Berkeley DBに大幅に変更を加える必要はありません。基礎となるopen、read、write、およびlseekインタフェースのコールをRAWパーティションで機能するように置き換えるだけです。ただし、Berkeley DBがその環境で完全に機能するには、データベース環境の一般的な管理機能が現状どおりスムーズに機能するための多くの作業が必要になります。なお、サード・パーティの研究者たちが、Berkeley DBでこの実験を行っています。彼らの研究内容はいかなる種類のものであれ入手できませんが、プルーフ・ポイントとしての役目を果たしています。

Bツリー・データベースのキーに整数を使用している場合でも、page-fillファクタが非常に低くなるのはなぜですか。

これは通常、x86などのリトル・エンディアン・アーキテクチャで整数キーを使用しているために生じます。 Bツリーのキーをソートするために使用されるBerkeley DBのデフォルト・キー比較関数のコードは、ユーザーが整数とみなしているDBT内のデータをバイト文字列として扱います。 このため、文字列として比較されたリトル・エンディアン整数は正しくソートされません。たとえば、数値254から257を例にすると、リトル・エンディアン・システムでのバイト・パターンは次のようになります。

254     fe 0 0 0
255     ff 0 0 0
256      0 1 0 0
257      1 1 0 0

これらを文字列として扱う場合、次のようにうまくソートされません。

256
257
254
255

ビッグ・エンディアン・システムでは、それぞれのバイト・パターンは次のようになります。

254     0 0 0 fe
255     0 0 0 ff
256     0 0 1 1
257     0 0 1 1

このため、文字列として比較された場合でも適切にソートされます。これは、ビッグ・エンディアン・システムのキーとして確実に増加する整数を使用する場合、Berkeley DBはうまく動作し、コンパクト・ツリーを取得できますが、リトル・エンディアン・システムのBerkeley DBでは生成されるコンパクト・ツリーは少なくなります。 この問題を回避するには、キーをフラット・テキスト表現またはビッグ・エンディアン表現に変換するか、DB->set_bt_compareメソッドを使用して独自のBツリー比較関数を提供する必要があります。 この問題とパック整数の実装に関して、詳しくは Berkeley DB Java Editionに関するOTNフォーラムを参照してください。

SQL APIに固有のFAQ

Berkeley DBはキーと値のペアを使用したデータベースであると理解しています。SQL APIについて教えてください。

Berkeley DBのSQL APIは、Berkeley DBのストレージ・エンジン上に階層化されたSQLiteの上半分にあたるSQL処理部分です。 このようにBerkeley DBとSQLiteを組み合わせることで、dbsqlと呼ばれるSQLコマンドライン・ユーティリティ(sqlite3コマンドライン・ユーティリティと同等の機能を持つ)、サード・パーティ・ライブラリ(JDBCとODBCを含む)、およびSQLiteバージョン3のC/C++ APIが提供されます。 この機能を有効化するには、Berkeley DBパッケージを使用してライブラリおよびツールを構築する前に、configureスクリプトに対して--enable-sql引数を渡します。

Berkeley DBのSQLインタフェースを使用する利点について教えてください。

次の利点をはじめとする、多数の利点があります。

  • Berkeley DBストレージ・エンジンの堅牢性と信頼性が提供されます。
  • きめ細かいロック機能を使用してSQLiteの同時実行性を改善することで、マルチスレッド・アプリケーションやマルチプロセス・アプリケーションのスループットが大幅に向上します。
  • SQLiteバージョン3のインタフェースが維持されているため、SQLiteアプリケーションのドロップイン置換品として使用できます。
  • 結果として生成される製品には、次のようなSQLiteの魅力的な特長が数多く維持されます。
    • 小さなフットプリント(約1MB)
    • 低いオーバーヘッド - 組込みアプリケーションに最適
    • データベース・ファイルの容易な管理
    • SQLiteに対して現在使用できるツールとの互換性

Berkeley DBストレージ・エンジンのおもな利点について教えてください。

次の利点をはじめとする、多数の利点があります。

  • 何百万もの配置で実証された完全なACID準拠
  • ローカルのインプロセス・データ・ストレージ
  • 同時実行性の高いシステムに対する詳細で構成可能なロック機能
  • 柔軟で構成可能なデッドロック検出機能
  • ホットおよびコールド・バックアップ、ログ・ファイルのアーカイブ、全データベース・ダンプ
  • テラバイトのデータ、数十億のレコードまで拡張可能

一般的なアプリケーション・シナリオについて教えてください。

  • 待機時間が短く、同時実行性の高いRDBMS
  • 組込みデバイス、携帯機器、アプリケーション・ソフトウェア
  • ビデオ、音楽、データの大容量ストレージ向けWebサイト・エンジン
  • エンタープライズRDBMSの代替機能
  • アプリケーション・ファイル形式
  • コマンドラインのデータセット分析ツール
  • 内部または一時のインメモリ・データベース
  • セキュアなオンライン更新/同期システム
  • 非定型ディスク・ファイルの代替機能
  • SQLiteアプリケーションの改善

SQLiteと互換性のあるAPIおよびコマンドライン・ツールを構築するには、どのようにBerkeley DBを構成すれば良いですか。

Berkeley DBのソース・コードをビルド向けに設定する場合、考慮すべきオプションが多数あります。 この設定は、distディレクトリ内のconfigureスクリプトを使用して行います。 UNIX系システムを使用している場合、次のコマンドを実行するとオプションが表示されます。

$ cd db
$ cd build_unix
$ ../dist/configure --help

出力は次のようになります。

  --enable-sql            Build the SQL API.
  --enable-sql_compat     Build a drop-in replacement sqlite3 library.
  --enable-jdbc           Build BDB SQL JDBC library.
  --enable-amalgamation   Build a SQL amalgamation instead of building files
                          separately.

したがって、ドロップイン置換品を構築するには、次のコマンドを実行します。

$ ../dist/configure --enable-sql --enable-sql_compat

SQLiteに関する詳しい情報はどこから入手できますか。

はじめに、Berkeley DBのSQL APIは本質的にSQLiteと等しいことを思い出してください。 実際には、この製品と異なる点が多くありますが( http://www.oracle.com/technetwork/database/berkeleydb/bdb-sqlite-comparison-wp-176431.pdfを参照)、最初にSQLite( http://sqlite.org)について理解し、使用してから、Berkeley DBのSQL APIの利点を確認することを推奨します。 また、Berkeley DBのSQLインタフェースを使用し始める際に役立つチュートリアルが多数提供されています。 SQLライブラリとコマンドライン・ツールdbsqlを生成するには、configureスクリプトに--enable-sqlを渡してビルドを実行する必要があります。 ドロップイン置換品を構築しない場合、チュートリアルでsqlite3コマンドライン・ツールの実行が推奨されているケースでは、代わりにBerkeley DBのdbsqlツールを実行してください。

Berkeley DB SQLインタフェースがサポートしているオペレーティング・システムとプラットフォームについて教えてください。

ほとんどのプラットフォームがサポートされていますが、 開発者によるテストが実施されているプラットフォームは次のとおりです。

  • Linux:Oracle Enterprise Linux、RedHat、CentOS、Ubuntuなど
  • Windows 7、Windows XP、Windows Vista
  • Solaris
  • Mac OS/X
  • Apple iOS、Android 2.x
  • Cygwin

POSIXをサポートしているシステムでは、通常、Berkeley DBが動作します。 Berkeley DBは使用するオペレーティング・システム・コールを最小限に抑えるよう設計されているため、移植性に優れています。

UNIX系システムでのビルド方法について教えてください。

通常どおりにBerkeley DB構成ユーティリティを実行し、--enable-sqlフラグを追加します。次に例を挙げます。

db-5.0.XX.tar.gzをダウンロード
$ tar xzvf db-5.0.XX.tar.gz
$ cd db-5.0.XX/build_unix
$ ../dist/configure --enable-sql
$ make

実行が完了すると、libdb_sql-5.0.laというライブラリとdbsqlというコマンドライン・ツールが生成されます。このツールを使用すると、次のようにSQLデータベースを作成し、操作できます。

$ dbsql test.db
Berkeley DB SQL interface version 11.2.5.1.XX
Enter .help for instructions
Enter SQL statements terminated with a ;
dbsql> create table t(a integer, b string);
dbsql> insert into t values (1, 'one');
dbsql> insert into t values (2, 'two');
dbsql> select * from t;
1|one
2|two

SQLiteのドロップイン置換品をビルドすることはできますか。

はい、できます。Berkeley DBの構成スクリプトに--enable-sql_compatフラグを追加してください。 こうすることで、libsqlite3.laという追加ライブラリとsqlite3という追加バイナリが作成され、SQLiteと同じインタフェースが提供されます。

Visual Studioを使用したビルド方法について教えてください。

Berkeley DBソリューションをVisual Studioで開き、db_sql_shellプロジェクトをビルドします。 これにより、Win32/{Debug|Release}/ディレクトリ内にdbsql.exeというバイナリが生成されます。

ビルド・オプションのリストはありますか。

Berkeley DBのSQL APIは、SQLite固有のコンパイル時フラグに加えて、次のオプションを使用して調整できます。

  • BDBSQL_LOG_REGIONMAX
  • BDBSQL_MAX_LOCKERS
  • BDBSQL_MAX_LOCKS
  • BDBSQL_MAX_LOCK_OBJECTS
  • BDBSQL_MUTEX_MAX
  • BDBSQL_OMIT_LEAKCHECK
  • BDBSQL_OMIT_LOG_REMOVE
  • BDBSQL_OMIT_SHARING
  • BDBSQL_SINGLE_THREAD
  • SQLITE_DEFAULT_CACHE_SIZE
  • SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
  • SQLITE_DEFAULT_PAGE_SIZE

この製品に実装されているSQLのバージョンについて教えてください。

一部の例外を除いて、SQL92が使用されています。

SQLiteのデータ型がこちらに記載されています。これらによる重要な影響とBerkeley DBの統合への影響について教えてください。

SQLデータ型に関して、Berkeley DBのSQL APIとSQLite APIで異なる点はありません。 データ型を処理するコードは、Berkeley DBとSQLiteで一致しています。

ドキュメントによると、SQLiteは静的な型システムではなく動的な型システムを使用していますが、下位互換性を提供しています。 RDBMSユーザーの観点から見た場合、これによる問題が発生しますか。

はじめに、データ型に関するSQLiteドキュメントをよく読んでください。 静的に型付けされたデータベースへのアクセスに使用されるSQLは、Berkeley DBと互換性があります。

Berkeley DBは動的SQLをサポートしていますか。

はい、しています。 必要に応じて、実行時にアプリケーションからSQL文を生成し、実行できます。

Berkeley DBはプリペアド・ステートメントをサポートしていますか。

はい。SQLiteはC/C++ APIを介してプリペアド・ステートメントをサポートしています。

Berkeley DBはPL/SQLをサポートしていますか。

SQLiteでPL/SQLに代わる手段として使用されているのは、ネイティブC/C++インタフェースです。 SQLiteではよくあることですが、サード・パーティのPL/SQLサポートが提供されているため、これを代替策としてアプリケーションで使用できる場合があります。

Berkeley DBはSQL文内での条件句をサポートしていますか。

はい、条件文は完全にサポートされています。

Berkeley DBはSQLからカーソルへの直接アクセスをサポートしていますか。

いいえ、サポートしていません。ただし、カーソル・セマンティクスはC/C++ APIを介して使用できます。 このサポートは、SQLiteの prepare/step API によって提供されています。

スレッド・セーフティに関して教えてください。sqlite3のDBハンドルはスレッド間で共有できますか。

Berkeley DBライブラリはスレッド・セーフであり、SQL APIはTDS(Transactional Data Store)を使用しています。開発者はあらゆる種類のスレッド(Berkeley DBはスレッドに依存しません)やマルチプロセスを使用し、データベースに対して自由に同時アクセスできます。 ロック、シリアライズ、およびその他の問題は、Berkeley DBによって管理されます。 SQLiteのスレッド・セーフティについても参照してください。

自動コミットはサポートされていますか。

はい、Berkeley DBは独自のトランザクション内で各コマンドを自動的に実行します。コマンドが失敗しない限り、その変更は自動的にコミットされます。 この操作モード(暗黙的トランザクション)は自動コミット・モードと呼ばれています。 明示的トランザクションを使用すると、システム効率が向上する場合があります。

Berkeley DBで使用できるツールについて教えてください。

SQLiteで使用できるツールのほとんどは、Berkeley DBアプリケーションに対しても使用できます。 一部のツールは SQLite Wiki に記載されています。また、Berkeley DBを使用して作成されたデータベースでは、Berkeley DBのユーティリティを使用できます。 SQLインタフェースでBerkeley DBユーティリティを使用する方法について、詳しくはBerkeley DB SQL APIドキュメント第4章を参照してください。

Berkeley DBインタフェースで使用できるコマンドライン・ツールはありますか。

はい。dbsqlというコマンドライン・ツールが提供されており、コマンドラインからSQLインタフェースを使用できます。 Berkeley DBに--enable-sql_compatフラグが設定されている場合は、sqlite3と呼ばれる、同じ機能を持つ別のコマンドライン・ツールが構築されます。

Berkeley DBにはインポート/エクスポート・ツールがありますか。

はい。組込みの.dumpコマンドで生成されるSQLを実行すると、データベースを再作成できます。

表の作成ツールはありますか。

SQLiteのデータベース管理ツールは数多く提供されています。 SQLiteで使用できるツールのリスト から、要件に合ったものを見つけてください。 SQLiteコマンドラインのSQLインタープリタを使用して表を作成することもできます。このコマンドラインはスクリプトから使用できます。

整合性チェック・ツールはありますか。

はい、整合性チェック・ツールは組み込まれています。このチェック機能にアクセスするには、PRAGMA integrity_checkコマンドを使用します。 詳しくは、pragmaページを参照してください。

サポートされているキャラクタ・セットについて教えてください。

http://www.sqlite.org/datatype3.htmlページに記載された次の文章が参考になります。TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16-LE).

Shift-JIS(SJIS、絵文字)キャラクタ・セットはサポートされていますか。

S-JISを直接格納することもできますが、SQLiteがキャラクタ・セットを解釈できるようにするためのAPIを実装する必要があります。 このため、UTF-8エンコーディングの使用を推奨します。 UTF-8に変換せずに直接Shift-JISを格納する方法も、実現可能に思われます。

サポートされているデータ型について教えてください。

SQLiteのデータ型ドキュメントを参照してください。

それぞれのデータ型に対してSQL文で使用できる検索の種類について教えてください。

SQLiteサイト内のデータ型および言語表現ドキュメントを参照してください。 すべての列タイプにおいて、全文検索、部分一致(LIKEGLOB)、およびカスタムの正規表現がサポートされています。

デフォルト・ソートは文字コードに基づいて実行されます。 文字コード以外でソートする方法はありますか。

はい、あります。 照合順序に関するドキュメントを参照してください。

それぞれのデータ型に対する制約について教えてください。

制約はSQLiteコード内に実装されているため、SQLiteの制約と同じ制約が適用されます。 integer primary keyを除いて、通常、主キーにはUNIQUE制約が適用されます。 一意キー制約はサポートされていますが、 現在、外部キー制約はサポートされていません(文は解析されますが、適用されません)。

TEXT列でのNULL値はサポートされていますか。

NULL値はサポートされており、表に含まれるその他すべての項目(その他のNULL値を含む)よりも先にソートされます。 したがって、NULL値をとるVARCHARフィールド間に明確な順序はありません。

256KBのCSVをBerkeley DB表に格納した場合、どのくらいの領域がデータベースによって使用されますか。

これはページ・サイズ、キー・サイズ(カンマで区切られた行に含まれる値がキーになるかどうか)、page-fillファクタ、および最小限のメタデータ・オーバーヘッドによって異なります。 データと圧縮アルゴリズムによって異なりますが、圧縮が使用されている場合は256KiBより小さくなる可能性があります。 キーの索引付けオーバーヘッドやページごとに数バイトのオーバーヘッドが発生するため、Berkeley DBが使用する領域は256KiB以上になります。 索引オーバーヘッドはキー・サイズによって異なるため見積りは困難です。 たとえば、キーが小さい場合は索引オーバーヘッドも小さくなります。 あらゆるデータベースで、索引付けやページ・ヘッダーなどにいくらかのオーバーヘッドが発生します。

トランザクションのネストはサポートされていますか。

BEGIN...COMMITを使用して作成されたトランザクションは、ネストしません。 トランザクションのネストには、SAVEPOINTコマンドおよびRELEASEコマンドを使用します。 これは、SQLiteの動作と同じです。

Berkeley DBでアクセス制御はサポートされていますか。

アクセス制御(認証、ユーザー権限)は、アプリケーション・レベルで実装します。

複数の同時ユーザーはサポートされていますか。

はい。複数のユーザーが同時にデータベースにアクセスできます。 SQLiteに認証機能は含まれていないため(上記Q/Aを参照)、ここでのユーザースレッドまたはプロセスを意味します。

Berkeley DBはストアド・プロシージャをサポートしていますか。

ストアド・プロシージャはSQLiteでサポートされていないため、Berkeley DBのSQL APIでもサポートされていません。

Berkeley DBはトリガーをサポートしていますか。

はい、トリガーはサポートされています。ただし、いくつかのサポートされないケースがあります。

Berkeley DBはトランザクションをサポートしていますか。

はい、SQLiteセマンティクスでトランザクションはサポートされています。詳しくは、こちらを参照してください。

Berkeley DBはバックアップをサポートしていますか。

はい、バックアップは通常のBerkeley DBバックアップ手順を通じてサポートされています。

Berkeley DBの処理で"一貫性"(ACIDの"C")は維持されますか。

はい、一貫性は保証されています。ただし、データベース構成で制約が無効化されている場合を除きます。

インメモリSQLデータベースを作成する方法を教えてください。

ファイル名を:memory:にすると、接続に対してプライベートの一時インメモリ・データベースが作成されます。

個々の問合せに優先順位を付けることができますか。

優先順位の低い処理に対する割込みは、現在サポートされていません。

データ自体が破損している場合にエラー・コードを返すことができますか。

はい。すべてのこのような問題に対して、APIコールからエラー・コードが返されます。 またSQLiteのPRAGMA integrity_checkコマンドを使用すると、明示的にデータベースを検証できます。

Berkeley DBはRAWディスク・アクセスをサポートしていますか。

RAWディスクへのアクセスは現在サポートされておらず、この機能に対する将来的なサポートも計画されていません。

Berkeley DBはスキーマ移行をサポートしていますか。

SQLiteはALTER TABLEに対するサポートを提供していますが、いくらかの制限があります。 将来的なバージョンのSQLiteでは、これが変更される可能性もあります。

SQLiteとBerkeley DB間の使用の違いについて教えてください。

サポートされるSQL言語とプログラミング・インタフェース(API)はまったく同じであり、 Berkeley DBは、SQLiteのこの部分を変更せずに使用しています。 コマンドライン・ツールによって解釈される特別なコマンドも同様です。 ただし、ストレージ・アーキテクチャ(およびリリースの有効期間)が異なるため、100%の互換性に関しては次の点に注意する必要があります。

  • 一部のSQLiteのプラグマはサポートされていないか、またはセマンティクスやデフォルト値(例:キャッシュ・サイズ)が異なります。
  • ロック・セマンティクスの違いによって、通常は同時実行性が高くなりますが、SQLiteでは発生しなかったデッドロックがBerkeley DBで発生する可能性があります(例:2つのトランザクションが同時に実行され、1つが表A、表Bの順に更新を実行し、もう1つが逆の順で更新を実行する場合)。

Berkeley DBからSQLiteデータベース・ファイルを開くことができますか。または自動的にファイルが移行されますか。

いいえ、Berkeley DBにはSQLiteの全コードが含まれているわけではありません。btreeファイルは除外されています。 特に、ファイル操作に関するコードはすべてBerkeley DBストレージ・エンジンによって置換されています。 スキーマとデータを移行するには、sqlite3コマンドライン・インタフェースを使用して.dumpを実行してから、Berkeley DBのdbsqlコマンドラインで、ダンプ・ファイルのデータおよびスキーマに対して.loadを実行する必要があります。

SQLiteからBerkeley DBへデータを移行する方法を教えてください。

SQLiteに含まれるsqlite3コマンド・ツールを使用して、次のコマンドを実行します。

$ sqlite3 my.db '.dump' | dbsql new.db

Berkeley DBでBEGIN IMMEDIATE/EXCLUSIVEを使用すると、どのように処理されますか。

これらの特別なトランザクション・モードは、デッドロックを回避する目的でSQLiteで使用されています。 SQLiteの内部には、読取り専用トランザクションと更新トランザクションという概念が存在します。 上記キーワードは更新トランザクションに適用されますが、これらを完全に理解するにはSQLiteのロック機能について理解する必要があります。 Berkeley DBでは、ほとんどの場合、これらのキーワードは無視されます。 言い換えると、デッドロックを回避するためにこれらを使用する必要はありません(これらのキーワードによってデッドロックが防止されるのではなく、デッドロックは自動的にBerkeley DBによって検出されます)。 上記のいずれかのキーワードを使用すると、トランザクションが更新トランザクションとして開始され、読取りに対する排他ロックが発生します(その他のRDBMSでのSELECT FOR UPDATEと同様)。 こうすることで、一部のアプリケーションではデッドロックの頻度が低下します。

5.2以降では、BEGIN EXCLUSIVEを使用して作成されたトランザクションは、排他トランザクションがコミットまたは中断されるまでの間、新規トランザクションの開始と既存トランザクションの進行をブロックします。

Berkeley DBで解消されたその他のSQLiteの制限/制約/問題について教えてください。

Berkeley DBでは、PRAGMA synchronousの意味合いがSQLiteとは異なります。 SQLiteでは、FULLよりレベルが低い場合、障害発生後にデータベースが破損している可能性があります。 Berkeley DBでは、事前書込みログ・セマンティクスが常にログに対して適用されるため、データベースは常に一貫性のある状態に回復できます。 したがって、synchronousを設定すると、破損の危険性を招くことなくBerkeley DBのスループットを向上できます。 Berkeley DBのsynchronous=ONレベルはDB_TXN_WRITENOSYNCフラグに相当し、システム・クラッシュ(ハード・リブートや電力損失)の前にコミットされたトランザクションをリカバリ時にロールバックできることを意味します。 このレベルでは、コミットされたトランザクションがアプリケーション・クラッシュによってロールバックされることはありません。 synchronous=OFFレベルはDB_TXN_NOSYNCフラグに相当し、アプリケーション・クラッシュまたはシステム・クラッシュのいずれの発生後にも、コミットされたトランザクションをロールバックできることを意味します。

Berkeley DBはADO.NETをサポートしていますか。

はい、Berkeley DB向けのADO.NETパッケージが提供されています。 このパッケージは、Berkeley DBダウンロード・ページから入手でき、ドキュメントも含まれています。 質問がある場合は、Berkeley DBのフォーラムを利用してください。

Visual Studio 2008でADO.NETソリューションを開くと表示されるセキュリティ警告について、注意する必要がありますか。

いいえ、この警告を気にする必要はありません。 この警告は、Visual Studioの外部でビルド・ファイルが自動生成されているために発生しているものです。 ファイルに問題はありません。

表示される正確な警告メッセージは次のとおりです。 "Security warning for System.Data.SQLite.2008"

ADO.NETパッケージが提供されていますが、System.Data.SQLiteパッケージは提供されていますか。

これらのパッケージは同じものです。 ADO.NETパッケージでは、.NET向けのSystem.Data.SQLiteの実装が提供されています。

Berkeley DBでfts1およびfts2を使用する方法を教えてください。

fts1やfts2を使用する必要がある場合は、お問い合わせください。

最小メモリ要件とデフォルト・メモリ要件を教えてください。

デフォルトのキャッシュ・サイズは10MiBであり、最小は100KiBです。 ログ・バッファ・サイズは32KiBです。 通常、その他の目的に100KiBが追加で使用されます。 最小の合計サイズは約1MiBになります。

デフォルトのページ・サイズを教えてください。

Berkeley DBでは、基盤ファイル・システムのブロック・サイズに基づいてデフォルト・ページ・サイズが構成されます。 詳しくは、Berkeley DBでのページ・サイズのチューニングに関するドキュメントを参照してください。

表の数に関する制約がありますか。

オープンできる表の数は、通常、オープンできるファイル・ハンドルの数によってのみ制限されます。

表のサイズに関する制約がありますか。

表サイズは、通常、ファイル・システム上に作成できる最大ファイル・サイズによって制限されます。

表に保存できるレコード数に制約がありますか。

実際的な制限はありません。 符号付き64ビット値に索引を作成できる数のレコードであれば、保存できます。

レコード・サイズに関する制約がありますか。

実際的な制約はありません。 stringフィールドやBLOBフィールドの最大長は、10億バイトです。

SQLiteのオプティマイザの機能について教えてください。 SQLiteのオプティマイザは統計情報を収集しないとオンライン上で確認しましたが、 WHERE句の順序に左右されるということですか。 つまり、WHERE句によって結合順序が決定されるとオプティマイザはみなしますか。

SQLiteのオプティマイザは特に高機能なものではありません。 使用できる索引があれば、これを使用するという経験則に基づいています。 一部の問合せコストはモデル化されており、統計情報を維持するanalyzeコマンドがオプションでサポートされていますが、これらはあまり高度なものではありません。 SQLiteの内部動作について、Webサイト上の詳細情報や SQLiteの最適化に関するFAQ を参照してください。ただし、古い情報が提供されている場合があります。

索引付けのメカニズムとこれによるBerkeley DBとSQLiteの違いについて、もう少し理解したいと考えています。 たとえばfillファクタが低い場合、Berkeley DBバージョンのSQLiteデータベースはどのくらい大きくなりますか。

Berkeley DBストレージ・エンジンでのファイル・サイズのオーバーヘッドに関しては、いくつかの情報があります。

  • Berkeley DBでは、行IDに対するカスタム・エンコーディングを除いて、SQLiteでの値のエンコーディングが直接使用されています。 このエンコーディングには長さ情報が含まれているため、それぞれのキー/データのペアに対してBerkeley DBが維持する長さが実質的に2倍になります。
  • Berkeley DBには、データ値の長さがすべてゼロになるようなデータベースに対するサポートは組み込まれていません。 Berkeley DBは、長さがゼロであるデータ項目を示す索引レコードごとに8バイト未満のデータを保管しますが、SQLiteではこのような目的専用の表タイプが提供されています。
  • 索引への挿入順序によってはBerkeley DBのfillファクタが不十分になる場合があります(索引リーフ・ページの空き領域が最大50%)。

このようなファクタがデータベース・ファイル・サイズに与える影響を正確に述べることは不可能ですが、 最悪の場合、小さいレコードと多数の索引が存在する結果となります。 レコードが大きく索引が少ない場合、ファイル・サイズはSQLiteとだいたい同じになります。

Berkeley DBでのBツリーのプライマリ/セカンダリ索引付けスキームについては理解しましたが、SQLデータに対してはスキームが異なると予想しています。 Berkeley DBでのSQLデータに対する索引付けの仕組みとその影響について教えてください。

SQLで表を作成すると、Berkeley DBファイルにprimaryサブデータベースが作成されます。 このプライマリ・データベースには、通常はSQLiteによって割り当てられる整数キーが定義されており、暗黙的な列名rowidを使用してSQLから参照できます。 SQLに宣言された索引ごとに追加のサブデータベースが作成され、索引を構成するSQL列に対するフィールドのエンコードが含まれたキーと、プライマリ内で相当する行の行IDが格納されます。 SQLiteは常にキーのみを設定または使用するため、これらのレコードでは、Berkeley DBでのデータ部分は常に空になります。 ただし、次の特別なケースに注意する必要があります。 表に対して整数の主キーを必要とするアプリケーションでは、次のとおりに表を宣言する必要があります。

create table t(id integer primary key, ...)

これはSQLiteのパーサーによって処理され、idが行IDの別名になります。これによりセカンダリ索引を維持する必要がなくなり、付随する実行時の検索コストも回避されます。 integer primary key索引を別の文で作成する場合を含め、その他の構文を使用すると、この特別な処理は実現されません。 Berkeley DBに組み込まれているセカンダリ索引と外部キーに対するサポートは、SQLインタフェースでは使用されない点に注意してください。 索引はSQLiteの問合せプロセッサによって維持されます。

SQLiteは特定のファイルに対して実行時に共有読取りロックまたは排他書込みロックを取得します。 ここで、ファイルはデータベース全体を意味しますか。または1つの表を意味しますか。

ファイルはSQLデータベース全体(表や索引を含むすべて)を指すため、SQLiteは通常、データベース全体のロックを取得します。 SQLiteが共有キャッシュ・モードで使用されている場合、ロック事情はさらに複雑になります。この場合、一部の操作でファイル全体がロックされる代わりに、キャッシュを共有しているプロセス内のスレッドに関連する表のみがロックされます。

ロックによるその他の影響について教えてください。 たとえば、大規模な表スキャンでは、Berkeley DBがすべてのページに対して読取りロックを取得および解放する必要がありますが、SQLiteがネイティブで取得または解放するのは1つのロックのみです。 これによるパフォーマンスへの影響と、もっとも影響を受けやすい/受けにくい問合せの種類について教えてください。

ロックによって大きな影響を受ける問合せもあります。 一部の問合せでは、最大30%の実行時間がロック(およびラッチ)に関係していることが確認されました。 スキャンによって表に含まれる各リーフ・ページがロックされることは事実ですが、通常、スキャンはバルク取得にマッピングされるため、多くの場合、ロックのコストはそれほど大きくはありません。 もっともコストの大きい問合せは、多数のランダム検索を含む問合せです。これは、それぞれの検索がBerkeley DB内でページ・ロックを取得するためです。 特に、索引は使用するが、中程度から高程度の選択性を持つ問合せのパフォーマンスが、一般に、Berkeley DBではもっとも低くなります。 該当する行は索引スキャンによって素早く特定されますが、プライマリ内での各行の検索によって高いオーバーヘッドが発生します。 回避策は、通常のRDBMSでの最適化手法と同じです。 索引の使用(プライマリのスキャン)を避け、包括索引(必要なすべての列を含む索引)を作成することで、プライマリへのアクセスが不要になります。

PRAGMA synchronous=OFFは、DB_TXN_WRITE_NOSYNCまたはDB_TXN_NOSYNCのいずれに相当しますか。

  • synchronous=OFFは、DB_TXN_NOSYNCの設定に相当します。
  • synchronous=ONは、DB_TXN_WRITE_NOSYNCの設定に相当します。
  • synchronous=FULLはBerkeley DBのデフォルト動作に相当し、コミットのたびに安定したストレージに対してログがフラッシュされます。

プラグマが使用されない場合、デフォルト設定はFULLになります。

Berkeley DBとSQLite間のVACUUMの違いについて教えてください。

SQLiteに実装されているVACUUMコマンドは、データベース・ダンプを実行し、続いてこのダンプから完全なリロードを実行します。 これはコストのかかる処理であり、処理中はデータベース全体がロックされます。 また、オール・オア・ナッシング処理でもあります。 成功するか失敗するかのどちらかであり、失敗した場合はもう一度実行する必要があります。 SQLiteが処理を終了すると、ダンプ・ファイルから順序どおりにキーが挿入されたことで、多くの場合、以前よりもデータベースのサイズ(ファイル・サイズ)が小さくなり、Bツリーの編成が改善されます(奥行きが浅くなります)。 処理が成功し、データベース全体をロックする余裕がある限り、SQLiteのVACUUMは優れた成果をもたらします。 Berkeley DBは、まったく異なるアプローチをとります。 多くのリリースにわたって、Berkeley DBのBツリー実装は、その他の処理を実行しながらコンパクト処理を実行する機能を提供しています。 コンパクト処理は、Bツリー・ノードを調査し、状態が最適でない場合はノードを再編成(併合など)するプロセスです。 Bツリーの奥行きが浅くなればなるほど、リーフ・ノードでデータを見つけるために必要な検索数が少なくなります。 Berkeley DBは一度に、特定のツリー・セクションに対して、またはツリー全体に対してコンパクト処理を実行します。 24時間365日(99.999%)の連続処理を提供している場合、この機能が不可欠になります。 Berkeley DBバージョンのコンパクト処理によって進行中のデータベース処理に悪影響が及ぶことはありませんが、SQLiteのアプローチでは影響が及びます。 しかし、コンパクト処理では、データベースの空白部分(削除されたデータが存在していたデータベース・ファイルのセグメント)は処理の対象になりません。 Berkeley DBはファイル内でデータを移動し、ファイルを切り捨て、この領域をファイル・システムに返すことで、データベース・ファイルの圧縮もサポートしています。 Berkeley DBのリリース5.1では、VACUUMコマンドによってデータベース・ファイルのコンパクト処理と圧縮が実行されます。 この処理では、データベースを稼働したままにするために、より多くの作業が実行されるため、SQLiteのダンプ/ロード・アプローチよりも多くの時間がかかります。 これは妥当なトレード・オフであると思われますが、意見が異なる場合はいつでも、コードを使用してデータベースのダンプ/ロードを実行できます。

SQLiteでは、Berkeley DBと同じ方法で(Bツリー・キーを使用して、データの格納先ページを特定)、ページ上で削除された領域が再利用されますか。

はい、このレベルのBツリー実装はほとんど同じです。 SQLiteは異なるアルゴリズムを使用してツリーのバランスを維持しますが、削除された行が使用していたページ上の領域は再利用されます。また、すべての行がページから削除されると、ページは空きリストに追加され、再利用の対象になります。 Berkeley DBでは、ファイルの最後のページが空白になると、ファイルは自動的に切り捨てられます。

デッドロックの検出はどのように構成されていますか。

デッドロックの自動検出が有効化されており、デフォルトのデッドロック解決アルゴリズムが使用されます。 詳しくは、set_lk_detect( http://download.oracle.com/docs/cd/E17076_02/html/api_reference/C/envset_lk_detect.html)のドキュメントを参照してください。

ログ・ファイルが削除されるタイミングについて、 またホット・バックアップおよび増分バックアップへの影響について教えてください。

デフォルトでは、ログ・ファイルに含まれるすべての情報がデータベース・ファイルに同期された時点で、ログ・ファイルは自動的に削除されます。 つまり、増分バックアップの処理には特別な注意を払う必要があります。 コンパイル時にBDBSQL_OMIT_LOG_REMOVEプリプロセッサ・フラグを指定すると、ログ・ファイルの自動削除を無効化できます。

Berkeley DBで使用できるチューニング・ツールについて教えてください。

専用に提供されているものはありませんが、SQLiteのアプリケーションやデータベースのチューニングに使用できるリソースは多数あります。

SQLデータベースに対するカスタム・プロセスの接続時に特別な考慮事項がありますか(チェックポイント、トリクルなど)。

はい、あります。 その他のデータベース・アクセスと同時にカスタム・プロセスを接続する場合、DB_REGISTERフラグを使用する必要があります。 Berkeley DBユーティリティでは、通常このフラグは設定されないため、ユーティリティの使用時にさらなる配慮が必要になります。

データベース・ファイルの内部で使用されているサブデータベース名について教えてください。

SQLiteはID番号を使用して表を参照しますが(SQLiteでは、IDがこの表に対するBツリーのルート・ページになります)、Berkeley DBは名前を使用してサブデータベースを参照します。 マッピングは次のとおりです。

sprintf(table_name, table, table_id);

通常の表は奇数を持ち、索引は偶数を持つように、IDが割り当てられます。 t1という名前のSQL表のIDを確認するには、次の問合せを実行します。

select rootpage from sqlite_master where name=t1;

これはたとえば、db_statユーティリティで-sフラグを指定して、特定の表の統計情報を取得する場合に使用できます。

DB_CONFIGファイルを使用してデフォルト設定をオーバーライドできますか。

はい、できます。データベースを作成する前に、ジャーナル・ディレクトリとDB_CONFIGファイルを作成してください。 または、データベース・ファイルが使用されていない間にDB_CONFIGファイルを作成し、手動でdb_recoverユーティリティを実行します。 Berkeley DBユーティリティを実行する前に、SQLデータベース向けのDB_CONFIGファイルに次の行が含まれていることを確認してください。

add_data_dir ..

一時データベースには永続性がないこと以外に特別な点がありますか。 また、:memory:データベースについて教えてください。 これらはBerkeley DBのキャッシュを内部で使用しますか。

一時表はディスク上のファイルには含まれておらず、インメモリ・ログを使用して、SQLで期待されるとおりにトランザクションやセーブポイントを処理します。 永続性を持たないため、クラッシュ後に回復することはできませんが、 その他に特別な点はありません。 :memory:データベースは一時表だけで構成されています。 内部キャッシュを使用しており、最初の一時表の作成時に割り当てられます。

SQLiteのC++ APIでは例外が使用されていますか。

SQLiteのC++ APIは、例外処理を使用する代わりにエラー・コードを返します。

SQLITE_BUSYの簡単な使用方法を教えてください。

SQLiteのAPIを使用して、ビジー・コールバック・ハンドラを登録できます。

int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);

こうすることで、SQLITE_BUSYイベントの自動処理を簡単に実行できるようになります。 ハンドラを登録しない場合、手動でリターン・コードをチェックして再試行する必要があります。 または、次のAPIを使用すると

int sqlite3_busy_timeout(sqlite3*, int ms);

タイムアウトのしきい値を設定できます。 結果セットに対する反復処理方法を教えてください。

  • ワンステップの問合せ実行インタフェース(sqlite_exec())を使用している場合、sqlite_exec()の3番目の引数にコールバック関数を設定することで、結果の反復処理を実行できます。
  • 準備された問合せ実行を使用している場合、sqlite3_column_*()関数を使用すると、現在の文ステップの結果をフェッチできます。
  • sqlite3_get_table()を使用するとメモリ・データ構造に結果を直接フェッチできますが、結果セットのサイズとシステムで使用可能なメモリのサイズによる制約を受けます。

sqlite3_prepare()sqlite3_prepare_v2()sqlite3_prepare16()、およびsqlite3_prepare16_v2()間の違いについて教えてください。

sqlite3_prepare()インタフェースとsqlite3_prepare_v2()インタフェースではUTF-8が使用されており、sqlite3_prepare16()sqlite3_prepare16_v2()ではUTF-16が使用されています。すべての新規プログラムに対して、sqlite3_prepare_v2()インタフェースとsqlite3_prepare16_v2()インタフェースの使用が推奨されています。 2つの古いインタフェースは下位互換性を維持するために残されていますが、これらの使用は推奨されていません。 詳しくは、prepareに関するSQLiteドキュメントを参照してください。

Berkeley DB 11g Release 2では、ユーザーが主キーを指定せずに表を作成できますか。

はい、できます。Berkeley DB 11g Release 2で表を作成する場合、主キーを指定する必要はありません。 この場合、Berkeley DB 11g Release 2によって、暗黙的な整数の行ID列が主キーとして作成されます。したがって、ユーザーが整数以外の主キーを指定すると、主キーから行IDへのマッピングを行う2番目の表が作成され、次の2つのBerkeley DB表が存在します。

  • 行全体と、SQLiteによって管理される整数キー(行ID)を含むプライマリ表
  • アプリケーション・キーから行IDへのマッピングを行う索引

プロファイリング・ツールは提供されていますか。

次のいずれかの方法を利用できます。

  • SQL文の前にexplainを使用して、問合せ計画(VDBE形式)を取得する。
  • sqlite_analyzer()メソッドを使用する。
  • トレース関数とプロファイリング関数(sqlite3_trace()およびsqlite3_profile())を使用する。 詳しくは、こちらを参照してください。
  • sqlite3シェルの.timerコマンドを使用する。
  • SolarisまたはMac OS/Xでdtraceを使用する。

Berkeley DB 11g Release 2データベースに含まれる表の数と各表の説明を確認する方法を教えてください。

SQLコマンドライン・モードでselect * from sqlite_master;コマンドを実行すると、これらの情報が表示されます。 サポートされているその他のSQL文については、SQLiteのチュートリアルを参照してください。

Berkeley DBはJDBCをサポートしていますか。

はい、Berkeley DBにはオープンソースのJDBCドライバが含まれています。

サポートされているJDBCドライバの制約について教えてください。

現在、JDBCドライバでは次のプロパティがサポートされていません。

  • prepareCall
  • savePoint(setSavepoint/rollback/releaseSavepoint)
  • prepareStatement()は、resultSetTypeFORWARD_ONLYSCROLL_INSENSITIVE、またはSCROLL_SENSITIVEのいずれかに設定されており、resultSetConcurrencyCONCUR_REQD_ONLYまたはCONCUR_UPDATABLEに設定されている場合に限って、条件付きでサポートされています。
  • getParameterMetaData

Berkeley DBはODBCをサポートしていますか。

はい、Berkeley DBにはオープンソースのODBCドライバが含まれています。

ある検索の実行中に、別の検索を中断することはできますか。

はい、これはsqlite3_interruptを使用したsqliteodbcでサポートされています。

Berkeley DBはSQLの取消しをサポートしていますか。

はい、これはsqlite3_interruptを使用したsqliteodbcでサポートされています。

Berkeley DBを実行できるWindows Mobileのバージョンについて教えてください。

デフォルトのソリューションおよびプロジェクト・ファイルを使用すると、Pocket PC 2003とSmartphone 2003向けのビルドが実行されます。Windows Mobile 6.0、6.1、6.5、および6.5.3向けのビルドを実行するには、Windows CEビルド・ドキュメントに記載された手順を参照してください。

Windows Mobile 6.xでのサンプル・アプリケーションのリンク・エラーLNK1112を修正する方法を教えてください。

具体例を次に示します。 fatal error LNK1112: module machine type 'THUMB' conflicts with target machine type 'ARM' Visual Studio 2005で、ビルド対象のプロジェクトをクリックします。

  1. 「プロジェクト」→「プロパティ」を選択し、Linkerへ移動します。
  2. 「Command Line」セクションを選択し、/MACHINE:ARMを削除します。

Windows Mobile 6.5.3でのサンプル・アプリケーション(デバッグ・ビルド)のリンク・エラーLNK1103を修正する方法を教えてください。

これは、Visual Studio 2005 SP1に対する既知のバグです。msdn.comを検索して最新の修正プログラムを入手してください。

SQL APIでトランザクション・スナップショットを有効化する方法を教えてください。

トランザクション・スナップショットは、5.0および5.1ではサポートされていません。 5.2以降では、PRAGMA multiversion=on|offおよびPRAGMA snapshot_isolation=on|offというプラグマを使用することで、トランザクション・スナップショットを有効化できます。 DB_CONFIGを使用したDB_MULTIVERSIONDB_TXN_SNAPSHOTの設定は、どのバージョンのSQL APIでも正しく動作しません。