使用活动记录构建查询的利弊


Pros and cons of building queries with Active Record

我有这个查询,我想在我的PHP应用程序后端运行。从概念上讲,sheet是一个数据库,它跟踪我们拥有的所有sheet。purchase是一个数据库,它跟踪哪些用户访问了哪个表。我想要运行的查询是给定用户的id,我可以得到他们应该有权访问的所有表。查询形式:

select distinct s.wsid, s.name from sheets s, purchases p where 
s.wsid = p.wsid AND p.uid = *value*; 

其中value是应用程序输入的值

在我看来,有两种方法可以让它在后端工作。

1)

选项

public function getPurchasedSheets($uid){
    if( is_numeric($uid) ){ //check against injections
        $query = "select distinct s.wsid, s.name from sheets s, purchases p 
            where s.wsid = p.wsid AND p.uid = ".$uid.";" ;
        return $this->db->query($query);
    } else {
        return NULL; //or false not quite sure how typing works in PHP
    }
}
2)

选项

public function getPurchasedSheets($uid){
    if( is_numeric($uid) ){ 
        $this->db->select('wsid, name'); 
        $this->db->distinct();
        $this->db->from('purchases');
        //not sure which order the join works in...
        $this->db->join('sheets', 'sheets.wsid = purchases.wsid');
        $this->db->where('uid ='.$uid);
        return $this->db->get();
    } else {
        return NULL; 
    }
}

所有CodeIgniter活动记录命令的源代码:

codeigniter.com/user_guide/database/active_record.html

是否存在某种性能或安全性上的差异?第二种方法对我来说似乎更令人困惑。这有点复杂,因为我不确定如何在这种编码风格中进行引用消歧,因为purchase和sheets都有一个uid字段,但它们意味着不同的东西(除了首先不熟悉SQL join命令之外)。purchase中的Uid(用户id)表示用户购买了该工作表,而sheets中的Uid表示哪个用户拥有该工作表。

TL,DR:基本上,我想问的是,我是否有理由花时间去研究如何用选项2的方式做事?

主要优点是:

  • 从数据库引擎中抽象出来,由库来处理数据库特定的SQL语法差异。如果你曾经/想要更改您正在使用的数据库。在理论上,第二种形式应该仍然可以工作。
  • "活动记录"语法自动转义参数
  • 可读性,虽然这是个人喜好的问题。
顺便说一下,如果你在PHP 5环境中,库支持方法链:
if( is_numeric($uid) ){ 
        return $this->db->select('wsid, name')
                              ->distinct()
                              ->from('purchases')
                              ->join('sheets', 'sheets.wsid = purchases.wsid')
                              ->where('uid ='.$uid)
                              ->get();
                              // nb. didn't check your join() syntax, either :)
    }

可能跑题了:CodeIgniter的活动记录更像是一个查询生成器,而不是活动记录的实现。如果你想知道的话。当被视为查询生成器时,它更有意义;)顺便说一句,我很喜欢CodeIgniter。

查询绑定是最容易实现的,它做的事情和查询构建做的事情是一样的——而且不会像构建那样限制你。

$query = $this->db->query('SELECT something FROM table WHERE name1=? AND name2=?', array($name1, $name2);
$result = $query->result();
http://codeigniter.com/user_guide/database/queries.html