如果您对前缀范围内的重叠数做出温和的假设,则可以使用MongoDB或MySQL来最佳地进行操作.在下面的答案中,我将用MongoDB进行说明,但是将这个答案移植到MySQL应该很容易.

首先,让我们重新说明一下问题.当您谈论匹配“前缀范围”时,我相信您实际上在谈论的是在词典顺序下找到正确的范围(直觉上,这只是字符串的自然字母顺序).例如,其前缀匹配54661601至54661679的数字集正是这样的数字集,当以字符串形式编写时,在字典上大于或等于“ 54661601”,但在字典上小于“ 54661680”.因此,您应该做的第一件事是将所有上限加1,以便您可以通过这种方式表达查询.在mongo中,您的文档看起来像

{low: "54661601", high: "54661680", bin: "a"}
{low: "526219100", high: "526219200", bin: "b"}
{low: "4305870404", high: "4305870405", bin: "c"}

现在的问题就变成了:给定一组[low,high]形式的一维间隔,我们如何快速找到包含给定点的间隔?最简单的方法是在低场或高场上使用索引.让我们使用高场.在mongo shell中:

db.coll.ensureIndex({high : 1})

现在,让我们假设间隔根本不重叠.如果是这种情况,则对于给定的查询点“ x”,包含“ x”的唯一可能的时间间隔是具有大于“ x”的最小高值的时间间隔.因此,我们可以查询该文档并检查其低值是否也小于“ x”.例如,如果存在以下情况,它将打印出匹配间隔:

db.coll.find({high : {'$gt' : "5466160179125211"}}).sort({high : 1}).limit(1).forEach(
function(doc){ if (doc.low <= "5466160179125211") printjson(doc) }
)

现在,假设不是假设间隔完全不重叠,而是假设每个间隔与少于k个相邻间隔重叠(我不知道k的哪个值对您来说是正确的,但希望它很小).在这种情况下,您只需在上面的“限制”中将k替换为1,即

db.coll.find({high : {'$gt' : "5466160179125211"}}).sort({high : 1}).limit(k).forEach(
function(doc){ if (doc.low <= "5466160179125211") printjson(doc) }
)

该算法的运行时间是多少?索引是使用B树存储的,因此,如果数据集中有n个间隔,则需要O(log n)时间以高值查找第一个匹配的文档,然后是O(k)时间来遍历下一个k文档,总共O(log nk)时间.如果k为常数,或者实际上小于O(log n),则这是渐近最优的(这是在标准计算模型中;我不计算外部存储器传输的次数或任何奇特的值).

发生这种情况的唯一情况就是k大,例如某个大间隔几乎包含所有其他间隔.在这种情况下,运行时间为O(n).如果数据的结构是这样的,那么您可能需要使用其他方法.一种方法是使用mongo的“ 2d”索引,将您的低值和高值编入x和y坐标.然后,您的查询将对应于在x-y平面的给定区域中查询点.这在实践中可能会做得很好,尽管使用2d索引的当前实现,最坏的情况仍然是O(n).

有许多理论结果可针对所有k值实现O(log n)性能.它们以诸如“优先级搜索树”,“段树”,“间隔树”等名称命名.但是,这些是您必须自己实现的特殊用途的数据结构.据我所知,目前没有流行的数据库实现它们.