【问题标题】:Database Abstraction - supporting multiple syntaxes数据库抽象 - 支持多种语法
【发布时间】:2010-09-17 23:54:46
【问题描述】:

在我正在处理的一个 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 代码并根据输入和输出语言重新格式化它。然而,就解析而言,我可以看到这是一个慢得多的解决方案。

【问题讨论】:

    标签: sql database data-access-layer database-abstraction


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我推荐基于类的 SQL 构建并推荐 DoctrineZend_DbMDB2。是的,如果它需要更多行来编写简单的选择,但至少你可以依赖解析器并且不需要重新发明轮子。

      使用任何 DBAL 都需要在速度上进行权衡,而不仅仅是数据库执行,而且您第一次使用其中任何一种时都会比您真正熟悉它时更加痛苦。此外,我几乎 100% 确定生成的代码不是最快的 SQL 查询,但这是我之前所说的权衡。

      最终这取决于您,因此即使我不会这样做并且这肯定不是不可能的,但问题仍然存在,您是否可以通过实施自己的 DBAL 真正节省时间和资源(从长远来看)。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          解决方案可能是针对不同平台使用不同的查询集,ID 类似

          MySql: GET_USERS = "SELECT * FROM users"

          MsSql: GET_USERS = ...

          PgSql:GET_USERS = ...

          然后在启动时加载所需的查询集并引用

          Db::loadQueries(平台):

          $users = $db->查询(GET_USERS)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-07
            • 1970-01-01
            • 2015-05-16
            相关资源
            最近更新 更多