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