李順
[摘 ? ? ? ? ? 要] ?基于為學校開發(fā)的實際項目,首先對NoSQL數(shù)據(jù)庫的理論和方向進行闡述,然后從總體的設計與需求出發(fā),對以Redis技術為主的NoSQL數(shù)據(jù)庫應用進行探究。
[關 ? ?鍵 ? 詞] ?數(shù)據(jù)庫;NoSQL技術;Redis
[中圖分類號] ?TP311.1 ? ? ? ? ? [文獻標志碼] ?A ? ? ? ? ? ?[文章編號] ?2096-0603(2019)15-0034-02
數(shù)據(jù)庫是數(shù)據(jù)存儲的主要場所,當前的數(shù)據(jù)庫技術主要是以MySQL、PosrareSQL等為主的關系數(shù)據(jù)庫。隨著網(wǎng)站技術的發(fā)展,特別是微博之類大型網(wǎng)站的出現(xiàn)讓人們意識到了關系數(shù)據(jù)庫的局限性,那就是關系數(shù)據(jù)庫的設計約束不夠靈活和海量數(shù)據(jù)處理能力不足,使用戶的體驗過程很不理想。所以為了優(yōu)化用戶的體驗,滿足數(shù)據(jù)庫低延時和高并發(fā)的需求,研究人員開始將目光投入到非關系數(shù)據(jù)庫上,也就是本文所研究的NoSQL技術。從本質(zhì)上來說,NoSQL技術是對關系數(shù)據(jù)庫的補足,主要是應對高并發(fā)和大數(shù)據(jù)的需求進行構架,充分開發(fā)了以集合論為代數(shù)基礎的結(jié)構化查詢語言,保證了事物的一致性,滿足了網(wǎng)站對數(shù)據(jù)庫伸縮性和高可用性的要求。
一、NoSQL簡介
NoSQL是基于CAP理論、最終一致性和BASE思想而構建起來的技術體系,與傳統(tǒng)的關系數(shù)據(jù)庫的數(shù)據(jù)模型有著很大的區(qū)別。傳統(tǒng)的關系數(shù)據(jù)庫的數(shù)據(jù)模型表現(xiàn)為關系型數(shù)據(jù)模型,而NoSQL拋棄了關系型模型的框架和模式,從鍵值、文檔、列、圖四個存儲應用方向出發(fā)進行構架。
鍵值(key-value)存儲是一張類似于HashTable集合的數(shù)據(jù)結(jié)構的哈希表,能夠根據(jù)結(jié)構中的key值進行存儲,與其對應的value沒有過多的限制,能夠根據(jù)產(chǎn)品的不同進行不同的操作。但是通常情況下的NoSQL數(shù)據(jù)庫不提供針對單獨value值的操作,而是根據(jù)key值開放delet、set等操作,目前常見的鍵值數(shù)據(jù)庫產(chǎn)品為Redis。
文檔(key-文檔)存儲與鍵值存儲類似,但對應的vale值從任意數(shù)值變成了結(jié)構化的文檔。文檔存儲的優(yōu)勢在于只要文檔滿足XML、JSON等存儲格式,就能夠?qū)崿F(xiàn)文檔內(nèi)嵌套的復雜存儲方式。所以文檔存儲可以看作是鍵值存儲的升級版本,目前常見的文檔存儲數(shù)據(jù)庫產(chǎn)品為CouchDB。
列(key-列)存儲在設計上與前兩種截然不同,它是一種能夠以傳統(tǒng)關系結(jié)構的表模型(Table)為基礎,打破了多行進行連續(xù)存儲的方式,從而提高壓縮率和緩存的利用率。但列存儲因為結(jié)構特性有著無法聚集、無法形成唯一索引、無法包含稀疏列等缺點,所以列存儲的應用范圍有限,通常被應用在數(shù)據(jù)倉庫或者匯總上,目前常見的列存儲數(shù)據(jù)庫產(chǎn)品為HBase。
圖存儲是利用圖結(jié)構的算法來實現(xiàn)存儲,常見的圖存儲算法為最短路徑尋址算法。圖存儲的計算方式是基于整個圖進行,所以其復雜算法不適合分布式集群方案。圖存儲的主要應用范圍在社交網(wǎng)絡這類能夠構建出關系圖譜的平臺上,目前常見的圖存儲數(shù)據(jù)庫產(chǎn)品為InfoGrid等。
二、基于NoSQL技術的數(shù)據(jù)庫設計
本次研究所構架NoSQL數(shù)據(jù)庫的方向為鍵值存儲,研究的項目為redis問答系統(tǒng)設計與實現(xiàn),旨在解決用戶對筆者所在學校及其相關辦學情況的疑惑。用戶可以在問答系統(tǒng)上自行發(fā)布問題,由學校內(nèi)部人員進行解答。
(一)總體設計與需求分析
首先,需要對用戶的相關需求進行分析,用戶登錄系統(tǒng)之后需要先對問題進行搜索,借助搜索引擎對問題進行定位;其次,如果用戶沒有發(fā)現(xiàn)相關問題,那么就可以通過自行提問,然后由學校安排特定人員進行登錄解答;最后,用戶對感興趣的問題進行關注,從而隨之對問題答案消息進行接收。所以跟據(jù)以上三種情況,筆者將主要的模塊分為四種:用戶模塊、關注模塊、點贊模塊和問題與評論模塊。全文搜索相關功能需要借助其他框架實現(xiàn),本文不多進行贅述。本次研究項目后臺使用Java,采用了SSM的架構方式。
1.用戶模塊
用戶在瀏覽網(wǎng)站首頁的時候需要進行權限認證,然后跳轉(zhuǎn)至登錄頁面進行登錄,在登錄驗證成功后就可以跳轉(zhuǎn)到之前的目標界面,如果沒有成功再會提示用戶信息出現(xiàn)問題。登錄驗證也分為新用戶和老用戶兩種驗證方式,新用戶需要提交權限認證和注冊,老用戶只需要輸入賬號密碼。
因為學校的用戶規(guī)模有限,并且各個用戶之間的關聯(lián)性較強,所以用戶模塊的數(shù)據(jù)存儲使用的是關系型數(shù)據(jù)庫,并且使用了MD5加密技術進行加密。在用戶模塊字段的描述方面:id表示系統(tǒng)記錄的用戶主鍵序號;name表示賬戶名;password表示密碼;slat表示根據(jù)原始密碼生成的加密技術;head url表示頭像的url。
2.問題與評論模塊
用戶在沒有找到自己想要了解的問題情況下,就需要自行進行發(fā)布請求的提交,這時系統(tǒng)會檢查用戶是否已經(jīng)登錄,如果用戶沒有登錄,就會彈出相應登錄界面。在用戶已經(jīng)登陸的情況下就可以提示用戶是否需要進行問題的發(fā)布,如果需要,就進入相關發(fā)布界面;如果不需要,就進入相關評論界面,兩個界面都需要填寫信息后提交,最終結(jié)果會在對應的界面上顯示。問題與評論模塊是相互對應進行設計的,所以選用的是傳統(tǒng)關系型數(shù)據(jù)庫進行數(shù)據(jù)存儲。
在問題模塊字段的描述方面:id表示系統(tǒng)記錄的問題主鍵序號;title表示標題;content表示內(nèi)容;user-id表示發(fā)布者的用戶表序號;created-time表示創(chuàng)建問題時間;comment-count表示問題下方的評論數(shù)量。
在評論模塊字段的描述方面:id表示系統(tǒng)記錄的評論主鍵序號;content表示評論內(nèi)容;user-id表示發(fā)布者的用戶表序號;entity-id表示評論對象的用戶表序號;entity-type表示評論對象的類型;created time表示創(chuàng)建評論時間。
3.點贊模塊
點贊模塊是優(yōu)化用戶體驗的重要內(nèi)容,如果用戶很喜歡某個答案,就可以點贊來作為認可。首先用戶需要提交點贊請求,系統(tǒng)會檢查用戶是否已經(jīng)登錄,如果用戶沒有登錄,就會彈出相應登錄界面。在用戶已經(jīng)登陸的情況下就可以讓后臺獲取用戶和問題的相關信息,針對用戶的需求進行Redis數(shù)據(jù)庫的操作,操作完成后返回頁面顯示成果。
點贊模塊的設計較為復雜,需要記錄點贊者、被點贊目標和目標得到點贊數(shù)等多項信息才能進行完整的描述,所以關系型數(shù)據(jù)庫已經(jīng)不能夠滿足描述的需要,導致整體點贊行為的讀寫壓力較大,所以筆者采用Redis技術進行數(shù)據(jù)的存儲。
4.關注模塊
關注模塊主要是讓用戶能夠第一時間接收到站內(nèi)的通知,提醒用戶新的答案或者所關注者的新動態(tài)。首先用戶需要提交關注請求,系統(tǒng)會檢查用戶是否已經(jīng)登錄,如果用戶沒有登錄,就會彈出相應登錄界面。在用戶已經(jīng)登陸的情況下就可以讓后臺獲取到用戶和問題的相關信息,針對用戶的需求進行Redis數(shù)據(jù)庫的操作,操作完成后返回頁面顯示成果。
關注模塊是大型網(wǎng)站的主要應用模塊,因為每個用戶都有不溝通的關注和被關注的需求,所以需要根據(jù)用戶建立不同類型的列表,數(shù)據(jù)量龐大,適合Redis這類NoSQL技術數(shù)據(jù)庫的發(fā)揮。具體方法是利用Redis的有序集合將關注實體進行劃分,用戶所關注的其他用戶為entity type(1),所關注的問題為entity type(2),從而確保類型的不同。
(二)Redis問答系統(tǒng)的設計
作為NoSQL數(shù)據(jù)庫的代表,Redis數(shù)據(jù)庫有其固有的優(yōu)勢與劣勢。在一些特定的場景下,非常適合采用Redis數(shù)據(jù)庫存儲數(shù)據(jù),而在其他場景下,Redis有時無法勝任,只能采用傳統(tǒng)的關系型數(shù)據(jù)庫。本節(jié)主要介紹Redis在此問答系統(tǒng)中的設計,并對Redis的適應場景做一般性的總結(jié)。
1.功能型設計
作為一種新興的數(shù)據(jù)庫,NoSQL能夠獨立承擔一些業(yè)務場景的數(shù)據(jù)存儲工作。當存儲的數(shù)據(jù)對結(jié)構化要求不高,比如不需進行join查詢,并且這些數(shù)據(jù)是海量的,無法對數(shù)據(jù)的規(guī)模、數(shù)據(jù)的增長速度進行預期時,就非常適合采用NoSQL數(shù)據(jù)庫,雖然也可使用關系型數(shù)據(jù)庫完成同樣功能,但性能以及擴展性卻遠不如NoSQL數(shù)據(jù)庫。
以此問答系統(tǒng)為例,對問題和評論場景,只需對問題、評論用戶等數(shù)據(jù)進行存儲,無需進行聯(lián)表查詢,對數(shù)據(jù)的結(jié)構化要求不高,而且當系統(tǒng)發(fā)展到一定規(guī)模后,用戶數(shù)據(jù)急劇上漲時,對一個熱點問題的評論數(shù)可能達到萬級別以上,而且這只是單個問題,當熱點問題數(shù)據(jù)規(guī)模達到百級別時,單獨評論功能的數(shù)據(jù)規(guī)模就可以達到百萬級別以上,這些數(shù)據(jù)是相當可觀的。如果采用傳統(tǒng)的關系型數(shù)據(jù)庫,需要額外建立一張表,按照上述數(shù)據(jù)規(guī)模,此表的數(shù)據(jù)可達到百萬條記錄,無疑會對數(shù)據(jù)庫的讀寫帶來極大壓力,并有可能成為系統(tǒng)擴展的瓶頸。
考慮采用Redis實現(xiàn),可以借助Redis內(nèi)置的數(shù)據(jù)結(jié)構set集合實現(xiàn)??梢詾槊總€問題都分配一個集合,集合內(nèi)存放的數(shù)據(jù)即為給此問題點贊的用戶id。由于集合內(nèi)存儲的元素只是用戶的id,即使達到百萬級別,其占用的內(nèi)存也是G級別的,相比內(nèi)存的高效存取,完全可以接受,而且用戶每點贊一次,只需向特定集合內(nèi)增加用戶id即可,無須重復問題id,減少了數(shù)據(jù)冗余。此外,Redis提供了相應的集合操作方法,比如統(tǒng)計每個集合內(nèi)元素數(shù)量scard()、判斷集合內(nèi)是否包含某元素sismember()等,可以方便高效地滿足各種需求。
2.類緩存設計
為了平衡時間與空間的矛盾,考慮使用Redis+MySQL的架構,以Redis作為數(shù)據(jù)的緩存,數(shù)據(jù)的主體部分存儲在關系型數(shù)據(jù)庫MySQL中。每個用戶依然存在一個關注列表,為了減少占用內(nèi)存空間,關注列表不再存儲關注的主體內(nèi)容,而是關注的主鍵記,關注的主體內(nèi)容存儲在MySQL數(shù)據(jù)庫的關注表中,獲取事件id后,再根據(jù)id到MySQL獲取實際內(nèi)容。由于列表內(nèi)只存儲關注的id,其占用的數(shù)據(jù)量大大減少,解決了完全采用Redis存儲大量數(shù)據(jù)冗余的問題;由于根據(jù)關注的主鍵id到MySQL中獲取信息,其效率也大大提高(關系型數(shù)據(jù)中一般都提供根據(jù)主鍵獲取信息的優(yōu)化措施),解決了完全采用MySQL存儲性能低下的問題。
參考文獻:
[1]許鑫,時雷,何龍,等.基于NoSQL數(shù)據(jù)庫的農(nóng)田物聯(lián)網(wǎng)云存儲系統(tǒng)設計與實現(xiàn)[J].農(nóng)業(yè)工程學報,2019,35(1):172-179.
[2]熊英,程玉.大數(shù)據(jù)時代數(shù)據(jù)庫原理及應用教程的教學模式探索[J].教育現(xiàn)代化,2018,5(50):27-29.
[3]劉玉程,李港.NoSQL數(shù)據(jù)庫與關系型數(shù)據(jù)庫對比[J].中國新通信,2018,20(7):81.
[4]洪漪,趙棟祥,趙一鳴.大數(shù)據(jù)環(huán)境下的信息架構與數(shù)據(jù)模型[J].信息資源管理學報,2018,8(1):29-38.
編輯 馮永霞