在C语言中编写数据库抽象层的好策略

时间:2012-04-18 07:34:01

标签: c api postgresql rdbms libpq

我需要在C语言中为PostgreSQL的数据库访问API( libpq )以及其他一些关系数据库管理系统编写数据库抽象层。

我正在考虑在 pqsql 以及可能的其他数据库系统中编写自己的现有函数抽象。 编写此类数据库抽象API时,最好的策略是什么?

到目前为止,我首选的写作计划可能是:

  1. 为任何特定数据库定义标头,函数和包装器 感兴趣的系统。
  2. 使用第一个连接呼叫(功能)时,请检查并确定哪个关系数据库管理系统适合。
  3. 包括正确的数据库抽象方法和定义。
  4. 但这种处理方式可能允许一次使用一个关系数据库管理系统。这对于数据库抽象层来说是否常见?

    还可以考虑其他哪些选项?

2 个答案:

答案 0 :(得分:10)

不要重新发明这个轮子。

它已经反复完成,虽然最受欢迎的系统(ODBC)无可否认是丑陋的,但它已经为你所听过的每个数据库编写了抽象。 使用UnixODBC项目,它也存在于UNIX和POSIX UNIX上,就像Mac OS X一样。

一个稍微不那么丑陋的替代方案,数据库支持更窄,libdbi。您不会像使用ODBC那样从libdbi供应商那里获得驱动程序。

怎么重复?

如果C ++没问题,我听到非常好的另一个数据库抽象层就是诺基亚(曾经是TrollTech)提供的Qt framework's database interface。它的主要优点是已经 *编写*并经过测试。主要的缺点是,如果您的应用核心不是基于C ++和Qt,那么它有点笨拙。

其他C ++选项,我未亲自使用过,sqlapi++dtemplatelibSOCI

如果到目前为止你想知道为什么所有这些数据库抽象层都是为C ++编写的,那么这可能就是一个提示。如果你用C编写一个DB抽象层,我打赌你会通过函数指针的结构重新发明C ++虚方法,并且可能最终创建一些像GObject一样丑陋的东西,在这种情况下你也可以使用libgdb / gnome-db。为了避免虚假的虚拟方法垃圾,你可以通过运行时库路径在链接时选择数据库层,只提供一堆普通的老函数,但我不知道为什么你这么做时会这么做选项在附近。

顺便说一句,如果事实证明你根本不需要DB抽象,只有一个更好的界面(因为你主要针对Pg),请查看libpqtypes(普通C,没有C ++,非常便携),或者称为“libpq应该是什么”。即使您要添加一个抽象层,也可能值得在libpqtypes上进行,而不仅仅是libpq。

如果ODBC,libdbi,libpqtypes,Qt等不适合您,您需要定义原因,并创建一组更具体的标准来满足。

或者:如果您的设计允许,您可能需要考虑使用类似Pythonpsycopg),{{3的数据库抽象层的嵌入式更高级语言进行数据库访问和相关工作}},RubyPerlJava)。所有这些都有自己广泛采用且经过良好测试的数据库抽象层,您可以从中受益,同时仍然在C中编写大部分程序。或者,就此而言,您可以在C中编写程序的性能关键位作为库,并使用已经为您编写的理智的数据库抽象层,从您选择的语言中使用它。

数据库抽象很难。真的很难。数据库抽象使用起来并不太糟糕,表现得体面,并且足够灵活,可以使用数据库,因为不仅仅是愚蠢的行存储更难 - 迟早,你需要的不仅仅是愚蠢的行存储。

答案 1 :(得分:3)

我不确定你是在寻找更具体或更通用的想法。 通常我看到类似的事情是通过定义一个包含所有相关函数的函数指针的公共结构。

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

然后,对于每个DBMS,您可以使用指向与该DBMS相关的函数的指针来填充此数组。然后将此指针保存到某处的propely initialized struct,并使用它来调用(directy或某种类型的包装函数)......

每当我看到我想知道为什么不简单地使用c ++和虚方法。