【问题标题】:What is the best approach to handling db queries处理数据库查询的最佳方法是什么
【发布时间】:2011-01-17 14:46:56
【问题描述】:

我确定我目前正在做的事情不是最佳的,但我真的很想听听一些关于如何处理 Web 应用程序上的所有数据库查询(包括连接字符串)的意见。

目前,我有一个 classes 目录,其中每个类都有一个文件,我还有另一个名为 db 的目录,其中包括一个 conn.php,其中包含连接字符串和 db 上的其他文件目录类似于classes 目录,每个类一个,但用于处理mysql查询。

所以基本上我将每个类的所有 db 查询都放在一个文件中,每当我需要从类文件中查询某些内容时,我都会调用 db 文件上的函数

我将每个 db 文件包含在相应的 db 文件中,例如在 user.class.php 文件中您会找到 include('db/user.db.php')

另外,我将conn.php 文件包含到每个数据库文件中。

user.class.php:

include('db/user.db.php');
class User {
    public $fname;
    public $userid;

    function __construct($userid) {
        $this->user_id = $userid;
        $this->fname = DB_GetFirstName($userid);
        }
}

user.db.php:

include('conn.php');
function DB_GetFirstName($userid) {
    $result = mysql_fetch_array(mysql_query("SELECT USR_FName FROM users WHERE USR_ID = '$userid'"));
    return $result[0];
}

conn.php:

$conn = mysql_connect("localhost", "user", "pass");
mysql_select_db("dbname", $conn);

你是怎么处理的?

【问题讨论】:

  • 听起来不错。您正在将 Db Access 从您的域类中分离出来。那你怎么把它放在一起?你能从你的 User 和 UserDb 类中展示一些 sn-ps 吗?
  • 添加了一些sn-ps,对我来说看起来不太优雅。我还被告知我应该为每个查询打开一个到数据库的连接,这是为什么呢?

标签: php mysql database database-design


【解决方案1】:

使用Database Abstraction Layer。只要您验证输入并防止注入攻击,您所做的听起来似乎比原始 SQL 行更好。

流行的 PHP 框架,例如 Doctrine2 have built-in database abstraction layers,已经受到公众的审查,并涵盖了很多您最终可能会自己做的事情。

我建议在创建自己的之前使用上述开源层,因为已经为您制作了非常可靠的代码库。不要重新发明轮子。如果您发现不足之处,请考虑改进项目。

【讨论】:

  • 我做的项目越多,我就越能得出这样的结论:数据库抽象层(大部分时间)毫无意义。当然,与学习所有现有的数据库供应商扩展相比,只需要学习一个 API 是很方便的。但话又说回来,它们也不难弄清楚,而且通常提供更大的灵活性。而且我从来不需要改变实际的数据库,所以这个参数不算数。
  • 我最近不得不更改我的数据库(Oracle 收购了 MySQL,更改了再分发许可条款),当我迁移到 postgres 时,DBAL 真的救了我。 DBAL 可以增加复杂性,并且确实感觉像是在训练轮子。然而,我并不孤单,我觉得它们为您节省的比花费的更多,尤其是当您考虑到安全性、灵活性和 DRY 时。
  • 我想这取决于您需要多少数据库供应商特定的代码功能。在一个项目中,我们不得不在查询中塞入大量特定于 Oracle 的 SQL,以至于选择 DAL 与数据库一起工作基本上没有任何意义。又因为他们付了天知道多少钱买了牌照,所以也不会很快变。在那个项目中,我们只是让数据库访问速度变慢了一点,几乎没有获得任何优势。应该直接使用 OCI 扩展。
【解决方案2】:

通过将域层与数据库访问层分开,您已经在做正确的事情。但是你把它放在一起的方式可以改进。看看Table Data Gateway (TDG) 模式。

在表数据网关模式中,一个类封装了对特定表的所有访问。这有点像您的 User.Db.php,不同之处在于 TDG 是一个实际的类。您将任何相关的数据库访问分组到该特定类中,而不是一堆函数。这样做的直接好处是,您可以将实例传递给任何需要它的类,而不是将函数调用硬编码到其中。

当您需要使用特定表时,您可以使用 TDG 从中获取/修改行。然后,您可以使用返回的记录集。或者使用DataMapper 将记录集中的数据映射到您的域类,例如你的用户类。对于简单的 DataMappers,自己制作就可以了。一旦变得更复杂,您最好使用现有的 ORM。

TDG 的替代方案是Row Data Gateway pattern

有一个很好的 TDG 介绍(带有 Zend 框架示例)在

对于行数据网关

【讨论】:

    【解决方案3】:

    对于小型项目,我使用非常简单的 php 类 http://code.google.com/p/edb-php-class/

    $result = $db->q("select * from `users`limit 3");
    
    foreach($result as $a){
            echo $a['name'].' '.$a['surname'].' '.$a['email'].' '.$a['country'].'</br>';
    }
    

    为了更大的使用数据库抽象层。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 2018-08-30
      相关资源
      最近更新 更多