2012-12-15 2 views
2

이 코드를 Kohana3 프레임 워크에서 작동시키는 방법은 무엇입니까? 구문 오류가 있습니다.Kohana3 프레임 워크를 사용하여 테이블에서 임의의 행 가져 오기 -

ORM::factory('table1') 
->where ('id', '=', ceil(DB::expr('rand()') * [SELECT max(id) from table1])) 
->find(); 

테이블에서 임의의 행을 선택하는 방법입니다.

이 있지만 큰 테이블, 작은 테이블 (즉, 1000 행보다 포함)에 대해 잘 작동 :

SELECT name 
    FROM table1 JOIN 
     (SELECT CEIL(RAND() * 
        (SELECT MAX(id) 
         FROM table1)) AS id 
     ) AS r2 
     USING (id); 
:

ORM::factory('table1') 
->order_by(DB::expr('RAND()')) 
->find(); 

내가 원하는 걸의 표준 MySQL의 동등한이 같은 것입니다

그래서, Kohana3 프레임 워크의 코드로 변환하는 방법은 무엇입니까?

P. 테이블에 구멍이 없거나 삭제 된 행이없는 경우이 방법을 사용하면 문제가 없어 내 경우에는 문제가되지 않습니다.

답변

2

당신이하려는 것은 정말로 MySQL의 문제입니다. 모든 크기 테이블에 대해 올바른 쿼리를 수행해야합니다. 보다 확장 성있는 구현은 PHP를 사용하여 최대 ID보다 작은 난수를 생성 한 다음이를 선택하는 것입니다.

가장 높은 ID 가져 오기 : 1 그래서 작동하는 LIMIT를 사용하여,

$rand_id = mt_rand(0, $max_id-1); 

을 다음 임의의 레코드를 선택하는 쿼리를 만들 :

PHP에서
SELECT MAX(id) max_id FROM table1 

선택하려면 "ID"를 얻을를 구멍이 있더라도.

SELECT * FROM table1 WHERE id>=$rand_id ORDER BY id LIMIT 1 

MySQL에서는이 모든 작업을 수행 할 수 있지만, DB 추상화 계층을 사용하여 읽거나 구현하기가 쉽지 않습니다.

+0

답변 해 주셔서 감사합니다. 나는 그것을 같은 방식으로했다. 당신의 대답은 내가 올바른 길을 가고 있다고 말한다. 유일한 차이점은 마지막 쿼리 문자열에 대한 것입니다. id> =를 사용하여 구멍을 덮는 것이 좋지 않은 것 같아요. 왜냐하면 당신이 순서 정렬을하려고하기 때문입니다. 그것은 큰 테이블을위한 sort_by의 낮은 성능에 대해 말하기 시작한 것입니다. 그래서 id> = 대신 id =를 사용하고 행이 있으면 나중에 확인하십시오. 그렇지 않은 경우 절차를 반복하십시오. 그렇게하면 값에 불규칙한 균일 분포가 생깁니다 (테이블에서 임의의 행을 선택하려고 할 때 프로그래머가 원하는 대부분의 값입니다). – Haradzieniec

+0

인덱스를 기준으로 정렬, 특히 기본 키 정렬은 매우 빠릅니다. 언제든지 ORDER BY를 삭제할 수 있습니다. 그런 다음 MySQL은 지정한 ID보다 큰 첫 번째 레코드를 반환합니다. 다음으로 높지는 않을 수도 있습니다. –

+0

네 말이 맞아. 감사. – Haradzieniec