如果您對在您的前綴範圍重疊數溫和的假設,就可以做你最好使用MongoDB或MySQL。在下面的答案中,我將用MongoDB進行說明,但它應該很容易將此答案移植到MySQL。
首先,讓我們改一下這個問題了一下。當你談論匹配「前綴範圍」,我相信你實際上是在談論一個字典排序下找到正確的範圍(憑直覺,這只是字符串的自然字母排序)。例如,其前綴與54661601至54661679相匹配的一組數字恰好是以字符串形式按字典順序大於或等於「54661601」,但按字典順序小於「54661680」的數字集。因此,您應該做的第一件事是將1加到您的所有高範圍內,以便您可以用這種方式表達您的查詢。在蒙戈,你的文件看起來是這樣的
{low: "54661601", high: "54661680", bin: "a"}
{low: "526219100", high: "526219200", bin: "b"}
{low: "4305870404", high: "4305870405", bin: "c"}
現在的問題就變成了:給定一組的形式[低,高)的一維區間,我們如何能夠快速找到其間隔( s)包含一個給定的點?要做到這一點最簡單的方法是在任的低或高領域的指標。我們使用高位字段。在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會對你有什麼價值,但希望它是小的)。在這種情況下,只需更換1 ķ在上面的「限制」,即
db.coll.find({high : {'$gt' : "5466160179125211"}}).sort({high : 1}).limit(k).forEach(
function(doc){ if (doc.low <= "5466160179125211") printjson(doc) }
)
這是什麼算法的運行時間?索引使用B樹存儲,因此,如果有Ñ間隔在數據集,它需要爲O(log Ñ)時間由高值,則O(ķ來查找第一匹配文檔)時間遍歷下一個文件,總共爲0(log n + k)time。如果ķ是恆定的,或實際上任何小於爲O(log Ñ),那麼這是漸近最優(這是在計算的標準模型;我不計算外部存儲器傳輸數或任何幻想) 。
這種情況下發生的唯一情況是,當k很大時,例如,如果某個較大的間隔包含幾乎所有其他間隔。在這種情況下,運行時間爲O(Ñ)。如果您的數據是這樣構建的,那麼您可能會想要使用不同的方法。一種方法是使用蒙戈的「2D」的索引,你低和高值編纂X和ÿ座標。然後你的查詢會對應查詢在X的給定區域點 - Ÿ平面。這在實踐中可能會表現得很好,儘管目前實現了2d索引,但最壞的情況仍然是O(n)。
對於所有k的值,都有許多理論結果達到了O(log n)性能。他們按照優先搜索樹,段樹,間隔樹等名稱進行搜索。但是,這些是專用數據結構,您必須自行實施。據我所知,目前沒有流行的數據庫實現它們。