最近遇到乙個問題:大批量的檔案,每個檔案除了擁有類似於
linux
中struct stat
中的一些基本的元資料外,還存在一系列的
key/value
對的擴充套件屬性,現在的需求是,根據使用者提供的
key/value
對,快速檢索出匹配的檔案集。
對於搜尋來說,暴力搜尋無疑是萬能的,遍歷所有的目標並逐個進行匹配,肯定能得出結果,比如
linux
下的find
工具就是採用這種方式找出特定檔案的。在匹配的過程中,查詢目標可能由數值(整數、浮點數)或是字串標示,對於數值可以通過直接比較的方式匹配,對於字串,則可通過相關的字串匹配演算法
(brute-force
、kmp
、正規表示式等)。
暴力搜尋的缺點在於效率太低,當目標集較大時開銷太大。通常解決的方法是為目標集針對搜尋特性建立相關的索引,對於結構化資料(如資料庫的應用)和非結構化的資料(如文字)採用的索引方式不同。
對於結構化的資料集(每個條目大小相同),如下圖:
學號名字
成績1001
jack
901005
rose
851006
jim95
1008
sun85
1012
robin
701018
lucy
90資料集按學號順序排列,如果需要查詢某一學號對應的成績,在沒有任何索引的情況下,需要遍歷整個資料集,為了提高效率,可為學號建立如下的索引(稠密索引,針對每一項建立乙個索引項)。
學號條目編號
1001
11005
21006
31008
41012
51018
6由於學號是順序存放的,當需要查詢指定的學號時,可採用二分查詢,將演算法的時間複雜度降低到了
logn
。如果採用稠密索引時索引占用的儲存空間過大,可採用稀疏索引的方式進行改善,如下圖,每兩項建立乙個索引。
學號條目編號
1001
11006
31012
5在檢索時,首先採用二分查詢找到比目標小的最大的學號,然後從該學號起進行遍歷,找出匹配的學號,演算法時間複雜度為
log(n/m)+ m(m
為索引間隔)。
對於名字和成績字段,可以採用相同的方式建立稠密索引,但因為其是無序的,不能建立稀疏索引。另外,還有很多種資料結構能加速結構化資料的查詢,如為資料集的某個字段建立二叉查詢樹、
b樹、紅黑樹等以加速查詢,多於一次需要查詢多個屬性的情形,可以採用
kd-tree
加速查詢。
對於非結構化的資料集,比如說文件,建立索引的方式就完全不同了,搜尋引擎就是幹這個的,索引的方式大都採用倒排表,搜尋引擎的相關原理以及索引的構建在我以前的博文
中介紹了。
對於本文開頭提到的需求,其特性不像結構化資料那樣規整,也不像非結構化資料那樣分散,稱其為半結構化的資料,
的bigtable
系統主要用於半結構化資料的儲存。大致模型相當於:每個物件擁有多種屬性(
bigtable
中的列),很多物件可能擁有相同的屬性(值不同)。
如何對半結構化的資料建立索引以加速查詢,幾經思索仍然沒有頭緒,希望與對此有興趣的技術牛討論交流,以發現並解決問題。
結構化資料 半結構化資料 非結構化資料
結構化資料 即行資料,儲存在資料庫裡,可以用二維表結構來邏輯表達實現的資料 所謂半結構化資料,就是介於完全結構化資料 如關係型資料庫 物件導向資料庫中的資料 和完全無結構的資料 如聲音 影象檔案等 之間的資料,html文件就屬於半結構化資料。它一般是自描述的,資料的結構和內容混在一起,沒有明顯的區分...
結構化 半結構化和非結構化資料
在實際應用中,我們會遇到各式各樣的資料庫如nosql非關聯式資料庫 memcached,redis,mangodb rdbms關聯式資料庫 oracle,mysql等 還有一些其它的資料庫如hbase,在這些資料庫中,又會出現結構化資料,非結構化資料,半結構化資料,下面列出各種資料型別 結構化資料 ...
結構化 半結構化和非結構化資料
在實際應用中,我們會遇到各式各樣的資料庫如nosql非關聯式資料庫 memcached,redis。mangodb rdbms關聯式資料庫 oracle,mysql等 另一些其他的資料庫如hbase,在這些資料庫中。又會出現結構化資料。非結構化資料。半結構化資料,以下列出各種資料型別 結構化資料 可...