關於SQL/NoSQL資料庫搜尋/查詢的思考,sqlnosql

來源:互聯網
上載者:User

關於SQL/NoSQL資料庫搜尋/查詢的思考,sqlnosql

轉載請註明出處:jiq•欽's technical Blog

Hbase特徵:

最近在學習Hbase,Hbase基於行健是建立了索引的,查詢速度會非常快,完全即時。

但是Hbase要基於行健之外的欄位進行查詢,那麼就只能是全盤掃描,基本上不可接受。

所以Hbase一般來說會針對具體的應用情境來設計行健,利用基於行健的查詢的即時性來達到Hbase資料的即時查詢。

 

關係型資料庫基於索引欄位的即時查詢:

然後聯想到關係型SQL資料庫,他們針對主鍵是建立了B/B+/B-樹索引的,基於主鍵的查詢是即時的,範圍掃描也是即時的。

更重要的是,基於非主鍵的其他欄位,關係型資料庫也可以很方便地為其建立索引,從而達到即時查詢。

 

Hbase的二級索引:

那麼Hbase這種NOSQL資料庫可不可以也為除了行健之外的欄位建立索引,從而針對這些欄位的查詢達到即時的效果呢?

答案是肯定的。

在Hbase裡面針對除了行健之外的欄位建立索引稱之為“二級索引”。

 

通常建立二級索引的方式是利用Hbase中的“副處理器”,副處理器主要包含Observer和Endpoint兩種模式,前者類似於關係型資料庫中的觸發器trigger,而後者類似於關係型資料庫中的預存程序,通過Observer可以講使用者代碼嵌入到現有的運行過程中,在特定的時間發生時就會觸發對應的這段使用者代碼,即回呼函數。目前有三種Observer介面:

1、  RegionObserver:提供對應資料操作事件的鉤子,該類操作有Get、Put、Delete、Scan 等等。每一個 region 都會有一個 RegionObserver 執行個體。

2、  WALObserver:提供預寫記錄檔(write-ahead log,WAL)相關操作的鉤子。WALObserver在WAL處理過程中運行,每一個region server有一個執行個體。

3、  MasterObserver:提供DDL操作的鉤子,該類操作有建立表、刪除表、修改表的元資訊等。MasterObserver運行在HBase master上。

每一類observer都可以載入多個,所有的observer會按鏈式順序執行。

 

Hbase社區關於使用Coprocessor架構建立二級索引的方案主要有三種:

1、             基於WALObserver在一個索引表內產生索引,通過欄截Write Ahead Log寫入操作,提取寫入HLog的KeyValue對資訊,把相應資訊儲存到索引表中。

2、             基於RegionObserver在一個Region內維護一個索引列族,通過攔截Region的put、delete等操作,提取相應資訊儲存到同一個Region的索引列族中,這種方式的索引是局部索引,不支援全排序。

3、             基於RegionObserver在一個索引表內產生索引,通過欄截Region的put、delete等操作,提取相應資訊儲存到索引表中。

這個時候大家可能想知道索引表是什麼樣子的,一般來說,如果某一個Hbase表中有一列叫做所在地區,儲存的是使用者當前所在的城市,比如南京,上海這樣,那麼要針對著一些建立對應的二級索引,當插入新的一行記錄的時候,在副處理器的鉤子函數Observer中就會提取出這一列的值,在對應的索引表中插入一行索引記錄,這行索引記錄的rowkey是該列提取出來的值,而將這行索引記錄的rowkey是剛才插入的那條記錄的真正的rowkey,這樣在檢索地區,比如使用者輸入一個“南京”,或者執行基於Hbase的SQL語句:select * from userTable where location=’南京’的時候,就會檢測到location這一列已經被建立了二級索引,所以就會在索引表中尋找rowkey為’南京’的記錄,然後取出真正的rowkey,在對應的資料表中取出對應的記錄,展示給使用者。

 

關係型SQL資料庫和NoSQL資料的針對非主鍵的索引建立還是有很多相似的地方的。

 

二級索引與全文檢索索引:

但是有一點要注意,二級索引和全文檢索索引是兩個不同的概念:

建立二級索引一般是為了能夠即時查詢,而全文檢索索引的目的是為了能夠快速地在資料庫中尋找到自己關心的內容。前者是屬於一種針對某一列值進行完全符合的方式,而後一種是需要對資料進行分詞,對分詞的結果建立‘倒排索引’,從而能夠支援根據特定的關鍵字尋找其所屬的那段內容(或者說所屬的文檔/記錄)。

 

Hbase中的全文檢索索引:

那麼在Hbase中的全文檢索索引一般怎麼做呢?

之前接觸過solr,是在Lucence上面的一層封裝好的庫,支援搭建分布式叢集方式的全文檢索索引服務。其原理就是簡單地將要進行全文檢索索引的欄位的內容進行分詞,然後將分詞後的結果分別建立倒排索引。

Hbase中要實現全文檢索索引,一般就可以結合Lucence/Solr來做,利用他們的自動建立索引的功能,針對Solr來說,無非就是其輸入源不同了,以前可能一般針對關係型資料庫,現在輸入源變為了Hbase。

 

全文檢索索引不是即時的,並不是說你往Hbase中插入一條記錄,馬上你就可以即時地在較快的時間內查詢到,因為後台建立索引是需要一個過程的,一般來說可能幾分鐘左右吧。

 

關係型資料庫中的全文檢索索引:

在這裡瞭解到了Hbase的全文檢索索引之後,自然而然就聯想到了關係型資料庫中的全文檢索索引。

關係型資料庫的全文檢索索引和Hbase的其實幾乎是一樣的。

比較流行的方式也是採用和Solr這樣成熟的開源的全文檢索索引庫結合實現,將關係型資料庫作為Solr的資料輸入源,它們會定期自動從關係型資料庫中抽取資料,或者由關係型資料庫的插入/刪除/更新操作觸發,來在Solr中為指定的欄位分詞後的結果建立倒排索引。

另外國內也有一些比較出名的商用的全文檢索索引引擎,我們公司目前使用的就是這種。

 

關係型資料庫中的模糊查詢like:

在思考查詢的時候,很難不想到關係型資料庫中的模糊查詢。

個人覺得,模糊查詢看似是和針對某一欄位的全文檢索索引類似,其實在功能上講(不談效率)要比這個更加強大,比如你針對“我是季義欽”這句話,你可能利用全文檢索索引引擎,分詞時候會分成“我”,“是”,“季義欽”三個詞(實際的分詞器可能不這樣,我只是舉個例子),這個時候你全文檢索索引只能夠搜尋到“我”,“是”,“季義欽”三個詞,如果你要搜尋“義欽”那麼就會搜尋不到。

但是關係型資料庫中的模糊查詢,你要是用“%義欽”來查詢絕對能查詢到。

 

為什麼呢?

我瞭解了一下,發現關係型資料庫中的模糊查詢並沒有為這個要模糊查詢的欄位建立整個欄位的索引,更沒有分詞之後再針對分詞結果建立索引,而是拿到“%義欽”的查詢條件之後,全表掃描,對這個Regex進行匹配。

 

雖然你把萬用字元放在前面,像“like %義欽”這樣,這個查詢肯定不會走索引,而是會全表掃描,但是如果你的模糊查詢是“like 季%”,即將萬用字元放在前後面,那麼這個查詢是有可能走索引的,而且萬用字元放在前面的查詢其實是有一些技巧來進行具體的最佳化的,比如看看這個例子:http://blog.csdn.net/firstboy0513/article/details/6912632。

 

在大部分關係型資料庫中,其實是可以為指定欄位建立全文索引(注意,這裡所說的並不是不是採用第三方全文檢索索引引擎)的,比如MYSQL中像這樣:

MATCH (col1,col2,...) AGAINST (expr[search_modifier])

search_modifier: { IN BOOLEAN MODE | WITHQUERY EXPANSION }

例如:SELECT * FROM tab_name WHERE MATCH (col1,col2) AGAINST(search_word);

這裡的table需要是MyISAM類型的表,col1、col2需要是char、varchar或text類型,在查詢之前需要在col1和col2上建立一個全文索引。

 

下面有一段話需要注意:

MySQL在高並發串連、資料庫記錄數較多的情況下,SELECT... WHERE ... LIKE '%...%'的全文檢索搜尋方式不僅效率差,而且以萬用字元%和_開頭作查詢時,使用不到索引,需要全表掃描,對資料庫的壓力也很大。MySQL針對這一問題提供了一種全文索引解決方案,這不僅僅提高了效能和效率(因為MySQL對這些欄位做了索引來最佳化搜尋),而且實現了更高品質的搜尋。但是,至今為止,MySQL對中文全文索引無法正確支援。

--- 這個問題可以通過使用一些MYSQL中文全文檢索索引外掛程式來解決。

 

關於Oracle中的全文檢索索引可以參考這篇文章:http://www.iteye.com/topic/1118055。

 

本文屬於個人見解,如有疑問或者指正,歡迎討論,謝謝!


nosql資料庫有什

1. CouchDB

所用語言: Erlang
特點:DB一致性,便於使用
使用許可: Apache
協議: HTTP/REST
雙向資料複製,
持續進行或臨時處理,
處理時帶衝突檢查,
因此,採用的是master-master複製(見編注2)
MVCC – 寫操作不阻塞讀操作
可儲存檔案之前的版本
Crash-only(可靠的)設計
需要不時地進行資料壓縮
視圖:嵌入式 映射/減少
格式化視圖:列表顯示
支援進行伺服器端文檔驗證
支援認證
根據變化即時更新
支援附件處理
因此, CouchApps(獨立的 js應用程式)
需要 jQuery程式庫

最佳應用情境:適用於資料變化較少,執行預定義查詢,進行資料統計的應用程式。適用於需要提供資料版本支援的應用程式。

例如: CRM、CMS系統。 master-master複製對於多網站部署是非常有用的。

(編注2:master-master複製:是一種資料庫同步方法,允許資料在一組電腦之間共用資料,並且可以通過小組中任意成員在組內進行資料更新。)

2. Redis

所用語言:C/C++
特點:運行異常快
使用許可: BSD
協議:類 Telnet
有硬碟儲存支援的記憶體資料庫,
但自2.0版本以後可以將資料交換到硬碟(注意, 2.4以後版本不支援該特性!)
Master-slave複製(見編注3)
雖然採用簡單資料或以索引值索引的雜湊表,但也支援複雜操作,例如 ZREVRANGEBYSCORE。
INCR & co (適合計算極限值或統計資料)
支援 sets(同時也支援 union/diff/inter)
支援列表(同時也支援隊列;阻塞式 pop操作)
支援雜湊表(帶有多個域的對象)
支援排序 sets(高得分表,適用於範圍查詢)
Redis支援事務
支援將資料設定成到期資料(類似快速緩衝區設計)
Pub/Sub允許使用者實現訊息機制

最佳應用情境:適用於資料變化快且資料庫大小可遇見(適合記憶體容量)的應用程式。

例如:股票價格、資料分析、即時資料搜集、即時通訊。

(編注3:Master-slave複製:如果同一時刻只有一台伺服器處理所有的複製請求,這被稱為
Master-slave複製,通常應用在需要提供高可用性的伺服器叢集。)

3. MongoDB

所用語言:C++
特點:保留了SQL一些友好的特性(查詢,索引)。
使用許可: AGPL(發起者: Apache)
協議: Custom, binary( BSON)
Master/slave複製(支援自動錯誤恢複,使用 sets 複製)
內建分區機制
支援 javascript運算式查詢
可在伺服器端執行任意的 javascript函數
update-in-place支援比CouchDB更好
在資料存放區時採用記憶體到檔案對應
對效能的關注超過對功能的要求
建議最好開啟日誌功能(參數 –journal)
在32位作業系統上,資料庫大小限制在約2.5Gb
空資料庫大約佔 192Mb
採用 GridFS儲存大資料或中繼資料(不是真正的檔案系統)

最佳應用情境:適用於需要動態查詢支援;需要使用索引而不是 map/reduce功能;需要對大資料庫有效能要求;需要使用
CouchDB但因為資料改變太頻繁而佔滿記憶體的應用程式。

例如:你本打算採用 MySQL或 PostgreSQL,但因為它們本身內建的預定義欄讓你望而卻步。

4. Riak

所用語言:Erlang和C,以及一......餘下全文>>
 
nosql 怎使用?在關聯式資料庫中可以通過 select 語句查詢,但是在nosql中怎使用這個了,難道只可以儲存索引值對?

NoSQL資料庫有很多種,實現方式差別很大。有接近SQL查詢方式的,也有純粹的索引值對查詢。
對於K-V型資料庫,比較典型的是Redis,系統提供了get、set之類的命令用於增刪改查。關鍵是索引值對的鍵和值怎麼設計。
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.