为什么我们需要 Zend_Db_Select

许多人说 Zend_DB_Select 是一个丑陋的实现,同时是完全没有必要的。那么我想谈一下我的想法,为什么我们需要 Zend_Db_Select。

首先,假设有一个非常熟悉 mysql 并且一直在其上工作的团队。现在有一个使用 Oracle 的项目需要开发。这个项目非常紧张,没有时间学习新的知识(是的,就像我们一样)。那么他们可以做什么?他们会掉入 SQL 的迷宫中去吗?又或者管理层突发善心给那么一点可怜的时间来学习 PL/SQL 的语法?

Zend_Db_Select 就是救世主。

他们不需要知道如何从 Oracle 中查询从一个记录号到另一个指定记录号之间的数据。只要记得 $select->limit($start, $end); 可以做到。这同 mysql 很像不是么?统一的 SQL 界面隐含了不同数据库之间的差异。开发人员不用天天为了各种数据库间 SQL 语法差异而努力奋战。也不用为了单引号、双引号、反引号在苦恼。因为 Zend_Db_Select 会处理这些。

又或者在一个很久以前写的已经关联了5个表的 SQL 语句中增加一个 left join。如何呢?不知道你有没有试过调试了半天,只是由于疏忽将新加入的 join 语句放在了 where 的后面?Zend_Db_Select 不需要你来考虑分解 SQL 语句把 join 语句放到合适的地方。只要在查询前的任何一个地方调用 $select->joinLeft(…) 问题解决了。Zend_Db_Select 会自己解决顺序问题,生成合法的 SQL 语句。

真正的高手一定会藐视上面的原因而拒绝使用 Zend_Db_Select 。因为他们永远不会遇到没有充裕时间学习的项目,或者需要使用不熟悉的数据库进行开发的项目。同时,他们也不会犯那种写错顺序的错误。因为,他们是高手。

但是,下面的原因似乎难以抗拒。

PHP 自身并没有一个健全的、统一的数据库接口。于是,当我们希望实现如 ORM 或 Data Table Gateway 这样的功能时,应该怎么做呢?没错,使用 PDO 或者 mysql、mysqli、oci8……自己来封装实现。嗯,嗯,我知道不少框架实现了很高级的数据库操作方式。但是只能用在 mysql ,或者很难移植到其他数据库。那么要给这些框架增加一个数据库支持呢?从头写吧,反正原理基本类似,换一换 SQL 语句,改一改功能实现……这样的程序健壮么?这样的数据库支持好么?或许用过一些其他数据库的朋友知道,不少框架在 mysql 上是龙,在其他数据库上是虫。

Zend_Db_Select 解决了这个问题,不需要再去管什么该死的引号,不用管分页查询是 TOP、LIMIT 还是BETWEEN row number。不论什么数据库,在 Zend_Db_Select 的写法是一致的。统一的 SQL 表达方式,换来的是更加内敛的数据库部件。开发 ORM 也好,开发 DTG 也罢,只要基于 Zend_Db_Select 的查询方式,就能保证在所有 Zend_Db_Adapter 支持的数据库上都可以用。开发人员可以更专注于数据库操作功能的实现,而不是 SQL 语句的兼容性问题。

当然了,有的高手也说过:这个内容,Db Driver 层就可以处理了何必要多搞出来一个 Db Select?不伦不类,不是多写几个 -> 就叫面向对象了。

Db Driver 或者叫 Db Adapter 可以来实现,这是没有错的,但是对于一些 ORM 或 DTG 不好实现或无法实现的功能,例如信息系统中最为常见的复杂报表、嵌套报表等又如何呢?手写 SQL 是吧?那又回到之前说过的那两个麻烦上面了。

哦,对不起,忘了,高手,高手是不会遇到这种问题的。

综上所述,Zend_Db_Select 并不是一些所谓的高手口中的鸡肋。其实是 Zend Db 的一个不可缺少的坚实基础。在这个基础之上可以由开发者自由发挥,而不需要过多关注实际的 SQL 书写规则。难道还有不使用它的理由么?

Comments

3 responses to “为什么我们需要 Zend_Db_Select”

  1. Jason Qi Avatar

    任何事情都有两方面,它肯定牺牲了效率。

  2. mikespook Avatar

    拿空间换时间,拿时间换空间,拿开发效率换执行效率,拿执行效率换开发效率……
    开发人员的修行之道啊 -_-!

  3. Noname Avatar
    Noname

    在中国,高手多如牛毛。所以,在中国,不需要Zend_Db_Select,只有在国外才需要。

Leave a Reply

Your email address will not be published. Required fields are marked *