Firebird/ja
│
English (en) │
français (fr) │
日本語 (ja) │
русский (ru) │
参照: チュートリアル/練習となる記事: 各種データベース |
これはLazarus/FPCでSQLDB(FPC/Lazarus同梱のライブラリ)SQLDBを用いてFirebirdデータベースを用いるためのガイドである。他のアクセス方法はOther Firebird librariesに述べられている。
概要
Firebirdは長年にわたり使用、開発されてきたオープンソースのフリーデータベースサーバである(BorlandによってオープンソースとなったInterbase 6 より開発されている)。豊富なSQLステートメント(例えば INSERT...RETURNING)、ストアドプロシージャ、トリガ、などをサポートしている。もしすでにあるFirebirdの拡張関数を拡張したければ、Free PascalのコンパイルされたUDF(ユーザー定義関数)を書くこともできる。 本データベースは一度設定してしまえばほとんど手動によるDBA作業を要求せず、小規模ビジネス用途、あるいは組み込み用途に好適に用いられる。PostgreSQLがそのような大規模環境にはより良い選択かもしれないが、適切なチューニングでテラバイトスケールにまで拡張できる。
Firebirdは - FPC/Lazarusで1行もコードを変える必要なく、(ファイルベースの)組み込みとクライアント/サーバデータベースを提供する もし組み込みデータベースとして用いられると、SQLiteよりも豊富なSQLサポート同様に、SQLiteが組み込みデータベースとして非常に優秀だといえど、クライアント/サーバデータベースにシームレスに移行できる 最新の安定バージョン、Firebird 2.5、はWindows(32- and 64-bit)、様々なLinuxバージョン (32- and 64-bit)、Solaris (Sparc、Intel)、HP-UX (PA-Risc)、OSXで動作する。
現在Androidにポート中で、Windows CEとWindows Mobileでは利用できない。
FPCのSQLDBにおけるFirebirdのサポートは非常によく、PostgreSQLに匹敵する。
ドキュメンテーション
FPC 2.6.2+には公式ドキュメンテーションが含まれている: SQLDB documentation for IBConnection
クライアント/サーバと組み込みインストール
Firebirdはクライアント/サーバと組み込みモードで動作することができる。
Client/Serverはどこかに物理的なFirebirdサーバ: ローカルマシンあるはネットワークでアクセスできる他のマシン。 サーバに対する接続はTCP/IPを介して、名前、IPアドレスを含む接続をホスト名である。このために必要なFirebird DLLはfbclient.dll(およびそのサポートファイル) である。
Embedded Firebird(組み込みFirebird)はローカルマシンのFirebirdデータベースにアクセスするFirebird DLLをロードするアプリケーションを意味する。接続を特定すれば、ホスト名はいつもからである。このために必要なFirebird DLLはfbembed.dll(およびそのサポートファイル)である。 詳細はここを参照されたいthe wiki page on Firebird embedded。
fbembed.dllはクライアント/サーバと組み込み用途両方に用いられることに注意。であるので、このdllのみをインストールするのは賢明である。
Windows
Win64: 特定のFPC/LazarusではWin64バージョンを用いないことを確かめてほしい here
Windows: (これはすべてのSQLLBデータベースドライバに当てはまる)、fbclient.dllを(もしくはfbembed.dll)を持つ必要があり、そのサポートDLLはいかにインストールする:
- プロジェクトディレクトリ と 実行ファイルアウトプットディレクトリ/アプリケーションディレクトリ(例えばプロジェクトディレクトリ下のlib/something)
- またはPATHの通ったディレクトリ(システムディレクトリではなく)
- もしシステムディレクトリを用いたいのであれば、公式インストーラーを用いて、"システムディレクトリにコピーする"を選択する
全てのデータベースDLLのように、DLLのビット数をアプリケーションに揃えなければならない。32-bitのためにコンパイルしたら、32-bitライブラリを、64-bitならば、64-bitを。
Unix/Linux/macOS
FreeBSD/Linux/macOSでは、Firebirdクライアントライブラリをインストールするべきである(例えばパッケージマネージャで通常パッケージと-devパッケージ)、またはそれらはライブラリサーチパスに置かれるべきである。
FPCは通常のライブラリ名を探索する(例えばlibfbclient.so.2.5, libgds.so, and libfbembed.so.2.5; もし、バージョンが異なっていたらibase60.incを調べられたい) これには2つの方法がある:
- sqldlibからTSQLDBLibraryLoader component(FPC 2.7.1). 全てのSQLDBコネクタコンポーネント.
- 正しいライブラリ名でを呼ぶ(このためにはibase60dynユニットを使う必要があるかもしれない).
function InitialiseIBase60(Const LibraryName : AnsiString) : integer;
接続例
クライアント/サーバの例:
ホスト名: 192.168.1.1 * データベースはIPアドレス 192.168.1.1である。 データベース名: /interdata/example.fdb * データベースファイル名はサーバの/interdataディレクトリの"example.fdb"(マシンのIP address 192.168.1.1). ユーザー名: SYSDBA パスワード: masterkey
もう1つのクライアント/サーバ:
ホスト名: dbhost * データベースはdbhostのホスト名を持つサーバにある データベース名: F:\Program Files\firebird\examples\employee.fdb * dbhostのF:¥ドライブのProgram Files\firebird\examplesディレクトリに"employee.fdb"データベースファイルを持つ ユーザー名: SYSDBA パスワード: masterkey
組み込み例:
ホスト名: なし * ホスト名は空のまま。 データベース名: test.fdb * データベースファイル名はアプリケーションが実行されるディレクトリの"test.fdb"(fbembed.dllがアプリケーション実行ディレクトリにあることを確認すること) ユーザー名: SYSDBA * 組み込みではユーザー名を特定する必要がある... パスワード: 空文字列 * ... しかしどのパスワードでも構わない
トラブルシュート クライアント/サーバアクセス問題
Interbase/Firebirdサーバが示されたIP/ホスト名で実行されていることを確かめること。マシンにtelnetして接続性を試すことができる。Firebirdは普通ポート3050で待ち受けている:
telnet 192.168.1.1 3050
何か、おそらくブランクスクリーンのようなものを見るはずだ。しかし何かをタイプできる。これはFirebirdデータベースにデータを送ったこととなる。
さらなる情報についてはFirebirdドキュメンテーションを参照されたい。
イベントのモニタリング
FPC/LazarusにはFirebirdデータベースからくるイベントをモニターするコンポーネントが付属する; TFBEventMonitorを参照されたい。
プログラム的にオブジェクトを作る
例えばツール、Flamerobinといったツールでテーブルを作ることができるが、またプログラム的/動的に行うこともでき、それは現在存在する、データベーススキーマに新しいスキーマでアップデートするときに便利である。
このタスクを行うために例えば TSQLQuery.ExecSQL を実行する:
Query.ExecSQL('CREATE TABLE TEST(ID INTEGER NOT NULL, TESTNAME VARCHAR(800))');
// どのDMLの前 - SELECT、INSERTなどのステートメント、DDLの後にトランザクションをコミットする必要がある。
// さもないとSQLはオブジェクトを見ないだろう。
これを行うためにTSQLScriptオブジェクトを用いる - TSQLScriptを参照されたい。
データベース管理
FPC/Lazarusはデータベース管理のためのコンポーネントを有している; TFBAdminを参照されたい。
日常の問題と解決策
ときに、LazarusのFirebirdは扱いに注意が必要となる。以下の解決策をご覧いただきたい。
読み取り専用カラム / COMPUTED BYフィールドへのアップデート
もし、FirebirdテーブルにCOMPUTED BYフィールド(サーバ側で計算されるフィールド)を持つ場合、SQLDBはそれらは読み取り専用で(性能上の理由で)ピックアップしない。
このような場合、自動生成されたINSERTSQL、UPDATESQLが"attempted update of read-only column"のようなメッセージをだす。解決策はTSQLQueryのSQLプロパティを設定した後に、当該フィールドをがアップデートされないかもしれないと手動で特定することである。それはこのように:
// ユーザーが変更できないようにこのフィールドを変更した値でアップデートまたは検索しないようにことである。
sqlquery1.fieldbyname('full_name').ProviderFlags:=[];
大整数: 失われた正確性
もし大整数データタイプ(64 bit でサインされた整数signed integer)をFirebirdで用いるときはパラメータとして.AsIntegerの代わりに.AsLargeIntを用いること:
// 大整数のIDをここで割りてる
sqlquery1.sql.text := 'insert into ADDRESS (ID) values (:ID)';
// これを使うこと:
sqlquery1.params.parambyname('ID').aslargeint := <some qword or 64 bit integer variable>;
// これは用いないこと:
//sqlquery1.params.parambyname('ID').asinteger := <some qword or 64 bit integer variable>;
...
... さもないと重複したプライマリキー - もし大整数をプライマリキーに用いている場合、があるとエラーが出るかもしれない。
ブール値データ型
Firebirdのバージョン3.0に満たないものはブール値データ型を持たない。
少なくともFPCトランク(2.7.1)はこの型をエミュレートできる:
SMALLINTを用いるDOMAINを用いること(他の整数型も動作するだろう - 適宜テストして読み替えられたい):
CREATE DOMAIN "BOOLEAN" AS SMALLINT
CHECK (VALUE IS NULL OR VALUE IN (-1,0,1))
/* -1 はFPC SQLDBとの互換性のために用いられている; 1は他の多くのデータアクセスレイヤで用いられている*/
;
フィールド/カラムにこのドメイン型を使わせること、例えば
CREATE TABLE MYTABLE
(
...
MYBOOLEANCOLUMN "BOOLEAN",
);
- これでフィールド値等に .AsBooleanを用いることができる。
To do: これがLazarusのグリッド等で動くことの確認。
INSERT INTO...RETURNING 問題 / Cursorは開いていない =
もし、このようなSQLでselect SQL(例えば Query Open)をしようとすると:
INSERT INTO PEOPLE (NICKNAME) VALUES ('Superman') RETURNING ID
このようなエラーを見ることになる:
Database error: : Fetch :
-Dynamic SQL Error
-SQL error code = -504
-Invalid cursor reference
-Cursor is not open(error code: 335544569)
FPC 2.6.0 (Lazarus 1.0で供給される)もしくはそれ未満では, おそらくFPC SQLDBパーサバグに遭遇しただろう。
SQLDBは今行われているステートメントは通常の値を返さない、INSERTステートメントと考える。実際はそれはデータを返す。 より新しいFPCコードではこれは修正してある。
もし、多くの人間がするように、プライマリキーにジェネレータ/連続数を用いているのならば、これの回避の仕方は次の連続番号を最初に得ることである:
SELECT NEXT VALUE FOR GEN_PEOPLEID FROM RDB$DATABASE /* もしジェネレータの名前がGEN_PEOPLEIDとして */
そして、それを一般的なINSERTをすることに用いる。 FAQ entryを参照されたい。
Locateが動いてないようだ
Source: Issue ##21988
UTF8(もしくは他のマルチバイトキャラクタセット)CHARフィールドを動作させると、locateはレコードを見失うようだ。 問題はUTF8キャラクタセットが用いられ、どのようにFirebirdがカラムの長さを返すかにほとんど関連している。UTF8の場合、Firebirdは4倍の"キャラクタ長"として最大カラム長(バイトで)を返す。そのため、char(8)で定義されたカラムを持つと、Firebirdは4*8=32を返す。 値はこの32の長さに対して右揃えされる。例えば'57200001'をロケートするとフィールドは実際には'57200001 ........................'(ここでは続くスペースをドットで表している)を格納するのでマッチしない。
回避策: selectクエリを書き直す:
SELECT substring(THEFIELD from 1 for 8) AS THEFIELD ...
または
SELECT cast(THEFIELD as varchar(8)) as THEFIELD ...
または VARCHAR フィールドを用いる。
注意: この問題はフィールド長を返すことに依存する他のデータベースでも起こるかもしれない。
上級トランザクション
この情報/より高度なものとして以下がある:
- Understanding Firebird Transactions 非常に詳細な記事
- Transactions in Firebird もう1つの非常に詳細な記事
- Interbase 6 API Guide (FirebirdとInterbaseで共通) 63ページ以降
- Overview of transaction settings in Interbase
- Detailed explanation of parameters in Firebird
- Overview of settings in Firebird
- Transaction isolation levels in FIBPlus
- README.set_transaction.txt Firebird 2.5 ドキュメンテーションフォルダ。
トランザクション隔離レベル
もし望むなら、トランザクションのパラメータプロパティに1行加えることで、トランザクション隔離レベルを変えることができる:
isc_tpb_read_committed
: 他のトランザクションによりコミットされたすべての変化をすべて見ることができるisc_tpb_concurrency
: スナップショットとも呼ばれる: データベースがトランザクションを始めた時を見ることができる。より大きなオーバーヘッドがある isc_tpb_read_committed。幽霊読み出しがないのでANSI直列化可能より優れているisc_tpb_consistency
: 安定性とも呼ばれる: データの安定した、直列化可能なビュー、しかしテーブルをロックしてしまう。これが必要なことはないだろう
例:
SQLTransaction1.Params.text:='isc_tpb_read_committed';
トランザクションに効果のあるパラメータを追加できる(ibconnection.ppソースファイルから引用および[1])
アクセスモード
読み取り専用または読み書き可能を許す
isc_tpb_read
: 読み取り許可read permissionisc_tpb_write
: 読み取り+書き込み許可
ロック回避
isc_tpb_nowait
: もし他のトランザクションがレコードを編集しており、そして待たないisc_tpb_wait
: もし他のトランザクションがレコードを編集しており、その終了を待つ。重い競合で "live locks" を最小限にする([2]). タイムアウトバリュー以下を参照されたい
テーブル予約
テーブル全体をロックする。
isc_tpb_shared
: 始めてこれを設定すると、1つ、あるいは複数のテーブルにlock_read または lock_write がかかる。テーブルに対するシェアされた読み取りまたは書き込みモード。isc_tpb_protected
: 始めてこれを設定すると、1つ、あるいは複数のテーブルにlock_read または lock_writeの両方がかかる。テーブルのロックオンは遅延したトランザクションのコストの代わりにデッドロックのない操作を可能にする。isc_tpb_lock_read
: 読み取りロックを設定する。テーブルをロックするときに設定。例えばisc_tpb_lock_read=CUSTOMERSisc_tpb_lock_write
: 読み取り/書き込みロック。どのテーブルをロックするか特定する。例えばe.g. isc_tpb_lock_read=CUSTOMERS
組み合わせ:
- シェアされて、書き込みロック: 同時実行性もしくはコミットされた隔離を伴う書き込みトランザクションはテーブルをアップデートする。すべてのトランザクションがテーブルを読み取ることができる。
- シェアされて、読み取りロック: どのトランザクションも読み取りまたはアップデートできる。
- 保護されて、書き込みロック、読み取りロック: 他のトランザクションはテーブルをアップデートできない。同時実行性と読み取りトランザクションがテーブルを読むことができる。
- 保護されて、読み取りロック: 他のトランザクションはテーブルをアップデートできない。どのトランザクションもテーブルを読み取ることができる。
レコードバージョン
この設定は明らかに他のトランザクションによって変更されたレコードに対するisc_tpb_read_committedアイソレーションモードに対してのみ関連する:
isc_tpb_no_rec_version
: もっとも新しいレコードバージョンのみ読み取られる。isc_tpb_read_committedとともにバッチ/バルクinsertに有用であるisc_tpb_rec_version
: 最も最近コミットされたバージョンが読み取られる、他のトランザクションがコミットされてない変更を持っているときでさえ。注意: 確認すること。isc_tpb_no_rec_versionよりもオーバーヘッドがある
様々なオプション
完全性のためにFirebird/Interbase FPCコードの中にはいくつかのオプションがある。 おそらくバッチinsert/editの速度を上げるためにisc_tpb_no_auto_undoを用いるであろう。
- isc_tpb_exclusive (明らかにFirebirdで保護されている変換をする。[3]を参照されたい)
- isc_tpb_verb_time (動詞時またはコミット時異なった制約に関連している。Firebird: 実装されていない、いつも動詞時を使う)
- isc_tpb_commit_time (動詞時またはコミット時異なった制約に関連している。Firebird: 実装されていない、いつも動詞時を使う)
- isc_tpb_ignore_limbo (無視されたトランザクションにより生成されたレコードを無視する。無視されたトランザクションはマルチデータベーストランアクションで2フェーズコミットを失敗する。将来これが必要となることはなさそうである)
- isc_tpb_autocommit (このトランザクションを自動コミットする: 全てのステートメントは分離される。おそらく、特にJayBird JDBCドライバのためである。)
- isc_tpb_restart_requests (明らかに他のトランザクションでアクティブであったコネクションのリクエストを探す、それを元に戻し、新しいトランザクションを再開する。)
- isc_tpb_no_auto_undo (トランザクションレベルアンドゥログを無効にする、バッチアップデートで最大のスループットを出すために便利である。データを呼んでいるだけの時には効果がない。)
- isc_tpb_lock_timeout (もし、isc_tpb_waitを用いているならロック解除のために待つ秒数を設定する。もしこの値がロック解除なしに到達すると、エラーが出される。)
Firebird と ISO トランザクション
FirebirdトランザクションはISO/ANSIトランザクションレベルに1対1で当てはまっていない。要約は:
- ISO Read Committed=READ COMMITTED+RECORD_VERSION
- ISO Read Committed=READ COMMITTED+NO RECORD_VERSION
- ISO Repeatable Read=SNAPSHOT (CONCURRENCYとしても知られる)
- ISO Serializable=SNAPSHOT TABLE STABILITY (CONSISTENCYとしても知られる)
通常のコンビネーション
デフォルトは読み取りコミットである(おそらく確認の必要がある)。
バッチ / バルク INSERT
isc_tpb_read_committed と isc_tpb_no_rec_version は良い組み合わせであろう: バッチが進行しているときに他のトランザクションが可能である。
読み取り専用トランザクション
もし、データベースアクセスが読み取り専用であることを望むなら、このトランザクションパラメータを設定することでそのようにできる:
isc_tpb_read
isc_tpb_read_committed
isc_tpb_rec_version
nowait
この組み合わせはガーベージコレクションをブロックしないだろう、それは良いことである。 出典: [4]
注意: Firebird FAQ はもしデータベースを読み取り専用に設定しないならば、もし、読み取りだけでもデータベースファイルに書き込みアクセスが必要であることを示している(例えば gfixを用いて)。
リンクとさらなる情報
以下のリストはFirebirdと関連するツールのさらなる情報に対するリンクである。
Lazarus Firebird サンプル
- Sample Lazarus/Firebird application source code [5]
- Firebird/SQLDB tutorials:
- PP4S tutorials; cover Firebird installation on Windows as well:(訳注いずれのリンクもおかしい)
ツール
- FlameRobin Flamerobin site オープンソースのFirebird管理ツールである。Windows、Linux、Mac OSXで使える。特に推奨される。
- Turbobird Turbobird site オープンソースのFirebird管理ツール。TIBCOnnectionを用いてLazarusで書かれてある。
- ibconsole : GUIでFirebird、Interbaseを管理するツール、Windows、Linuxで利用できる。
- Lazarus Data Desktop - Lazarusレポジトリに含まれる。('tools/lazdatadesktop/'ディレクトリにある)
- LazSQLX マルチデータベースオープンソースデータベースマネジメントツール。LazarusでSQLDBとZeosの両方を用いて書かれている。Firebirdに対するサポートがある。
- tiSQLEditor - tiOPFレポジトリの"Support Apps"ディレクトリに含まれる。コード補完サポートでSQLを書くために使われるツールである。スクリプトを実行、のちに組み立てるために、ある構築からスクリプトをアップグレードできる。Object Pascalアプリケーションのために様々な便利なコピー&ペースト機能を持つ。tiOPFにとって便利な(tiOPFのビジタークラスでクエリの結果からObject Pascalのコードテンプレートを生成する)多くの機能がある
Firebird
- The Firebird RDBMS Firebird site. このサイトはFirebirdについて多くのドキュメンテーションを含む。
- Firebird FAQ [6]. 例えば、たのRDBMSとの差異を示す便利なサイト。
- 最近のツールとLibreOfficeの用い方を示す新しいサイト、FPCが間もなく加えられる。Firebird