2013-11-26 554 views
0

我想這樣做基於10位的數值,其中僅第一ň數字是顯著數據庫查詢。假設有事先沒有辦法通過查看值來確定ñ高效數據庫查找

例如,收到值5432154321.相應的條目(如果存在)可能具有鍵54或543215或基於n爲某處1和10(含)之間的任意值。

是否有任何有效的方法來對這樣的字符串短的簡單嘗試所有的可能性10匹配?

一些背景

的值是從條形碼掃描。的條形碼EAN13限制循環號碼,以便它們具有以下結構:

02 [1234567890]Ç

其中C是一個校驗和。 02和校驗和之間的10位數字包括一個項目標識符,後跟一個項目度量。商品標識符後面可能有一個檢查數字。

由於我不能依賴數據來遵守任何單一標準,我希望能夠在特定的基礎上定義特定條形碼的結構,這意味着10位數字的部分我解壓,可以是1和10只是一些想法在這裏之間

+1

一種可能性是從數據庫鍵構建[trie](http://en.wikipedia.org/wiki/Trie),並在內存中搜索該trie。然後從數據庫加載記錄(如果找到)。 –

+1

在索引列上,10次查找真的不會花那麼長時間。如果你正在尋找一個數據庫設計(不是一個通用的算法或數據結構答案,可能不適用於數據庫),我建議你刪除[tag:algorithm],並且可能添加適用的數據庫標籤(但正如我所說 - 10次​​查找真的不會花費那麼長時間,我不確定是否有更好的方法)。 – Dukeling

+0

@JimMischel,謝謝,但我認爲加載到內存中所需的數據量是過高的。 – PhilDin

回答

1

任何時間長度:

1) 在逆轉形式,這些數字可能存儲在您的數據庫。 如果你有N = 54321你將其存儲在數據庫N = 12345。 說N是您存儲它的列的名稱。

當你閱讀K = 5432154321,扭轉這一個了, 你K1 = 1234512345,現在檢查DB N列 (其值假設P),如果K1%10 2 -S == P, 其中s =地板(Math.log(P)+ 1)。 注意:floor(Math.log(P)+ 1)是 的公式數P> 0的位數。 價值floor(Math.log(P)+1)也可以 存儲在數據庫作爲一個預計算的,這樣 你不需要每次都計算它。 2)因爲這1)有點不舒服(但也許這裏最好的3個想法), 也許你只是將​​它們存儲在一個字符串列中,並用 'like operator'來檢查它。但這是微不足道的,你可能已經認爲它已經是 。 3)或者...你存儲的數字反向,但你也 存儲他們所有的殘留mod 10^k爲k = 1 ... 10。 COL1,COL2,......,col10 然後你就可以幾乎直接比較數字, 檢查會像

N % 10 == col1 
or 
N % 100 == col2 
or 
... 
(N % 10^10) == 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. 

所以這個想法1)似乎沒有那麼糟糕。

+0

謝謝,我想我終於設法將它融入我的腦海。我認爲問題在於,單個全表掃描(您的解決方案所要求的)是否會比10個索引掃描(如@Dukeling所建議的)更快,這是我必須嘗試的。 – PhilDin