3

PostgreSQLのデータベースアクセスAPI( libpq)およびおそらく他のリレーショナルデータベース管理システム用に、Cでデータベース抽象化レイヤーを作成する必要があります。

私は、pqsqlおよびおそらく他のデータベースシステムで既存の関数の独自の抽象化を書くことを検討しています。このようなデータベース抽象化APIを作成するために検討するのに最適な戦略は何でしょうか。

これまでのところ、これを書くための私の好みの計画はおそらく次のようになります。

  1. 対象の特定のデータベースシステムのヘッダー、関数、およびラッパーを定義します。
  2. 最初の接続呼び出し(関数)を使用するときは、それがどのリレーショナルデータベース管理システムに適しているかを確認して判断します。
  3. データベースを抽象化するための適切なメソッドと定義のセットを含めます。

しかし、このような処理方法では、おそらく一度に1つのリレーショナルデータベース管理システムしか使用できません。これはデータベース抽象化レイヤーで一般的ですか?

他にどのようなオプションを検討できますか?

4

2 に答える 2

11

この車輪を再発明しないでください。

それはすでに何度も行われており、最も人気のあるシステム ( ODBC ) は紛れもなく醜いものですが、これまでに聞いたことのあるすべてのデータベースに対して既に抽象化が記述されています。UnixODBCプロジェクトでは、UNIX や Mac OS X などの POSIX UNIX にも存在します。

はるかに狭いデータベースサポートを備えたやや醜い代替手段はlibdbiです。ODBC の場合のように、libdbi のベンダーからドライバーを入手することはできません。

どのくらい繰り返しますか?

C++ が問題ない場合、 Qt フレームワークの データベース インターフェースである Nokia (かつては TrollTech) によって提供されている、非常に良いと聞いたもう 1 つの DB 抽象化レイヤーです。これには、すでに*記述*およびテスト済みであるという大きな利点があります。主な欠点は、アプリのコアが C++ および Qt ベースでない場合、少しぎこちないことです。

私が個人的に使用したことのないその他の C++ オプションは、sqlapi++dtemplatelib、およびSOCIです。

この時点で、これらすべてのデータベース抽象化レイヤーが C++ 用および C++ で作成されている理由を疑問に思っている場合は、おそらくそれがヒントです。C で DB 抽象化レイヤーを作成すると、関数ポインターの構造体を介して C++ 仮想メソッドを再発明することになり、おそらくGObjectとほぼ同じくらい醜いものを作成することになるでしょう。その場合、libgdb / gnomeを使用することもできます-デシベル。偽の仮想メソッドのジャンクを回避するために、ランタイム ライブラリ パスを介してリンク時に DB レイヤーを選択可能にし、単純な古い関数の束を提供することができますが、非常に多くの既存の関数を使用する理由がわかりませんオプションは周りにあります。

ところで、DB の抽象化がまったく必要ないことが判明した場合は、(主に Pg をターゲットにしているため) より優れたインターフェイスのみが必要です libpq は". 抽象化レイヤーを追加する場合でも、libpq だけでなく libpqtypes に対して行う価値があるかもしれません。

ODBC、libdbi、libpqtypes、Qt などが適していない場合は、その理由を定義し、満たすためのより具体的な基準セットを作成する必要があります。

別の方法: 設計が許す場合は、 Python ( psycopg )、RubyPerl、またはJava ( JDBC )などの DB 抽象化レイヤーを使用して、組み込みの高レベル言語でデータベース アクセスと関連作業を行うことを検討することをお勧めします。これらはすべて、広く採用され、十分にテストされた独自のデータベース抽象化レイヤーを備えており、プログラムの大部分を C で作成しながら、その恩恵を受けることができます。ライブラリを作成し、選択した言語から、既に作成された適切なデータベース抽象化レイヤーを使用して使用します。

データベースの抽象化は難しいです。とても大変。データベースの抽象化は、使用するのが悪くなく、適切に機能し、データベースを使用するのに十分な柔軟性を備えています。これは、愚かな行ストア以上のものはさらに困難です。そして遅かれ早かれ、愚かな行ストア以上のものを必要とするでしょう。

于 2012-04-18T11:23:12.700 に答える
3

より具体的なものを探しているのか、単に一般的なアイデアを探しているのかわかりません。同様のことが行われるのを私が見た通常の方法は、関連するすべての関数への関数ポインターを含む共通の構造体を定義することです。

struct dbms {
    int (*connect)(const char *cs);
    int (*disconnect)(void);
    int (*query)(...);
    ...
}

次に、DBMS ごとに、この配列にその DBMS に関連する関数へのポインターを入力します。次に、このポインターを適切に初期化された構造体のどこかに保存し、それを使用して(直接または何らかのラッパー関数から)呼び出します...

それを見るたびに、単純に C++ と仮想メソッドを使用しないのはなぜだろうと思います。

于 2012-04-18T08:51:40.307 に答える