2012-02-07 4 views
3

properietery 데이터베이스 (실제로는 파일 시스템이지만이 경우 간단하게 유지하려고합니다)의 유효성을 검사하려고합니다. 데이터베이스의 속성은 다음과 같습니다.확인할 수있는 난수 생성 - Java

기본 키는 1 개 또는 2 개가 될 수 있으며 정수 여야합니다. 열은 문자열 (비 ASCII 허용됨), 정수, Long 또는 날짜 시간이 될 수 있습니다.

이 데이터베이스에 저장하도록 요청한 값이 많은 수의 레코드 (> 500k 레코드)와 함께 올바르게 저장되었는지 확인하고자합니다. 그래서 이것을 위해 나중에 데이터를 쉽게 생성 할 수있는 도구를 확장하고 싶습니다. 나는이 도구를 사용하여 50 만 개 레코드를 생성 할

pk1 (int - primary key) 
pk2 (int - primary key) 
s1 (string) 
l1 (long) 
i1 (int) 

:

그래서 기본적으로 말하자면이 샘플 스키마입니다. 그런 다음, 주어진 시간에 주어진 기록을 온전하게 점검 할 수 있기를 원합니다. 일련의 작업 (예 : 백업, 데이터베이스 복원)을 수행 한 다음 몇 가지 레코드를 "현장 확인"할 수 있습니다. 따라서 기본 키 (pk1 = 100, pk2 = 1)에 대한 레코드 항목이 유효한지 신속하게 확인할 수 있기를 원합니다.

나중에 쉽게 확인할 수 있도록 각 열의 값을 생성하는 가장 좋은 방법은 무엇입니까? 값은 완전히 랜덤 일 필요는 없지만 빈번하게 반복해서는 안되기 때문에 압축 로직 중 일부가 너무 많이 발생할 수 있습니다. 예를 들어

는 말 "어떻게 든"도구는 행의 다음 값 생성 :

pk1 = 1000 
pk2 = 1 
s1 = "foobar" 
l1 = 12345 
i1 = 17 

가 지금은 여러 가지 작업을 수행하고, 나는이 말에 그 유효성을 검사 할을,이 행은있다 타락하지 않았다. 나는 s1, l1 및 i1에 대해 예상 값을 신속하게 생성 할 수 있어야합니다 - pk1 = 1000 및 pk2 = 1 - 주어진 값을 매우 빨리 검증 할 수 있어야합니다.

아이디어가 있으십니까?

(나는 새로운 사용을 오전 이후 지금이 :) 이 좋아 추가 내 자신의 질문에 대답을 게시 할 수 없습니다, 그래서 내가 추구 할 수있는 가능한 방법에 있습니다

접근 방법 # 1 : 사용 HASH (tablename)^HASH (fieldname)^pk1^pk2를 시드로 사용하십시오. 이렇게하면 유효성을 검사 할 때 각 열의 시드를 쉽게 계산할 수 있습니다. 반면에 시드가 열마다 한 번 계산되어야하기 때문에 많은 행에 대한 데이터를 생성 할 때 비용이 많이 든다. 그래서 위 스키마의 경우, 500k 레코드를 생성하기 위해 500k * 3 개의 시드를 사용할 것입니다.

Approach # 2 (Philipp Wendler가 제안) : 행당 하나의 시드를 생성하고 해당 행의 첫 번째 열에 시드를 저장하십시오. 첫 번째 열이 int 또는 long이면 값을있는 그대로 저장합니다. 첫 번째 열이 문자열이면 첫 번째 x 바이트에 시드를 저장 한 다음 해당 시드를 사용하여 생성 된 문자로 필요한 문자열 길이까지 채 웁니다.

행당 하나의 시드가 있기 때문에 접근 방식 # 2가 더 좋기 때문에 데이터 생성 속도가 접근 방식 # 1보다 다소 빠릅니다.

+0

... 무엇 나는 씨앗이 방법으로 생성하는 경우 : 씨 = HASH (TABLENAME)^HASH (기둥 이름을)^PK1^PK2 지금은 쉽게 씨앗을 계산할 수 있습니다 pk1과 pk2가 주어진 상태에서 여전히 테이블간에 무작위로 유지됩니다. columnname은 동일한 pk1 및 pk2 값에 대해 여러 테이블에서 반복 될 수 있지만 기능적으로 말하자면 동일한 값을 가져야합니다. – walletless

+0

다른 옵션은 Philipp Wendler가 아래에서 제안한 것을 추구하는 것입니다. 사용 된 시드를 저장하려면 테이블의 첫 번째 열을 사용하십시오. 이것이 int 또는 long 인 경우 시드를 그대로 저장하십시오. 이것이 문자열 인 경우 첫 번째 n 바이트를 사용하여 시드를 저장하고 해당 시드를 사용하여 생성 된 문자를 사용하여 필드를 필요한 길이만큼 채 웁니다. – walletless

+0

기본 키도 생성합니까? 그렇다면 다른 열의 해시를 저장하는 데 사용할 수 있습니다. 이것은 물론 삽입시 충돌을 일으킬 수 있습니다. (그러나 무작위로 pk를 생성하면 이런 일이 발생할 수 있습니다.) – wmz

답변

0
+0

고맙습니다. 나는 이미 이것을 보았다. 문제는 "시드"값을 사용할 수 있도록하기 때문에 문자열을 쉽게 생성 할 수 있습니다. 근본적으로이 문제는 다음과 같습니다. pk1 (1000) 및 pk2 (1); 임의 생성기에서 사용해야하는 시드는 무엇입니까? 그래서 매번 s1, l1 및 i1에 대해 동일한 값을 일관되게 만들 수 있습니다. – walletless

+0

@walletless 그냥 열의 하나에 시드를 저장하십시오 (내 솔루션에서 제안 된대로 해시 코드로 수행하는 것과 유사). 그런 다음 각 행에 대해 임의의 시드를 생성하고 시드의 해당 행에있는 데이터를 생성 할 수 있습니다. –

+0

이 방법은 검증에 사용되는 난수 생성 알고리즘이 생성에 사용 된 것과 정확히 동일하다는 사실에 의존합니다. 이것은 당연한 것처럼 들리 겠지만, 그러한 생성자의 구현자가이를 보장하지는 않으며 이후에 (예를 들어 라이브러리의 다음 버전에서) 알고리즘을 약간 변경시킬 수 있습니다. 그러면 갑자기 데이터가 더 이상 검증되지 않습니다. 일반적인 해시 코드와 같이 잘 표준화 된 알고리즘을 사용하면 문제가 해결됩니다. –

0

이 질문의 두 번째 부분에 응답에서 무언가 - 다른 모든 필드의 해시를 저장 (L1)을 만드는 방법에 대한 어떻게?그런 다음 손상된 부분이 있는지 신속하게 확인할 수 있습니다.

+0

스키마가 항상 길면 작업 할 수 있습니다. 주어진 테이블에 대한 열 세트는 긴 열을 가질 수도 있고 없을 수도 있습니다. 또한 긴 열도 둘 이상있을 수 있습니다. 스키마에 의존하는 앱이 특정 양식에 있기 때문에 기존 스키마를 수정하는 것은 옵션이 아닙니다. 수정하면 생성 된 데이터의 맨 위에서 발생하는 기능 테스트가 무효화됩니다. – walletless

1

임의의 임의 데이터를 생성하고 해시 코드 (예 : MD5는 암호로 보호 할 필요가 없으므로)를 계산하고 데이터와 함께 해시 코드를 저장할 수 있습니다. 해시 코드에 대해 별도의 열을 만들거나 예를 들어 문자열 열에 추가 할 수 있습니다.

확인을 위해 저장된 해시 코드를 해당 행의 나머지 데이터와 분리하고 해시 코드를 다시 계산하여 동일한 지 비교하십시오. 일치하지 않으면 데이터가 수정되었습니다.

여기서는 악의적 인 공격자가 아닌 실수로 인한 데이터 수정 만 방지하려는 것으로 가정합니다. 그래서 더 창의적인 솔루션을 생각하고

+0

안타깝게도 스키마 수정 옵션이 아닙니다. 하나의 옵션은 고정 된 시드를 응용 프로그램의 입력으로 시작하고 xor는 pk1과 pk2로 시작하는 것으로 생각했습니다. 그런 다음 그것을 무작위의 씨앗으로 사용하십시오. 그래서 입력 시드를 12345로 사용한다고 가정 해 봅시다 (예 : 시스템 틱). 그래서 임의의 함수에 대한 seed는 12345^1000^1이 될 것입니다. 그리고 난수를 아파치 공유지와 함께 사용하면 각 열을 생성 할 수 있습니다. 이 방법의 문제점은 여러 행에 대해 동일한 값을 얻게된다는 것입니다. – walletless

+0

임의의 길이의 문자열이 있습니까? 항상 문자열 열이 있습니까? 그렇다면 첫 번째 문자열 열에 대한 데이터의 끝에 해시 코드를 추가하십시오 (예 :). 그렇지 않으면 하나 또는 여러 개의 숫자 열을 선택할 수 있습니다. 해시 코드의 일부 비트 (예 : 64 개) 만 저장하면 충분합니다. –

+0

이 방법을 사용하는 경우 확인 도구는 시작 입력 (이 경우 12345)을 알아야하며 pk1 및 pk2 값이 지정된 행의 유효성을 쉽게 확인할 수 있습니다. 하지만, 문제는 이것이 많은 dupe 값을 야기한다는 것입니다. 데이터는 100 개의 테이블에 대해 생성되므로 피할 수 있다면 각 행의 시드를 별도로 저장하지 않아도됩니다. – walletless