2010-03-18 8 views
0

그래서 몇 개의 간단한 열, 자동 증가 및 해시 (varchar, UNIQUE)가있는 mysql 테이블을 상상해보십시오.MySQL 고유 한 해시 삽입

mysql에 열을 추가하고 다중 쿼리없이 고유 한 해시를 생성하는 쿼리를 제공 할 수 있습니까?

현재이 문제를 해결하기 위해 생각할 수있는 유일한 방법은 당분간입니다. DB에 더 많은 항목이있을수록 프로세서 집약적으로 될 것이라고 걱정합니다.

여기에 분명히 검증되지 않은 일부 의사 PHP,하지만에 걸쳐 일반적인 생각을 가져옵니다 위의 예에서, 해시 열이 UNIQUE 것

while(!query("INSERT INTO table (hash) VALUES (".generate_hash().");")){ 
    //found conflict, try again. 
} 

, 그래서 쿼리가 실패합니다. 문제는 db에 500,000 개의 항목이 있고 base36 해시 생성기에서 4 개의 문자로 작업하고 있다고 가정 해 보겠습니다. 갈등의 가능성은 3 분의 1에 가까워 질 것입니다. 따라서 160,000 개의 쿼리를 실행할 수는 없습니다. 사실, 5 세 이상은 받아 들일 수 없다고 생각합니다.

그래서 순수 SQL로이 작업을 수행 할 수 있습니까? base62, 6 char 문자열 (예 : "j8Du7X", chars a-z, A-Z 및 0-9)을 생성하고 last_insert_id를 업데이트하거나 삽입하는 동안 생성하십시오.

MySQL을 사용하여 기본 CRUD를 처리 할 수 ​​있지만 JOIN도 MySQL의 안락 영역 밖에 있지 않으므로 이것이 케이크 인 경우 내 무지를 용서하십시오.

아이디어가 있으십니까? 순수한 MySQL 또는 PHP & MySQL을 사용하는 것을 선호하지만 지옥, 만약 다른 언어가 이것을 제대로 수행 할 수 있다면 스크립트와 AJAX도 만들 수 있습니다.

감사합니다.

+3

왜 해시를 원하십니까? 같은 목적으로 auto_increment 열을 사용할 수 없습니까? – zneak

+0

URL 문자열에 사용할 base62, 6 char 해시가 필요합니다. auto_inc를 base62로 변환 할 수는 있지만 수동으로 엔트리를 만들 수는 없습니다. (TheLnk - 유효한 base62 해시입니다.하지만 auto inc에서 작업하고 있다면 추가 할 수 없습니다. ..). – Jesse

답변

0

누군가가 비슷한 문제를 겪고있는 경우에 대비해 고유 한 필드를 사용하고 있으며, 해시를 삽입하기 위해 PHP 해시 함수를 사용할 것입니다. 오류가 발생하면 다시 시도해 보겠습니다. 다시. 충돌 가능성이 낮기 때문에 천천히 진행되지는 않을 것입니다.

1

이 해시는 무엇입니까? 무작위로 생성 된 고유 한 VARCHAR 열을 원하는 것처럼 보입니까? 자동 증가가 잘못된 이유는 무엇입니까?

어쨌든 더 큰 해시를 사용해야합니다. (실제로 해시를하는 경우) MD5 기능을 사용하거나 4 자 이상의 UUID 생성기를 사용해야합니다. 예, while 루프를 사용할 수는 있지만 충돌이 거의 일어나지 않을 정도로 충분히 큰 것을 생성하십시오.

+0

필자는 반드시이 숫자를 6 자로 지정해야하며 충돌이 없다고 가정하면 확실히 충돌 할 필요가 없으므로 제대로 작동하지 않을 것입니다. 나는 MD5를 사용하지 않고 편안하게 사용할 수 있지만, 36 번째에서 6 번째까지는 거대하지만, 맹목적으로 삽입 할만큼 거대하지는 않다. – Jesse

3

하트가 기본 36 4 문자 해시 (해시 스페이스는 1679616)를 사용하여 설정되는 경우, 해시 테이블을 미리 생성 할 수 있습니다 이미 다른 테이블에 있습니다. 그런 다음 고유 한 해시를 찾는 것은 "사용되지 않는 테이블"에서 O (1) 인 "사용 된 테이블"로 이동하는 것처럼 간단합니다.

테이블이 1/3 정도라고 생각되면 평생 동안 채워질 가능성이 있으므로 해시 스페이스를 확장하는 것이 좋습니다. 공간이 가득 차면 어떤 알고리즘을 사용 하던지 더 이상 고유 한 해시를 찾을 수 없습니다.

+0

앱의 특성상, 특별히 base62 6 문자가 필요하다. 필자가 필요하다면 테이블을 미리 생성 하겠지만, 비록 mysql이 빠르다고 할지라도 500 억 개의 항목을 실행하는 것은 여전히 ​​내가 찾던 해결책이 아니다. (나는 많은 항목에 도달 할 것으로 예상하지 않지만, – Jesse

+0

해시가 100 만 개까지 미리 생성되어 설명 된 것과 비슷할 수 있습니다. 그런 다음/낮아지면 더 많이 생성 할 수 있습니다. 해시가 손보다 먼저 수행되면 O (1)을 보장 할 수 있지만 솔직히 충돌은 결코 없을 것입니다 .1 백만 개의 해시를 사용하면 여전히 0.0017 %의 충돌 만 있고 처리 할 코드를 작성합니다 충돌의 db 오류 (일어난 경우) –

0

의견이 있으십니까? 자동 증가 열을 사용하지 않으시겠습니까? 다른 (고유하지 않은) 필드에 해시를 저장하고 id를 연결합니다 (동적으로). 그래서 사용자에게 [해시] [ID]를 부여합니다. substring 함수를 사용하여 pure SQL에서 구문 분석 할 수 있습니다.

해시가 있어야하므로 사용자는 ID를 증가시켜 다른 레코드를 볼 수 없습니다.

+0

autoby가 Toby에게 응답 한대로 autoinc가이 작업을 수행하는 가장 깨끗한 방법 일 것입니다. 해시는 참조 할 수있는만큼 보안을 위해 존재하지 않습니다. 이 URL 문자열에있을 것이며, 나는 그것이 윙윙 거리는 옵션을 가지고 선호합니다. - 읽을 수있는. 불행히도 자동 inc에 db를 잠그면 해시를 키 입력하고 순서가 다른 항목을 추가해야하므로 어렵습니다. 그것은 지금까지 가장 가까운 것이 분명합니다. 다른 것을 알 수 없다면 나는 그것을 할 것입니다. – Jesse

1

다른 사람이 autoinc 필드에 무슨 문제가 있다고 제안 했습니까? 영숫자 값을 원할 경우 int에서 기본 36의 영숫자 문자열로 간단하게 변환 할 수 있습니다. 이것은 거의 모든 언어로 구현 될 수 있습니다.

+0

autoinc 필드를 사용하고 싶습니다.이 옵션이 가장 좋을 것 같습니다. (기본 62로 변환해야합니다.)하지만 환경 설정에서 임의의 숫자를 사용하고 싶습니다. 이것은 또한 순서에 맞지 않는 항목을 추가하는 기능을 제거합니다. 이는 구현하고자하는 것입니다. 이것은 아마도 가장 실현 가능성이 높은 옵션이지만 여전히 원하는 것을 남겨 둡니다. – Jesse

0

또한 MySQL 기능 UUID()UUID_SHORT()을 확인할 수 있습니다. 이러한 함수는 정의에 따라 전역 적으로 고유 한 UUID를 생성합니다. PHP에서 생성 된 해시 문자열이 이미 존재하는지 다시 확인하지 않아도됩니다.

여러 가지 경우에 이러한 기능이 프로젝트 요구 사항에 맞을 수도 있습니다. :-)

관련 문제