代码之家  ›  专栏  ›  技术社区  ›  Ross

数据库抽象-支持多种语法

  •  1
  • Ross  · 技术社区  · 17 年前

    在我正在研究的一个PHP项目中,我们需要创建一些DAL扩展来支持多个数据库平台。我们遇到的主要陷阱是,不同的平台有不同的语法——值得注意的是,MySQL和MSSQL是完全不同的。

    最好的解决办法是什么?

    以下是我们讨论过的几个问题:

    基于类的SQL构建

    这将涉及创建一个类,该类允许您逐位构建SQL查询。例如:

    $stmt = new SQL_Stmt('mysql');
    $stmt->set_type('select');
    $stmt->set_columns('*');
    $stmt->set_where(array('id' => 4));
    $stmt->set_order('id', 'desc');
    $stmt->set_limit(0, 30);
    $stmt->exec();
    

    不过,对于一个查询,它确实涉及相当多的行。

    SQL语法重新格式化

    这个选项要干净得多——它将读取SQL代码,并根据输入和输出语言重新格式化它。但就解析而言,我可以看到这是一个慢得多的解决方案。

    4 回复  |  直到 17 年前
        1
  •  1
  •   Till    17 年前

    我建议使用基于类的SQL构建并推荐 Doctrine , Zend_Db MDB2 .是的,如果它需要更多的行来编写简单的选择,但至少您可以依赖于解析器,而不需要重新发明轮子。

    使用任何dbal都是速度上的折衷,不仅是数据库执行,而且第一次使用其中任何一个dbal都比真正熟悉它时更痛苦。另外,我几乎百分之百地肯定生成的代码不是最快的SQL查询,但这是我前面所说的权衡。

    归根结底,这取决于您,所以即使我不会这样做,而且肯定也不是不可能的,但问题仍然存在,您是否可以通过实现自己的DBAL来节省时间和资源(从长远来看)。

        2
  •  1
  •   andy.gurin    17 年前

    一个解决方案可能是为不同的平台使用不同的查询集,其ID类似于

    mysql:get_users=“从用户中选择*

    mssql:get_users=…

    pgsql:获取用户数=…

    然后在启动时加载所需的一组查询,然后引用

    DB::LoadQueries(平台):

    $users=$db->查询(获取用户)

        3
  •  1
  •   Cade Roux    17 年前

    这样的方案不会考虑到SQL提供的所有丰富性,因此您最好使用为每个DB的所有表生成的代码存储过程。

    即使您使用参数化存储过程,这些过程更了解数据库模型(即它们可以连接或了解用户,因此针对每个供应商都进行了优化),这仍然是一种很好的方法。我总是认为数据库接口层不仅仅是为应用程序提供简单的表,因为这种方法会占用大量的带宽,而且会浪费往返时间。

        4
  •  1
  •   MikeJ    17 年前

    如果您有一组后端支持它,我同意生成存储过程以形成契约是最好的方法。但是,如果您的后端在存储过程方面的能力有限,则此方法不起作用,在这种情况下,您将构建一个AbstAction层来实现SQL或基于抽象/有限的SQL语法生成特定于目标的SQL。