2013-01-25 123 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,它運行良好,但它非常複雜。因此,我儘可能堅持正常的查詢。 :-) –