2013-11-26 3 views
0

첫 번째 자릿수 만 중요한 10 자리 숫자 값을 기준으로 데이터베이스 조회를 수행하고 싶습니다. 미리 값을보고 n을 결정할 방법이 없다고 가정합니다.모든 숫자가 중요하지 않은 입력을 기반으로 효율적인 데이터베이스 조회

예를 들어 값 5432154321이 표시됩니다. 해당 항목 (있는 경우)에는 키 54 또는 543215 또는 n이 1에서 10 사이의 값을 가질 수 있습니다.

단순히 10 가지 가능성 모두를 시도하는 것만 큼 그러한 문자열을 일치시키는 데 효율적인 방법이 있습니까?

값은 바코드 스캔에서 일부 배경.

02 [1234567890] C

C가 체크 합이다 : 그들은 다음과 같은 구조를 가질 수 있도록 바코드 EAN13 순환 수를 제한한다. 02와 체크 합 사이의 10 자리 숫자는 항목 식별자 다음에 항목 식별자로 구성됩니다. 항목 식별자 뒤에 체크 숫자가있을 수 있습니다.

하나의 표준을 준수하기 위해 데이터에 의존 할 수 없기 때문에 특정 바코드가 어떻게 구성되어 있는지를 임시적으로 정의 할 수 있기를 바랍니다. 이는 10 자리 숫자의 부분

1) 은 아마 당신의 DB에 반대 형태로이 번호를 저장 : 나는 추출 것으로, 여기에 그냥 몇 가지 아이디어

+1

하나의 가능성은 데이터베이스 키로부터 [http://en.wikipedia.org/wiki/Trie]를 구성하고 메모리에서 해당 트라이를 검색하는 것입니다. 발견되면 데이터베이스에서 레코드를로드하십시오. –

+1

인덱싱 된 열에서 10 개의 조회는 실제로 그렇게 오래 걸리지 않습니다. 데이터베이스 설계 (데이터베이스에 적용되지 않는 일반 알고리즘 또는 데이터 구조 응답이 아닌)를 찾고 있다면 [tag : algorithm]을 제거하고 해당 데이터베이스 태그를 추가하는 것이 좋습니다 (하지만 제가 말했던 것처럼 - 10 개의 조회는 실제로 그렇게 오래 걸리지 않을 것이고 훨씬 나은 방법이 있는지 확신하지 못합니다.) – Dukeling

+0

@ JimMischel, 고마워요.하지만 메모리에로드하는 데 필요한 데이터 양이 엄청날 것 같아요. – PhilDin

답변

1

1 ~ 10 길이 될 수 있습니다. N = 54321이면 DB에 N = 12345로 저장합니다. 말 N은 당신이 그것을 저장 컬럼의 이름입니다.

당신이 = 5,432,154,321 K를 읽어 당신은 지금, K1 = 1,234,512,345를 얻을 DB 열을 확인, 너무 을이 일을 반대 할 때 그 값의 말을하게되는 N (P), K1 % 10^s == P, 여기서 s = floor (Math.log (P) + 1). 참고 : floor (Math.log (P) + 1)은 숫자의 자릿수입니다. 값 바닥 (Math.log (P) +1)은 에 저장 될 수도 있습니다. DB는 사전 계산 된 것으로, 따라서 은 매번 계산할 필요가 없습니다.

2)이 1)이 아프지 만 (여기에 나온 3 가지 아이디어 중 가장 좋음) 문자열 열에 저장하고 '연산자와 같은 것일 수 있습니다. 하지만 이것은 사소한 일입니다. 아마도 이미 으로 간주했을 것입니다.

3) 또는 ... 숫자를 역으로 저장하지만 도 k = 1 ... 10에 대해 모든 잔여 모 드 10^k를 저장합니다. 하지만

N % 10 == col1 
or 
N % 100 == col2 
or 
... 
(N % 10^10) == col10. 
여전히

매우 우아하지 같은 COL1, COL2, ..., col10 그럼 당신은 거의 직접 숫자를 비교할 수 있습니다, 검사가 될 것입니다 뭔가 (그리고 귀하의 경우에 해당되는 경우 확실히 확실하지 않음) .


나는 내 아이디어 1)를 확인하기로 결정했습니다. 여기에 예제가 (SQL Server에서 수행)입니다.

insert into numbers 
(number, cnt_dig) 
values 
(1234, 1 + floor(log10(1234))) 


insert into numbers 
(number, cnt_dig) 
values 
(51234, 1 + floor(log10(51234))) 

insert into numbers 
(number, cnt_dig) 
values 
(7812334, 1 + floor(log10(7812334))) 



select * From numbers 

/* 

Now we have this in our table: 

id number cnt_dig 
4 1234 4 
5 51234 5 
6 7812334 7 

*/ 

-- Note that the actual numbers stored here 
-- are the reversed ones: 4321, 43215, 4332187. 
-- So far so good. 

-- Now we read say K = 433218799 on the input 
-- We reverse it and we get K1 = 997812334 
declare @K1 bigint 

set @K1 = 997812334 

select * From numbers 
where 
@K1 % power(10, cnt_dig) = number 

-- So from the last 3 queries, 
-- we get this row: 
-- id number cnt_dig 
-- 6 7812334 7 
-- 
-- meaning we have a match 
-- i.e. the actual number 433218799 
-- was matched successfully with the 
-- actual number (from the DB) 4332187. 

그래서이 아이디어는 나쁘지 않게 보입니다.

+0

고마워, 나는 마침내 그걸 내 머리에 맞출 수 있었다고 생각한다. 필자는이 질문이 솔루션 전체에 필요한 단일 전체 테이블 스캔 (@Dukeling에서 제안한 것처럼)보다 10 번 빠른 인덱싱 스캔인지 여부를 판단하는 것으로 생각합니다. – PhilDin

관련 문제