2013-11-26 175 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