2012-09-06 4 views
0

임의의 ID를 만드는 함수를 작성했습니다 makeid(); ID가 고유한지 확인하기 위해 ID가 이미 존재하는지 확인하는 SQL 문이 있습니다.쿼리 결과에 따라 함수를 반복하는 방법

$does_id_exist = mysql_query("SELECT COUNT(*) AS count FROM signups WHERE affid='$affid'"); 
if(mysql_num_rows($does_id_exist) == 1) 
    { 
    #loop function and perform query again 
    } 
else 
    { 
    #insert record 
    } 

그래서 함수를 반복하는 데 문제가 있습니다. 함수 makeid()을 루프 처리하고 $does_id_exist 검사를 수행하여 각 ID이 고유한지 확인하십시오.

--UPDATE-- 명확하게 - 내 코드는 [email protected]과 같은 ID를 만듭니다.하지만이 ID를 사용자 레코드에 삽입하기 전에. 다른 사용자가 이미이 ID를 갖고 있는지 확인하기 만하면됩니다. 다른 사용자가이 ID를 가지고있는 경우 이벤트가 내 ID를 생성하기 위해 내 기능을 트리거해야합니다. WOW!29E3 그리고 다른 사용자가 인 을 가지지 않았는지 확인하기 위해 sql/query를 다시 확인하십시오. 실패하거나 끝나면 루프를 계속하고 ID를 사용할 수 있으면 INSERT합니다.

+2

항상 자동 증가 ID 필드를 사용하여 이것을 완전히 회피 할 수 있습니다. – andrewsi

+0

제휴 ID와 같은 것을 생성하기 때문에 위장 할 수 없습니다. 그것은 INT가 아닙니다 - 단어 + 임의의 숫자와 + 기호 – fyz

+0

심각한 SQL 주입 버그를 피하려면 [자리 표시 자] (http://bobby-tables.com/php)를 사용하여 SQL을 이스케이프 처리해야합니다. ** mysql_query는 구식이며 위험하기 때문에 새로운 응용 프로그램을 작성하고 있습니다 ** mysqli와 PDO는 훨씬 안전하고 적절하게 사용하기 쉽습니다. – tadman

답변

0

당신도 바로이 같은 기본 데이터베이스 테이블에 키 또는 무언가를 사용할 수 있습니다

<?php 
    // the id to insert 
    $newId = null; 

    // populate with results from a SELECT `aff_id` FROM `table` 
    $currentIds = array(); 

    // prepopulate 
    for($i=0; $i<100000; $i++) 
    { 
     $currentIds[] = "STRING_" + rand(); 
    } 

    // generate at least one id 
    do 
    { 
     $newId = "STRING_" + rand(); 
    } 
    // while the id is taken (cached in $currentIds) 
    while(in_array($newId, $currentIds)); 

    // when we get here, we have an id that's not taken. 
    echo $newId;  
?> 

출력 :

STRING_905649971 (실행 시간 95ms);

쿼리를 반복적으로 실행하지 않는 것이 좋습니다. 트래픽 볼륨이 충분히 높으면 삽입하기 전에 최종 점검을하는 것이 좋습니다.

+0

이것은 나를 위해 작동하지 않습니다. 내 코드는 * YES @ 281E *와 같은 ID를 만든다. 그러나이 ID를 사용자 레코드에 삽입하기 전에. 다른 사용자가 이미이 ID를 갖고 있는지 확인하기 만하면됩니다. 다른 사용자가이 ID를 가지고있는 경우, 새 ID * WOW! 29E3 *을 작성하기 위해 이벤트를 트리거해야하며 다른 사용자가 해당 ID를 가지고 있지 않은지 다시 확인하십시오. IF가 실패하면 계속 진행하거나 ID를 사용할 수 있으면 끝내고 INSERT하십시오. – fyz

+0

@FA '' '' '' '' '' '' '' ': 정확히 그것이하는 일입니다. '$ currentIds'를 현재의 id로 채우고, 현재 id가 현재의 id에 들어가는 동안 ('while') 새로운 것을 생성합니다 ('while'). 그런 다음 마지막 삽입을하기 전에 빠른'SELECT COUNT (*)'를 할 수 있으며 다른 누군가가 ID를 만들고'$ currentIds'에 캐시되지 않았 음을 주목합니다. – Josh

+0

나는 캐시 교정을위한 계산을 좋아하지만, 모든 ID를 이해할 수없는 배열로 가져올 수는 없습니다. 40,000 개가 넘는 ID가 있습니다 - 방금 생성 한 태그가 삽입되기 전에 생성되었는지 확인해야합니다. 답을 수정 해 주시겠습니까? – fyz

-1

아무런 행이 없다는 것을 알 필요가 없으므로 (ID가 고유해야하므로 0 또는 1이어야 함) DB가 행을 찾으면 여전히 전체 테이블을 검사합니다 계산하기. 1 행이 있다면 정말로 신경 써야합니다. 따라서 ID가 충분하고 충분할 행을 선택하십시오. rand()도 사용하지 않아야합니다. 이는 보는 것처럼 도움이되지 않으며 "무료 슬롯"을 찾기 전에 수행 할 수있는 루프 수를 예측할 수 없습니다. 날짜 접두어와 같이 예측 가능한 것을 사용하거나 접두어 이 매일 증가합니다. 데이터 세트를 좁히는 데 도움이되는 모든 것. 그러나 지금은 (의사!) :

$id = null; 
while($id == null) { 
    $newId = 'prefix' . rand(); 

    mysql_query("SELECT `affid` FROM `signups` WHERE `affid`='${newId}'"); 
    if(mysql_num_rows() == 0) { 
    $id = newId; 
    break; 
    } 
} 

일을 속도, 당신은 DB 색인 생성해야합니다.

편집 : 모든 캐시가 일을 빠르게하는 데 유용 할 것이라는 점에 동의합니다 (@Josh 예제를 기반으로 쉽게 추가 할 수 있음). 여전히 잘못된 장소에서 수정됩니다. 가능한 경우 ID를 생성하는 방법을 다시 생각해보십시오. 자동 증분 일 필요는 없지만 rand()보다 예측 가능한 것이 도움이됩니다. ID가 쉽게 기억할 필요가 없으며 순차적으로 보안을 염려 할 필요가없는 경우 10보다 다른 숫자로 숫자를 사용하십시오 (예 : 26을 사용하면 모든 숫자 + 문자를 사용하므로 PREFIX-AX3TK으로 끝나기 때문에 string 원하는대로 신속하게 다음 ID를 쉽게 생성 할 수 있습니다.

+0

매우 효율적인 권장 사항은 아닙니다. 그는 예제에서와 같이 촬영 된 ID를 배열에 미리 캐시해야하며 그의 사이트가 동시 ID가 생성 될만큼 많은 양인 경우에는 ID = $ NEW WHERE TABLE = WHERE TABLE을 사용하십시오. 그렇게하면 각 충돌마다 'N'이 아니라 단지 1-2 개의 쿼리가됩니다. – Josh

+0

확실히, 배열의 "캐시"는 아프지 않습니다. -1 주셔서 감사합니다. 아주 유치한. –

+0

@ '' '' '' '' '' '' '' '' '' ''나는 조쉬에게 가져갔습니다. 그리고 아니요, 저는이 질문에서 아무것도 다운 다운하지 않았기 때문에 당신은 저에게 맞지 않았습니다. –

관련 문제