2011-01-10 15 views
6

Tại sao học thuyết (1.2) sử dụng WHERE IN thay vì LIMIT?Tại sao học thuyết sử dụng WHERE IN thay vì LIMIT?

Mã này:

Doctrine_Query::create() 
    ->from('Table t') 
    ->limit(10) 
    ->getSqlQuery(); 

Returns một cái gì đó như thế này:

SELECT t.id_table AS t__id_table FROM table AS t WHERE t__id_table IN (1,2,3,4,10,12,18,20,21,25); 

Thay vì điều này:

SELECT t.id_table AS t__id_table FROM table AS t LIMIT 10; 

behaivor Đây là cùng một giá trị cho bất kỳ LIMIT. Điều này tạo ra một truy vấn rất dài cho các giá trị cao LIMIT.

Câu hỏi thưởng: Doctrine biết, sử dụng id nào? (Bằng cách gửi một truy vấn khác tới DB ??)

+0

Bạn đang sử dụng chương trình phụ trợ cơ sở dữ liệu nào? –

+0

@Matt Gibson: MySQL –

+0

Odd; Tôi vừa làm một cái gì đó tương tự với Doctrine của Symfony 1.4, mà tôi _think_ là phiên bản 1.2.3, và nó sử dụng mệnh đề LIMIT cho MySQL, như bạn mong đợi. –

Trả lời

4

Đó là vì LIMIT hoạt động trên các hàng cơ sở dữ liệu không phải là "đối tượng". Khi bạn nhập $q->limit(10) bạn muốn nhận mười đối tượng, không phải mười hàng từ cơ sở dữ liệu.

xem xét sau đây truy vấn (sản phẩm và loại có nhiều-nhiều mối quan hệ):

SELECT p.*, c.* FROM product p 
INNER JOIN product_category_ref pcr ON p.id = pcr.prodcut_id 
INNER JOIN category c ON c.id = pcr.category_id 
WHERE p.price < 123; 

Để lấy 10 sản phẩm (đối tượng) truy vấn của bạn sẽ phải lấy ít nhất 20 dòng. Bạn không thể sử dụng nguyên nhân LIMIT 10 (ví dụ: chỉ) 3 sản phẩm sẽ được trả lại. Đó là lý do tại sao bạn cần tìm ra sản phẩm nào sẽ được tìm nạp (giới hạn áp dụng cho sản phẩm) và sau đó tìm nạp dữ liệu thực tế.

Điều đó sẽ dẫn đến truy vấn sau đây:

SELECT p.id FROM product p WHERE p.price < 123; 
SELECT ..... WHERE p.id IN (...); 

truy vấn thứ hai có thể trở lại 20, 423 hoặc 31 hàng. Như bạn có thể thấy đó không phải là giá trị từ limit().

PS. Doctrine2 rõ ràng hơn nhiều trong trường hợp đó vì nó sử dụng phương thức setMaxResults() thay vì limit(), điều này ít gây nhầm lẫn hơn.

+0

bạn nhận thông tin này từ đâu? theo giới hạn thủ công() là một phần của DQL và được sử dụng trước khi hydrat hóa –

+0

Tôi biết rằng từ sự tận tụy và nghiên cứu các nguồn của riêng tôi. Và có, bạn đúng - 'LIMIT' là một phần của phương thức DQL (' limit() 'xuất phát từ' QueryBuilder') và bạn có thể thấy nó được sử dụng trước khi hydrat hóa (truy vấn thứ hai (truy vấn thực sự ngậm nước) không thậm chí không có mệnh đề 'LIMIT')). – Crozin

+0

Điều này nghe có vẻ kỳ lạ đối với tôi. Tôi (và các đồng nghiệp của tôi) nghĩ rằng LIMIT được áp dụng cho số hàng được trả về bởi truy vấn (sau khi xử lý tất cả các phép nối, truy vấn con, v.v.). –

0

Sử dụng Học thuyết 1.2.3:

<?php 

include(dirname(__FILE__).'/Doctrine.php'); 
spl_autoload_register(array('Doctrine', 'autoload')); 

$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'testdb', 'testdb'); 
$conn = Doctrine_Manager::connection($dbh); 

class Table extends Doctrine_Record { 
    public function setTableDefinition() { 
    $this->hasColumn('id_table', integer, 10, array('primary' => true)); 
    } 
} 

$q = Doctrine_Query::create() 
    ->from('Table t') 
    ->limit(10) 
    ->getSqlQuery(); 

echo $q; 

tôi nhận được kết quả:

SELECT t.id_table AS t__id_table FROM table t LIMIT 10 

Có lẽ cái gì khác đang xảy ra trong mã của bạn?

+0

Chúng tôi chỉ biết rằng WHERE IN chỉ được sử dụng khi sử dụng JOIN. Xin lỗi vì đã gây nhầm lẫn. –