2009-10-03 2 views
4

5 문자 무작위 문자열을 데이터베이스에 효율적으로 삽입하면서 고유성을 보장해야합니다. 임의의 문자열을 생성하는 것은 문제가 아니지만 현재 내가하고있는 일은 문자열을 생성 한 다음 DB가 이미 존재하는지 검사하는 것입니다.가장 효율적인 방법 ... 고유 한 무작위 문자열

이 과정을 수행하는보다 효율적인 방법이 있습니까?

GUID 또는 5 자 이상인 것을 사용하고 싶지는 않습니다. 5 문자 이상을 사용해야합니다.

추신 : 나는 차이가 있다고 생각하지 않지만 내 문자열은 모두 대소 문자를 구분합니다. 여기

당신은 GUID를 생성하고 첫 번째 (5 개) 문자를 사용할 수

Public Function GetRandomNumbers(ByVal numChars As Integer) As String 
    Dim chars As String() = { _ 
    "A", "B", "C", "D", "E", "F", _ 
    "G", "H", "I", "J", "K", "L", _ 
    "M", "N", "O", "P", "Q", "R", _ 
    "S", "T", "U", "V", "W", "X", _ 
    "Y", "Z", "0", "1", "2", "3", _ 
    "4", "5", "6", "7", "8", "9", _ 
    "a", "b", "c", "d", "e", "f", _ 
    "g", "h", "i", "j", "k", "l", _ 
    "m", "n", "o", "p", "q", "r", _ 
    "s", "t", "u", "v", "w", "x", _ 
    "y", "z"} 
    Dim rnd As New Random() 
    Dim random As String = String.Empty 
    Dim i As Integer = 0 
    While i < numChars 
     random += chars(rnd.[Next](0, 62)) 
     System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1) 
    End While 
    Return random 
End Function 
+0

내 코드를 쓰는 사람을 찾고 있지 않습니다. 효율성 개념을 찾고 있습니다. –

답변

9

순차적으로 추가 된 5 개의 큰 문자열 풀 (즉, 고유 한)이있는 테이블을 만들고 기본 키로 GUID를 만듭니다. 사용 여부를 나타내는 열을 추가하십시오.

새 번호가 필요하면 풀에서 최상위 1을 선택하고 guid로 정렬하여 (따라서 임의로 됨) 결과를 "소비"로 설정하십시오.

+1

이것은 추가 표를 작성하지만 고유하고 임의적이며 현재 값을 계속 검색하지 않고 가능한 가장 큰 값을 사용합니다. OP의 원래 솔루션은 행 수가 증가함에 따라 더 오래 걸릴 것입니다. –

+0

그래서 초기 무작위 문자열을 생성하는 데 상당한 양의 작업이있을 것이라고 가정합니다. –

+1

열을 추가하여 사용 여부를 표시하는 대신 사용 된 그대로 삭제하지 않는 이유는 무엇입니까? 쿼리를 더 빠르고 쉽게 작성할 수 있습니다. – JohnFx

1

은 "임의의 문자열"부분을 무엇입니까?

+3

그건 임의의 문자열을 생성하는 또 다른 방법 일 뿐이지 만 여전히 중복을 확인해야합니다. – Guffa

+0

대소 문자를 구분하는 문자열을 위해 5 비트를 추가로 생성해야하지만, 내 생각도 처음이었습니다. – schnaader

1

임의성이 더 중요합니까, 아니면 고유성이 더 중요합니까? - 나는 "더 중요하다"고 말했다. 둘 다 필요하다는 사실을 알게되었습니다.

임의성이 더 중요하면 역사적인 가치를 추적 할 방법이 필요합니다. 적절한 인덱스를 가진 데이터베이스 자체가이를 수행하는 가장 좋은 방법이 될 것입니다.

고유성이 더 중요 할 경우 카운터를 사용하고 5 자리 숫자로 제로 패드를 사용하면됩니다. 이것은 물론 당신을 100,000 개의 행으로 제한 할 것이기 때문에 카운터와 문자 공간으로의 변형을 사용할 수 있습니다 (예 : 1 = "A", 2 = "B", 27 = "AA"등) .

+0

아이디어는 단순히 URL 단축기에 대한 내 애플 리케이션을 구축했다. 나는 [bit.ly] (http://bit.ly)과 같이 5 개의 무작위 문자를 원했다. –

1

사용하지 않은 고유 단어를 무작위로 선택하는 방법이 있지만, 지금하고있는 것보다 조금 나아지지는 않을 것입니다.

원칙적으로 사용되지 않는 단어의 순열을 결정하고 사용되지 않은 permuation 수에 따라 임의의 숫자를 생성 한 다음 해당 단어를 선택하는 것이 원칙입니다.

예를 들어 단어가 3 자이고 문자 0과 1 만 사용하는 경우 8 가지 가능한 순열이 있습니다.

No. PI UI 
---------- 
000 0 0 
001 1 1 
010 2 - 
011 3 2 
100 4 - 
101 5 3 
110 6 4 
111 7 5 

PI = 순열 지수
UI = 사용하지 않는 순열 인덱스가 사용되지 않는 순열을 선택하려면 이미 조합 "010"과 "100"을 사용하는 경우는 다음과 같다 뭔가를 얻을 것 0에서 5까지 임의의 숫자를 생성하고 해당 순열을 선택하면됩니다.

모든 가능한 permuations의 목록을 유지하는 것은 물론 실용적이지 않으므로 문자열에서 순열 색인을 결정할 수있는 함수와 순열 색인에서 문자열을 결정할 수있는 함수가 필요합니다.

또한 어떤 순열이 사용되지 않았는지 판별하려면 어떤 순열이 사용되는지 확인해야하므로 어느 시점에서 여전히 테이블을 쿼리해야합니다.

0

문자열을 기존의 채워진 테이블에 삽입하는 경우 문자열이 존재하지 않는지 항상 확인해야합니다 (명시 적 SELECT 일 필요는 없습니다). 수동으로 할 수도 있고 열에 UNIQUE 제한 조건을 부여하여 데이터베이스가이를 수행하게 할 수도 있습니다. 따라서 문자열이 이미 있으므로 데이터베이스에서 오류를 반환하면 다른 문자열을 생성하십시오.

빈 테이블이 있고 여러 임의의 문자열로 채우려는 경우 다른 문제입니다.

0

나는 당신이 당신의 원래 생각을 고수해야한다고 생각합니다. 인덱스에 고유 한 제한 조건을 설정하고 데이터베이스에서 중복을 확인 /보고하면 중복 검사의 방법이 상당히 효과적 일 수 있지만이 가정은 행의 수와 무작위로 선택된 데이터가 포함 된 중복 가능성과 같이 제공되지 않은 일부 정보에 따라 달라집니다.

매개 변수로 고유 한 시퀀스 풀을 완전히 미리 채우려면 4 억 5 천 9 백만 행의 테이블이 필요합니다.

블룸 필터를 사용하여 관리 가능한 통계를 데이터베이스 나 메인 메모리에로드하고 중복을 피할 수 있지만 행 수와 필터 구성에 따라 행 수가 대폭 증가한 경우 필터가 채워질 수 있습니다. 459 백만 한계. 필터가 오 탐지를보고 할 수 있기 때문에 시스템이 멈추는 상황에 빠지지 않도록 필터를 통과하는 순열을 영원히 접근하도록 노력해야합니다.

0

단어가 얼마나 오랫동안 남았는지 알고 계시 겠지만 트리 기반 접근 방식을 사용하지 않으시겠습니까? (랜덤 트리 워크라고 부르 자)

단어에 n 문자가 있다고 가정 해보십시오. S에서 모든 기호 s의 목록을 생성하고 각 기호에 대한 카운터와 문자열의 가능한 위치, 본질적으로 차원 s 배의 행렬 M을 연관시킵니다. 이제 주사위를 굴려 첫 글자와 훑어보기 M (s, 1)을 선택하십시오. M (s, 1)이 s로 시작하는 가능한 단어의 수보다 크거나 같으면 다시 롤백합니다. 그렇지 않으면 M (s, 1)을 증가시킵니다.

모든 문자 1에 대해 n을 반복합니다.

많은 단어를 다 사용하기 전까지는 꽤 빨라야합니다.

관련 문제