2010-01-05 2 views
3

저는 PHP와 MySQL을 사용하고 있습니다. 저는 3 개의 필드 ((ID, , PID)를 가진 테이블을 가지고 있습니다.8 개의 임의 문자로 된 고유 한 문자열 삽입

PID 필드에 8 개의 고유 한 문자로 구성된 문자열을 포함 시키길 원합니다.

내 솔루션은 PHP에서 임의의 문자열을 생성하고 존재하는지 확인하는 것입니다. 존재하면 다른 문자열을 생성합니다.

MySQL 트리거 등의 처리 시간을 절약 할 수있는 더 좋은 솔루션이 있습니까?

답변

1

이 당신에게 임의의 8 문자열 줄 것이다 :

substr(str_pad(dechex(mt_rand()), 8, '0', STR_PAD_LEFT), -8); 

는 여기에서 찾을 : 사용자 이름 필드에 고유 한 경우

또는 http://www.richardlord.net/blog/php-password-security 당신은 또한 사용할 수 있습니다

substr(md5('username value'), 0, 8); 

는 비록 특히 md5의 경우는 거의 없습니다. 어느 경우에도 고유 한 문자열이 보장되지 않으므로 다음과 같이 처리 할 것입니다.

// Handle user registration or whatever... 

function generatePID($sUsername) { 
    return substr(md5($sUsername), 0, 8); 
} 

$bUnique = false; 
$iAttempts = 0; 

while (!$bUnique && $iAttempts < 10) { 
    $aCheck = $oDB->findByPID(generatePID("username value")); // Query the database for a PID matching whats generated 
    if (!$aCheck) { // If nothing is found, exit the loop 
     $bUnique = true; 
    } else { 
     $iAttempts++; 
    } 
} 

// Save PID and such... 

... 아마 유일한 '확인'쿼리를 내고, 어쩌면 고유 한 경우 2 개가 생겨 고유 한 문자열을 보장합니다.

+0

PHP를 생성하고 데이터베이스가 존재하는지 확인하기 위해 루프를 생성하는 최선의 방법. 일부 magin mysql 문에서이를 수행 할 수있는 방법을 찾을 수 있다고 생각했습니다. – trrrrrrm

+0

아니요. 고유하지 않은 값을 삽입하려고 시도 할 때 실패하는 PID 필드에 고유 키가 있어야합니다.이 값은 무언가가 성공적으로 삽입 될 때까지 루프를 계속 실행하려고 시도하는 또 다른 옵션을 제공합니다. 나는 당신이 이미지 갤러리를하고있는 것을보고 우리는 실제로 항상 현재 시간 + 파일 이름의 md5를 저장하고 그 파일 확장자를 '파일'필드에 나타냅니다.이 필드는 항상 고유 한 문자열을 얻습니다. 약 8 년 만에 문제가 발생하지 않았습니다. 필드는 32 문자 + 확장 길이를 허용해야합니다 - 우리는 보통 50으로 붙어 있습니다. –

0

문자가 랜덤해야합니까? 아니면 그냥 독특한거야? 고유해야 할 필요가있는 경우 타임 스탬프를 사용할 수 있습니다. 값을 제 시간에 맞추면 독창성이 보장됩니다.

다른 경로로 이동하는 경우 고유 한 값이 될 때까지 생성 된 값을 데이터베이스와 비교해야합니다.

+0

가주의 : 두 개의 레코드가 서로의 초 이내에 추가하는 경우의 MySQL의 타임 스탬프와 함께 그들은 같은 타임 스탬프가있을 수 있습니다. –

+0

Alex, 가능한 경우 밀리 초 단위로 기본 설정하십시오. – Sampson

0

항상 올바른 방법으로 UUID (별명은 GUID)를 사용하지 마십시오.이 UUID는 항상 고유하며 필요 여부를 확인할 필요가 없습니다. 36 문자가 될 수 있지만, 표준 CHAR 데이터보다 디스크 공간을 절약하고 속도를 향상시키는 16 진수로 저장하는 이점이 있습니다.

PHP doc for functions that do this에 대한 의견을 읽을 수 있습니다.

-1

PID 값으로 8 자로 설정 한 경우 문자열을 생성하고 이미 존재하지 않는지 확인해야합니다.

$alphabet = range('A','Z'); 

// get all the PIDs from the database 
$sql = "select PID from mytable"; 

// save those all to an array 
$pid_array = results of query saved to array 

shuffle($alphabet); 
$pid_offer = array_slice($alphabet,0,8); 

while(in_array($pid_offer, $pid_array)){ 
    shuffle($alphabet); 
    $pid_offer = array_slice($alphabet,0,8); 
} 

// found uniuqe $pid_offer... 

경쟁 조건이 여전히 존재한다. 문자열을 무작위로 할 필요가없는 경우

, 다음 아마 자동 증가 정수 ID 값을 사용하고 그 다음 10000000

단지 할 수있는 간단한 A = 1에 해당에 대한 카운트를 시작합니다 , B = 2, C = 3 등 숫자를 대체하여 문자열을 생성합니다.

귀하의 마일리지는 다를 수 있습니다.

--Mark이

+0

나중에 그것은 무작위로해야합니다. 솔루션에 감사하지만 mysql 트리거에서 수행 할 수 있습니까? 또는 sth 그런? 처리 시간을 절약 할 수 있습니까? 안 그래? – trrrrrrm

+0

ok, 위의 코드 솔루션을 사용하면 원하는 임의성을 얻을 수 있습니다. 경합 조건을 피하기 위해 md5 (microtime (true). $ origfilename) 파일을 저장할 수 있습니다. 그런 다음 새 이미지 디렉토리를 통해 적절한 파일 이름을 제공하고 데이터베이스를 PID 값으로 업데이트하며 이미지가 처리되고 볼 준비가되었음을 사용자에게 알리는 별도의 cron 프로세스를 갖습니다. 그냥 생각해보십시오. –

+0

또한 PID 값에 허용되지 않아야하는 문자열 목록을 개발해야합니다. 외설물 등. 그런 다음 삽입하기 전에 해당 목록에 대해 $ pid_offer 값을 필터링하십시오. 8 개 이하의 문자로 철자가 될 수있는 부적절한 단어가 많이 있습니다! –

0

당신은 같은 방법으로 8 개 문자를 MySQL의 독특한 캐릭터를 만들 수 있습니다

CAST(MD5(RAND()) as CHAR(8)) 
0

내 솔루션은 PHP에서 임의의 문자열을 생성하고 존재하는 경우 확인하는 것입니다. 존재하면 다른 문자열을 생성합니다.

잘못된 방법입니다. 웹 서버는 코드의 여러 인스턴스를 동시에 실행하고 조만간 두 인스턴스 에 데이터베이스에 동일한 PID을 저장합니다.

이 문제를 해결하는 올바른 방법은 PIDUNIQUE을 작성하고 사전 점검에 신경 쓰지 않는 것입니다. INSERT 쿼리를 실행하고 결과를 확인하십시오.

결과가 1062 (ER_DUP_ENTRY) 오류 인 경우 새 PID을 생성하고 다시 시도하십시오.

다른 데이터베이스 오류는 평상시처럼 처리해야합니다. 이 (안된) 같은

아마 뭔가 :

<?php 

/* $link = MySQLi connection */ 

if (!($stmt = mysqli_prepare ('INSERT `t` (`ID`, `Username`, `PID`) VALUES (?, ?, ?)'))) { 
    /* Prepare error */ 
} 
if (!mysqli_bind_param ('iss', $id, $user, $pid) { 
    /* Bind error */ 
} 

$e = 0; 

for ($i = 0; $i < 10; $i++) { 
    $pid = /* generate random string */; 
    if (mysqli_stmt_execute ($stmt)) 
     break; /* success */ 
    $e = mysqli_stmt_errno ($stmt); 
    if ($e !== 1062) 
     break; /* other error */ 
} 
mysqli_stmt_close ($stmt); 

if ($e) { 
    if ($e === 1062) { 
     /* Failed to generate unique PID */ 
    } else { 
     /* Other database error */ 
    } 
} else { 
    /* success */ 
} 
관련 문제