2013-01-25 34 views
6

Hiện nay tôi sử dụng CodeIgniter với các truy vấn thường xuyên, ví dụ:CodeIgniter Active Record vs truy vấn thường xuyên

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

Tôi đã bắt đầu nhìn vào ActiveRecord, và nó trông tốt đẹp, và có lợi thế của truy vấn được xây dựng không phân biệt trong đó trình điều khiển cơ sở dữ liệu được sử dụng - tuy nhiên, tôi sử dụng đúng một kiểu cơ sở dữ liệu duy nhất cho mỗi dự án nói chung, vì vậy đây không thực sự là một lợi ích cho tôi.

Tôi nhận thấy rằng các truy vấn thông thường (như tôi có trong ví dụ của tôi) dễ đọc hơn và được duy trì dễ dàng hơn theo ý kiến ​​của tôi, vì vậy tôi hiện đang nghĩ đến việc giữ các truy vấn thông thường.

Bên cạnh những lý do được đề cập ở trên, tôi nên chọn lý do nào và vì lý do nào?

Cảm ơn bạn

+0

vui lòng bất cứ khi nào bạn đăng câu hỏi, chấp nhận câu trả lời thỏa mãn bạn. –

+0

Hi Raheel, tôi thường chấp nhận câu trả lời khi có câu trả lời để chấp nhận. Tôi không hoàn toàn chắc chắn cái nào để chấp nhận, vì không ai thực sự trả lời câu hỏi của tôi theo ý thích của tôi. Bạn đề nghị tôi chấp nhận cái nào? –

+0

Tôi đề nghị @tomexsans hợp lý hơn nên tôi có thể nói rằng anh ấy nên được chấp nhận. Ông là đúng về tiêu thụ bộ nhớ cũng là một điểm cần lưu ý là chạy thêm chức năng php để xây dựng truy vấn làm cho quá trình chậm không nhanh –

Trả lời

7

tốt cho tôi tôi thích chạy truy vấn thông thường, hồ sơ hoạt động của CI tiêu thụ nhiều bộ nhớ. bởi vì nó sẽ tải tất cả kết quả trong bộ nhớ. Nếu bạn biết ý tôi là gì. Về tính phức tạp, tốt hơn là nên truy vấn thông thường thay vì gắn vào sytax ghi lại hoạt động của CI.

+0

Chào tormexsans. Cảm ơn. Tôi vẫn ưu tiên các truy vấn thông thường. Dựa trên các phản ứng cho đến nay, không có lý do thực sự cho tôi để chuyển đổi. Cảm ơn một lần nữa. –

+2

xin lỗi, đã hơn một năm, nhưng tôi không hiểu tại sao kết quả truy vấn thông thường không được tải trong bộ nhớ ... kết quả của truy vấn được lưu trong biến và sau đó được trả về ... Tôi không hiểu tại sao không được tải nếu nó là một truy vấn thông thường, bạn có thể giải thích rằng xin vui lòng? – Samuel

4

Vâng, lý do chính của tôi là nó hoạt động nhanh và an toàn. Kể từ khi nó tự động thoát khỏi giá trị vv Nhưng khi nói đến truy vấn phức tạp của tôi đề nghị sử dụng một chuỗi truy vấn bình thường.

(không nói về tham gia vv Vì CodeIgniter hỗ trợ nó khá tốt và có thể đọc được) Giống như trục truy vấn, hoặc lựa chọn bởi rownumber (như bên dưới)

$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

Cảm ơn, Chris. Tôi vẫn chưa tin rằng tôi muốn chuyển sang bản ghi hoạt động.Tôi không thể thấy logic trong việc có ActiveRecord đối với một số truy vấn và các chuỗi truy vấn thông thường cho các truy vấn khác. Sự mâu thuẫn này là một trở ngại đối với tôi. Vì vậy, cho đến khi tôi đọc một cái gì đó rõ ràng chỉ cho tôi lý do tại sao ActiveRecord là tốt hơn, tôi sẽ gắn bó với những gì tôi đang làm - chuỗi truy vấn bình thường. Cám ơn bạn đã góp ý. –

+0

Vâng, tôi đang sử dụng cả hai và chỉ cố gắng làm cho tên của mô hình của tôi thực sự mô tả. Ví dụ: getRandomAlbums(), getRandomAlbumsByArtistIds(), checkAlbumIdExists(). Nếu điều đó vẫn chưa đủ, tôi khuyên bạn nên truy vấn, vì tôi không thể đảm bảo với bạn rằng bạn không vấp phải một số truy vấn lạ. –

5

Vâng cho quesries đơn giản bạn đang ở đâu tireds của bằng văn bản SELECT blah blah bạn có thể thay đổi phong cách của bạn một chút bằng cách sử dụng hồ sơ hoạt động bởi vì trong khi viết một truy vấn thường xuyên có nhiều cơ hội mà bạn có thể làm cho một lỗi syntex. Hồ sơ hoạt động được thiết kế cho mục đích này mà bạn không cần phải viết cú pháp usuall nơi mà cơ hội làm sai là cao, trừ khi bạn là một chuyên gia. Ngoài ra hồ sơ hoạt động cho cơ sở thoát. Bạn không quen thuộc với hồ sơ hoạt động mà họ đang (khi đơn giản) có thể đọc được quá. Hãy xem ví dụ này

$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

Xin chào Raheel, cảm ơn. Tôi không tệ khi viết các truy vấn, và tôi cũng sử dụng các tham số ràng buộc để làm cho chúng an toàn hơn, và bởi vì chúng dễ đọc hơn đối với tôi khi sử dụng các truy vấn bình thường, tôi sẽ dính vào đó ngay bây giờ :-) –

7

Tôi có xu hướng thích ActiveRecord nhiều nhất. Tôi tìm thấy nó dễ đọc hơn và nó làm cho việc xây dựng các truy vấn động dễ dàng hơn nhiều vì bạn không phải khỉ xung quanh với các đoạn kết nối SQL thô rõ ràng với nhau. Điều này có nghĩa là tôi có thể thêm tất cả các loại điều kiện vào trình tạo truy vấn của mình với rất ít phiền toái và xuất hiện với một thứ rất dễ đọc.

Có một số điều mà việc triển khai CodeIgniter của ActiveRecord rất kém (và làm cho tôi bỏ qua Doctrine) và tôi sử dụng SQL thẳng cho điều đó nhưng nó không xảy ra quá thường xuyên.

+0

Cảm ơn, Freqout. Tôi sẽ ghi nhớ câu trả lời của bạn cho các dự án trong tương lai. –

+0

Hi Frequot, tôi mới sử dụng Active Records trong khuôn khổ Codeigniter. Tôi muốn biết một hồ sơ hoạt động sẽ hỗ trợ các lớp mô hình động mà tôi có nghĩa là Doctrine như cấu trúc? –

2

ActiveRecord không phải lúc nào cũng tạo truy vấn theo thứ tự bạn muốn, điều này có thể dẫn đến kết quả không thể đoán trước. Ví dụ, mô hình này:

 $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(); 

tạo truy vấn này:

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

Nhưng tôi muốn kiểm tra cho showsearch để được thực hiện ở phần cuối của các truy vấn, đó là lý do tôi đặt nó ở đó trong địa điểm đầu tiên. Nhưng ActiveRecord di chuyển nó đến giữa truy vấn và tôi nhận được kết quả không chính xác.

+0

Điều này rất thú vị. Cảm ơn, @Kenzo. Tôi cũng ủng hộ các truy vấn bình thường, nhưng tôi chưa bao giờ biết về điểm đặc biệt này. –

2

Có một lợi ích to lớn khi sử dụng mô hình đối tượng cho các truy vấn.Trong khi bạn có thể thực hiện phân tích cú pháp chuỗi và ghép nối để xây dựng một truy vấn trên một số hàm, thì đây là thời gian và rất dễ bị lỗi. Với một mô hình đối tượng, bạn có thể chuyển cùng một tham chiếu và tiếp tục xây dựng truy vấn hoặc chuyển nó tới các bộ xử lý trước trước khi thực thi.

Ví dụ có thể giả mạo có thể là tự động thêm bộ lọc ngày vào tất cả các truy vấn cho các bảng có trường tạo_dùng.

CI cũng cho phép bạn kết hợp SQL thô với mô hình đối tượng khá tốt. Về cơ bản, bạn xây dựng một truy vấn tùy chỉnh trả về kết quả để hydrate các đối tượng.

+0

Xin chào. Câu trả lời hay; chắc chắn không phải thứ tôi đã nghĩ đến. –

5

Gần hai năm sau, tôi đã tìm thấy câu hỏi này. Một số đồng nghiệp của tôi đã trả lời với một số ưu điểm hoặc nhược điểm, tôi chỉ muốn thêm một ý kiến ​​bởi kinh nghiệm cá nhân của tôi:

Như đã nói, tôi cũng trộn lẫn một số lần truy vấn , lý do là nó rất đơn giản để sử dụng nó khi bạn cần một phương thức nhận được rất nhiều tham số os và thay đổi truy vấn cho phù hợp. Ví dụ, tôi có một phương pháp tiếp nhận một loạt các thông số gọi là 'lựa chọn':

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(); 

Tất nhiên nó chỉ là một ví dụ đơn giản, nhưng tôi đã xây dựng các phương pháp với hàng trăm đường dây và điều kiện mà có thể thay đổi một chung ' có được 'phương pháp, và hồ sơ hoạt động làm cho nó thực sự tốt đẹp và rất dễ đọc vì bạn không cần phải viết mã ở giữa của nó để định dạng truy vấn đúng.

Bạn thậm chí có thể tham gia và các nội dung khác có thể có điều kiện. Vì vậy, bạn có thể sử dụng phương pháp tập trung chung, bằng cách tránh viết lại hầu hết mã và sao chép các phần của nó (khủng khiếp để bảo trì). , nhưng nó vẫn không ngừng truy vấn của bạn nhanh chóng vì chỉ tải những gì bạn cần:

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'); 
    } 
} 

Một điểm tốt cho activerecord, là nó chấp nhận SQL tinh khiết trong các báo cáo, như truy vấn con và các công cụ khác, vì vậy bạn có thể sử dụng nó như bạn xin vui lòng.

Tôi đang nói về những lợi thế, tuy nhiên, rõ ràng là SQL thuần túy sẽ luôn được thực hiện nhanh hơn và sẽ không có chức năng gọi điện. nhưng để nói sự thật, trong hầu hết các trường hợp, trình phân tích cú pháp php sẽ làm điều đó nhanh đến nỗi nó sẽ không ảnh hưởng đến kết quả cuối cùng theo cách biểu cảm, và nếu bạn phải thực hiện rất nhiều điều kiện thủ công, mã của bạn có thể chậm như activerecord phân tích cú pháp anyway. Chỉ cần lưu ý rằng đôi khi truy vấn activerecord sẽ không hoạt động theo cách bạn mong đợi, bởi vì nó cố gắng xây dựng truy vấn một cách hợp lý mà nó đã được lập trình để làm, vì vậy hãy cẩn thận khi sử dụng câu lệnh 'OR', ví dụ, thời gian bạn phải cách ly nó (và):

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

Nếu bạn không thêm dấu(), thì nguyên tắc OR sẽ ảnh hưởng đến toàn bộ mệnh đề where. Vì vậy, một khi bạn đã quen với activerecord, nó có thể giúp rất nhiều và vẫn thực hiện các truy vấn nhanh và dễ đọc.

+0

Xin chào Luciano, cảm ơn câu trả lời của bạn. Tôi đánh giá cao thời gian bạn đã thực hiện cho việc này. Vì quá khứ này đã được thực hiện, tôi đã sử dụng ActiveRecord nhiều hơn một chút, và nó hoạt động tốt, nhưng nó rất phức tạp để đọc. Tôi do đó gắn bó với các truy vấn thông thường khi có thể. :-) –

Các vấn đề liên quan