1

在我正在处理的一个 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

4 回答 4

1

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

MySql: GET_USERS = "SELECT * FROM users"

MsSql: GET_USERS = ...

PgSql:GET_USERS = ...

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

Db::loadQueries(平台):

$users = $db->query(GET_USERS)

于 2008-10-19T12:27:04.817 回答
1

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

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

于 2008-10-19T12:39:47.083 回答
1

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

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

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

于 2008-10-19T15:16:34.243 回答
1

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

于 2008-10-19T15:24:43.713 回答