2013-01-25 124 views
6

目前我使用笨定期查询,即:笨活动记录与定期查询

$sql = " 
    SELECT * 
    FROM my_table 
    WHERE item_id > 1 
";  
$q = $this->db->query($sql); 

我已经开始寻找到ActiveRecord的,它确实看起来不错,并有查询的优势,无论在建其中使用了数据库驱动程序 - 但是,我一般严格使用每个项目的单个数据库类型,所以这对我来说并不是真正的好处。

我发现在我看来,定期查询(如我在我的例子中)更具可读性并且更容易维护,所以我目前正在考虑与常规查询保持一致。

除了上面提到的原因,我应该选择哪个,以及原因是什么?

谢谢

+0

只要您发布问题,请接受您满意的答案。 –

+0

嗨拉希尔,我通常会在接受答案时接受答案。我不太确定哪一个可以接受,因为我没有真正回答我的问题。你建议我接受哪一个? –

+0

嗯,我建议@tomexsans更明智,所以我可以说他应该被接受。他对消耗内存是正确的还有一点需要注意的是,运行额外的php函数来构建查询会使进程变得缓慢不快 –

回答

7

很适合我,我更喜欢运行的常规查询,CI的活动记录要消耗多少内存。因为它会将所有结果加载到内存中。如果你明白我的意思。至于复杂性,最好定期查询,而不是坚持CI的活动记录组合。

+0

嗨tormexsans。谢谢。我仍然偏爱正常的查询。根据迄今的反应,我没有切实的理由。再次感谢。 –

+2

不好意思,已经过了一年多了,但我不明白为什么常规查询的结果没有加载到内存中......查询的结果保存在一个变量中,然后返回......我不明白为什么如果它是一个普通的查询,它不会被加载,你能解释一下吗? – Samuel

4

那么,我的主要原因是它的工作速度和安全性。因为它会自动转义值等。但是当涉及到复杂的查询时,我建议使用普通查询字符串。

(不谈论加入等等。因为笨支持它非常好,可读)更多类似支点查询的,或由ROWNUMBER选择(如下面)

$query = $this->db->query('SELECT * FROM 
    (SELECT @row := @row + 1 as row, t.* 
    FROM `default_red_albums` t, (SELECT @row := 0) r) AS view 
WHERE `row` IN(' . $in . ')'); 

return $query->result(); 
+0

谢谢,克里斯。我仍然不相信我想切换到活动记录。对于某些查询,我看不到具有ActiveRecord的逻辑,而对于其他查询则使用普通查询字符串。不一致对我来说是一个缺点。所以直到我读了一些清楚地告诉我为什么ActiveRecord更好的东西,我将坚持我正在做的 - 普通查询字符串。谢谢你的评论。 –

+0

那么,我正在使用这两个,只是试图让我的模型methodnames真正描述。例如:getRandomAlbums(),getRandomAlbumsByArtistIds(),checkAlbumIdExists()。如果这仍然不够,我建议去查询,因为我不能向你保证你不会偶然发现一些奇怪的查询。 –

5

好了,你是tireds简单quesries写选择等等等等,你可以改变你的风格有点使用活动记录,因为在编写定期查询时,你很可能会犯syntex错误。主动记录是为此目的而设计的,除非你是专家,否则你不需要编写通用的语法来指出犯错的几率。同时有效的记录也提供了逃逸设施。你并不熟悉他们(当简单的话)也是可读的活动记录。看看这个例子

$array = array(
     'user.username', 
     'user.email', 
     'user.password', 
     'other.blah', 
     'other.blah' 
); 
$where = array(
     'active' => 1, 
     'other'  => 'blahblah' 
); 

return $this->db 
     ->select($array) 
     ->from('user') 
     ->join('other','other.user_id = user.id','left') 
     ->where($where) 
     ->get() 
     ->result();  
+0

嗨Raheel,谢谢。我在写查询方面并不错,而且我还使用绑定参数来提高它们的安全性,并且由于它们对我来说使用普通查询更具可读性,所以我现在坚持:-) –

7

我倾向于更喜欢ActiveRecord。我发现它更具可读性,并且它使构建动态查询变得更加容易,因为您不必随意将原始SQL块一起串联起来。这意味着我可以添加各种条件到我的查询构建器中,只需要很少的大惊小怪,并且出来一些非常容易阅读的东西。

有一些事情CodeIgniter的ActiveRecord实现很不适合(并且让我错过Doctrine),并且我使用了直接的SQL,但它并不经常发生。

+0

谢谢,Freqout。我将为未来的项目考虑您的答案。 –

+0

嗨Frequot,我是Codeigniter框架中的Active Records的新手。我想知道一个活动记录是否支持动态模型类,我的意思是类似结构的教义? –

2

ActiveRecord并不总是以您想要的顺序产生您的查询,这可能会导致不可预知的结果。例如,这种模式:

 $this->db->select('page, content'); 
     $this->db->from('table'); 
     $array = array('title' => $searchq, 'content' => $searchq); 
     $this->db->or_like($array, 'both'); 
     $this->db->where('showsearch', 'Yes'); 
     return $this->db->count_all_results(); 

产生这个查询:

 SELECT COUNT(*) AS `numrows` 
     FROM (`table`) 
     WHERE `showsearch` = 'Yes' 
     AND `title` LIKE '%term%' 
     OR `content` LIKE '%term%' 

但我想在查询,这是年底做了showsearch检查为什么我把它放在那里的第一名。但ActiveRecord将它移动到查询的中间,我得到的结果不准确。

+0

这非常有趣。谢谢,@Kenzo。我自己也喜欢正常的问题,但我从来不知道这个问题。 –

2

使用对象模型进行查询有很大的好处。虽然您可以执行字符串解析和串联来构建多个函数的查询,但这非常耗时且极易出错。使用对象模型,您可以传递引用并继续构建查询,或在执行之前将其传递给预处理器。

一个人为的例子可能是自动添加日期过滤器到具有creation_date字段的表的所有查询。

CI还允许您将原始SQL与对象模型很好地混合。基本上,你构造了一个返回结果来保湿对象的自定义查询。

+0

Hi Rich。很好的答案;绝对不是我想到的。 –

5

差不多两年后,我发现了这个问题。我的一些同事已经回答了几个优点或缺点,我只是想通过我的个人经验添加一个意见:

正如有人所说,我也将使用活动记录和纯粹的直接sql混合起来用于非常复杂的查询,原因是当你需要一个接收很多os参数并相应地改变查询的方法时,它的使用非常简单。举例来说,我有一个接收的称为参数数组“选项”的方法:

if(!empty($options['login'])) 
{ 
    $this->db->where('tl.login', $options['login']); 
} 
if(!empty($options['ip'])) 
{ 
    $this->db->where('tl.ip', $options['ip']); 
} 
if(!empty($options['sucesso'])) 
{ 
    $this->db->where('tl.sucesso', $options['sucesso']); 
} 

if(isset($options['usuarios_existentes']) && $options['usuarios_existentes']) 
{ 
    $this->db->join('usuario u', 'tl.login = u.login'); 
} 
else 
{ 
    $this->db->join('usuario u', 'tl.login = u.login', 'LEFT'); 
} 

if(!empty($options['limit'])) 
{ 
    $this->db->limit($options['limit']); 
} 
else 
{ 
    $this->db->limit(50); 
} 

return $this->db->select('tl.id_tentativa_login, tl.login, DATE_FORMAT(tl.data, "%d/%m/%Y %H:%i:%s") as data, tl.ip, tl.sucesso', FALSE) 
       ->from('logs.tentativa_login tl') 
       ->order_by('tl.data', 'DESC') 
       ->get()->result(); 

当然这只是一个简单的例子,但我已经建造方法与数百行和条件可能会改变一个通用的' get'方法,并且活动记录使其非常好,并且非常易读,因为您不需要在其中间编写代码来正确地格式化查询。

你甚至可以有连接和其他可以有条件的东西,所以你可以使用一个通用的集中式方法,这样可以避免重写大部分代码和复制部分代码(可怕的维护),它不仅可读,但它让你的查询速度快,因为只加载你所需要的:

if(!empty($opcoes['com_maquina'])) 
{ 
    if(strtoupper($opcoes['com_maquina'])=='SIM') 
    { 
     $this->db->join('maquina m', 'm.id_local = l.id_local'); 
    } 
    elseif(strtoupper($opcoes['com_maquina'])=='NAO') 
    { 
     $this->db->join('maquina m', 'm.id_local = l.id_local', 'LEFT'); 
     $this->db->where('m.id_maquina IS NULL'); 
    } 
} 

换个好点的ActiveRecord的是,它接受纯粹的SQL语句中的一样,子查询和其他的东西,所以你可以使用它作为你请。

我在谈论优点,但是,显而易见的是,纯SQL总是会执行得更快,并且不会有调用函数的开销。但要说实话,在大多数情况下,php解析器会做得太快以至于不会以一种富有表现力的方式影响最终结果,并且如果您必须制作大量手动条件,则代码可能与主动记录一样慢无论如何,解析器。

请注意,有时activerecord查询不会按照您期望的方式工作,因为它会尝试以编程的逻辑方式构建查询,所以在使用'OR'语句时要小心,大多数时间你必须隔离它(和):

$this->db->where('(m.ultimo_status < DATE_ADD(NOW(), INTERVAL -2 HOUR) OR m.ultimo_status IS NULL)'); 

如果你没有添加(),OR的状态会影响整个where子句。 因此,一旦你习惯了主动记录,它可以帮助很多人,并且仍然可以快速和可读的查询。

+0

嗨卢西亚诺,谢谢你的回答。我很欣赏你为此所做的时间。由于这是过去的事情,我使用了更多的ActiveRecord,它运行良好,但它非常复杂。因此,我尽可能坚持正常的查询。 :-) –