日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何將關(guān)系型數(shù)據(jù)導(dǎo)入MongoDB?

準(zhǔn)備工作

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、虛擬主機(jī)、營銷軟件、網(wǎng)站建設(shè)、三穗網(wǎng)站維護(hù)、網(wǎng)站推廣。

關(guān)系型數(shù)據(jù)庫已經(jīng)統(tǒng)治數(shù)據(jù)存儲長達(dá)三十幾年的時(shí)間,即便在 2000 年以后誕生了 NoSQL 數(shù)據(jù)庫,但他的出現(xiàn)并沒有改變關(guān)系型數(shù)據(jù)的統(tǒng)治地位。隨著最近幾年互聯(lián)網(wǎng)應(yīng)用的快速崛起,以及互聯(lián)網(wǎng)用戶的不斷增加,數(shù)據(jù)來源越來越復(fù)雜多樣,傳統(tǒng)關(guān)系型數(shù)據(jù)存儲面臨了很大的挑戰(zhàn)。這種挑戰(zhàn)體現(xiàn)在數(shù)據(jù)格式死板,改動困難,存儲不夠靈活,難于擴(kuò)展等方面。因此,很多企業(yè)、公司都先后把數(shù)據(jù)從關(guān)系型遷移到 NoSQL 上來,其中 MongoDB 又是使用相對較廣泛的數(shù)據(jù)庫實(shí)現(xiàn)。本文就為大家分享一下關(guān)系型數(shù)據(jù)導(dǎo)入進(jìn) MongoDB 中應(yīng)當(dāng)遵循的步驟和注意的問題。

在考慮將關(guān)系型數(shù)據(jù)導(dǎo)入到 NoSQL 中時(shí),首先需要確認(rèn)的幾點(diǎn)是:這個(gè)導(dǎo)入過程不會是全自動的,并不是像備份數(shù)據(jù),遷移數(shù)據(jù),記住幾個(gè)命令那么簡單;其次,這個(gè)過程不是一個(gè)純技術(shù)問題,在制定具體方案時(shí),項(xiàng)目經(jīng)理,業(yè)務(wù)分析人員,開發(fā)人員,數(shù)據(jù)庫管理員都應(yīng)當(dāng)參與到方案的討論中。遷移的計(jì)劃、技術(shù)方案、各個(gè)項(xiàng)目負(fù)責(zé)人的職責(zé)應(yīng)當(dāng)在全體人員在場的情況下制定清楚;***,應(yīng)當(dāng)考慮到遷移失敗以后的恢復(fù)方案,根據(jù)應(yīng)用數(shù)據(jù)的復(fù)雜程度不同,遷移的工作量也不會完全一樣。

上圖列出了一個(gè)項(xiàng)目經(jīng)過關(guān)系型數(shù)據(jù)向 NoSQL 中遷移的大致步驟,當(dāng)然這絕對不是一個(gè)唯一的標(biāo)準(zhǔn)。只是通常情況下的做法,可能會根據(jù)不同項(xiàng)目的特別需求有一些調(diào)整。下面我們來詳細(xì)分析每一個(gè)階段的具體工作內(nèi)容。

數(shù)據(jù)模型定義

有可能你會覺得奇怪,MongoDB 不是結(jié)構(gòu)無關(guān)的 NoSQL 數(shù)據(jù)庫嗎?為什么我們要提到數(shù)據(jù)庫表結(jié)構(gòu)定義。實(shí)際上,NoSQL 中的結(jié)構(gòu)是指從技術(shù)層面來講,數(shù)據(jù)庫對表結(jié)構(gòu)沒有強(qiáng)約束,任何格式的 JSON 都可以插入進(jìn) MongoDB 表中。但是,我們在做項(xiàng)目時(shí)不能為所欲為的在數(shù)據(jù)庫中插入數(shù)據(jù),一定要遵循我們自己定義的一套規(guī)則來進(jìn)行,否則程序根本無法管理數(shù)據(jù)層面的業(yè)務(wù)邏輯。在討論表結(jié)構(gòu)之前,先來看一下 MongoDB 中的一些術(shù)語和關(guān)系型數(shù)據(jù)庫的對應(yīng)關(guān)系。

看起來很好理解,在 MongoDB 中我們把表稱做Collection,表中每一行的數(shù)據(jù)稱作Document。其他的基本沿用關(guān)系型數(shù)據(jù)庫的命名。在 MongoDB 中,所有的數(shù)據(jù)格式都是以 JSON 為數(shù)據(jù)庫類型,它能夠比較靈活的存儲各種數(shù)據(jù)庫關(guān)系。這也是為什么 MongoDB 能夠在一個(gè) Collection 中存儲各種不同結(jié)構(gòu)的數(shù)據(jù)。比如,你可以插入這樣一個(gè) JSON 到 MongoDB 中:{"user": {"name": "Zhang San", }},另外再插入這個(gè) JSON{"product": {"id": "00001"}}??梢钥吹竭@兩個(gè) JSON 沒有任何關(guān)系,也沒有任何相同的屬性,但在 MongoDB 中都是合法的數(shù)據(jù),他們可以同時(shí)存在于一個(gè) Collection 中。當(dāng)然,我們并不鼓勵(lì)大家這樣做,因?yàn)檫@樣很難維護(hù)你的數(shù)據(jù)庫表格,而且對于查詢索引來說也很麻煩,會產(chǎn)生很多不必要的索引存儲。我們所說的結(jié)構(gòu)靈活指的是在一個(gè)結(jié)構(gòu)框架基礎(chǔ)上,可以靈活擴(kuò)充、添加新的數(shù)據(jù)而不用重新定義數(shù)據(jù) Schema。因此,我們在進(jìn)行數(shù)據(jù)庫遷移之前需要討論如何定義 Collection 的結(jié)構(gòu)。

MongoDB 將 JSON 存儲成一個(gè)叫BSON的數(shù)據(jù)結(jié)構(gòu)中,BSON指的是Binary JSON,二進(jìn)制 JSON,并在 JSON 的基礎(chǔ)上添加了一些新的數(shù)據(jù)類型,int,float,long。JSON 格式可以靈活的存儲嵌入式數(shù)據(jù)結(jié)構(gòu),以及數(shù)組,要是在關(guān)系型數(shù)據(jù)庫中實(shí)現(xiàn)其難度是很難想象的。在定義Collection 結(jié)構(gòu)時(shí),需要根據(jù)應(yīng)用程序?qū)嶋H需求找出數(shù)據(jù)模型的定義,***程度的利用 MongDB 的存儲靈活性。例如,下面是一個(gè)典型的兩張一對多的數(shù)據(jù)庫表格。

學(xué)生表:

成績表:

其中,***張表是學(xué)生表,第二張是學(xué)生成績表,一個(gè)學(xué)生可以有多門課程的成績,因此他們之間是一對多的關(guān)系,其中studnet_id在學(xué)生表中是主鍵,對應(yīng)成績表中的外鍵。在關(guān)系型數(shù)據(jù)庫中這種表示方法***并正確,但是到了 MongoDB 中也許就是另外一種存儲樣式了。為了充分利用 JSON 格式的內(nèi)嵌式存儲,我們通常會把這種關(guān)系存儲到 Collection 中的一條記錄(Document),如下所示:

上面是對學(xué)生 Zhang Scan 的記錄存儲,可以看出我們把學(xué)生成績當(dāng)作是學(xué)生表的內(nèi)嵌字段,由于是一對多的關(guān)系,我們把他存儲成一個(gè)數(shù)組的形式。這種基于 JSON 文檔的存儲結(jié)構(gòu)有一下幾點(diǎn)優(yōu)勢:

  • 數(shù)據(jù)一目了然,當(dāng)你從數(shù)據(jù)庫中取出一條學(xué)生記錄后,關(guān)于學(xué)生的基本信息全部顯示出來。方便大家閱讀瀏覽。
  • 避免了多次數(shù)據(jù)庫表連接操作。在關(guān)系型數(shù)據(jù)庫中存在著多種表之間的鏈接操作,比如左右連接,內(nèi)連,外連等等。為了找到關(guān)于一個(gè)學(xué)生的全部信息,我們也許需要進(jìn)行若干張表的連接才能拿到想要的數(shù)據(jù)。除了需要寫更復(fù)雜的 SQL 語句以外,數(shù)據(jù)庫的性能也會受到影響。當(dāng)數(shù)據(jù)庫進(jìn)行一次連接操作時(shí),內(nèi)部可能是需要從磁盤不同位置讀取數(shù)據(jù),加大了 IO 操作。反觀 MongoDB,一次查詢只需要讀取一次磁盤,大大提高的查詢效率。
  • 刪除、修改操作簡單方便。如果所有相關(guān)學(xué)生的信息都存儲在一張 Collection 中,那么對學(xué)生信息的刪除和修改只需要在一張表中操作就可以。試想一下在關(guān)系型數(shù)據(jù)庫中,如果需要?jiǎng)h除一個(gè)學(xué)生紀(jì)錄,有可能需要操作學(xué)生表、成績表、宿舍表、等等與學(xué)生關(guān)聯(lián)的所有表,這樣的設(shè)計(jì)是困擾關(guān)系型數(shù)據(jù)庫開發(fā)人員的一大難題。搞不好數(shù)據(jù)庫中就會存儲大量過時(shí)、失效的數(shù)據(jù),而這些數(shù)據(jù)可能成為永遠(yuǎn)也不會被訪問的死角。
  • 所有 Document 都是自我描述的,這方便大家進(jìn)行數(shù)據(jù)庫的水平擴(kuò)展。在 MongoDB Shard 中,我們可以將一個(gè) Collection 切分到不同的 Shard 集群中,這種切分方法在不需要進(jìn)行 JOIN 的操作前提下變得十分簡單。因?yàn)椋珼BA 再不用擔(dān)心需要進(jìn)行夸節(jié)點(diǎn)的 JOIN 操作。(關(guān)于 MongoDB 水平擴(kuò)展的內(nèi)容,情參考另外一篇文章MongoDB 的水平擴(kuò)展,你做對了嗎?。

內(nèi)嵌還是引用

上面是一個(gè)將一對多關(guān)系的兩張表整合到一個(gè) Document 中,實(shí)際上我們的數(shù)據(jù)表結(jié)構(gòu)會復(fù)雜很多,一個(gè)企業(yè)級應(yīng)用動輒就要設(shè)計(jì)幾百甚至上千張表,表之間會有一對一,一對多,多對多種關(guān)聯(lián)關(guān)系。對于如此復(fù)雜的場景目前我們還沒有一個(gè)準(zhǔn)確的可以使用任何情況的解決方案?;旧隙夹枰槍I(yè)務(wù)數(shù)據(jù)具體分析,從而得出新的數(shù)據(jù)結(jié)構(gòu)。這里,我可以給大家列出一些基本的原則以及處理不同關(guān)系的基本方法,根據(jù)這些基本原則方法我想大家總可以根據(jù)自己的業(yè)務(wù)歸納出一個(gè)行之有效的解決方案。具體到 MongoDB,有內(nèi)嵌和飲用兩種方式來進(jìn)行關(guān)聯(lián),下面我們分布看一下它們應(yīng)用的場景。

 內(nèi)嵌

就像上面舉的例子那樣,將關(guān)系型數(shù)據(jù)中表的一行內(nèi)嵌到與他相關(guān)聯(lián)的表中使之在新的 Collection 中成為一個(gè) Document。這種內(nèi)嵌的方法適用于兩種情況:

  • 當(dāng)表關(guān)系是一對一時(shí),或者
  • 當(dāng)表關(guān)系是一對多時(shí)

在上面兩種關(guān)系下,如果關(guān)系表不經(jīng)常單獨(dú)進(jìn)行查詢,它只是依附在主表查詢的基礎(chǔ)上進(jìn)行,那么我們可以考慮使用內(nèi)嵌的方法。以產(chǎn)品和產(chǎn)品價(jià)格為例說明一下,在紀(jì)錄產(chǎn)品價(jià)格時(shí),價(jià)格是會隨著時(shí)間的變化而取不同的值。一款新上線的產(chǎn)品價(jià)格相對較高,隨著時(shí)間的推移其價(jià)格也會隨之下降。在一些類似雙十一節(jié)假日期間,價(jià)格也會臨時(shí)調(diào)整。在分析產(chǎn)品銷售狀況的時(shí)候,我們還要考慮到在什么樣的價(jià)格下產(chǎn)品銷量高,所以不能簡單的把產(chǎn)品和價(jià)格放到一張表中,必然會存在一張與產(chǎn)品相關(guān)聯(lián)的價(jià)格表,它紀(jì)錄了產(chǎn)品當(dāng)前價(jià)格以及歷史價(jià)格。那么,我們在統(tǒng)計(jì)產(chǎn)品的銷量報(bào)表時(shí),這張價(jià)格表不會單獨(dú)存在,它必然會依附在產(chǎn)品表之下。此時(shí),將產(chǎn)品價(jià)格內(nèi)嵌到產(chǎn)品表中就是一個(gè)比較可行的方案。查詢語句可以通過一個(gè) Collection 找出所有產(chǎn)品相關(guān)價(jià)格從而避免了表之間的 JOIN 操作。

但是并不是所有的一對一和一對多的關(guān)系都適合使用內(nèi)嵌的方式。在一下情況下應(yīng)當(dāng)慎重使用內(nèi)嵌數(shù)據(jù)結(jié)構(gòu):

  • 如果一個(gè) Document 的大小超過了 MongoDB 的限制(16M),此時(shí)不應(yīng)考慮嵌入數(shù)據(jù)結(jié)構(gòu)。當(dāng)你的數(shù)據(jù)表關(guān)系很復(fù)雜,可能將所有相關(guān)的數(shù)據(jù)內(nèi)嵌到一個(gè) Document 中會超過 16M 的限制。
  • 如果一個(gè) Document 需要經(jīng)常被訪問,而其中的一個(gè)內(nèi)嵌 Document 很少被訪問到,這時(shí)不太適合使用內(nèi)嵌;因?yàn)檫@會使 MongoDB 在檢索數(shù)據(jù)時(shí)增加內(nèi)存的消耗。
  • 如果一個(gè) Document 中的一個(gè)內(nèi)嵌 Document 需要經(jīng)常修改,或者大小經(jīng)常發(fā)生變化,而另一個(gè)內(nèi)嵌 Document 相對靜態(tài),這是也不要考慮使用內(nèi)嵌結(jié)構(gòu)。
  • 由于內(nèi)嵌 Document 的增加和減少會導(dǎo)致整個(gè) Document 大小發(fā)生變化,當(dāng)變化超過了分配給 Document 的磁盤空間時(shí)會導(dǎo)致數(shù)據(jù)庫從新為 Document 分配空間。

 引用

除了內(nèi)嵌之外還可以使用引用的方式來關(guān)聯(lián)數(shù)據(jù)。引用的方式和關(guān)系型數(shù)據(jù)庫表的主外鍵很想。你可以把主表和外鍵表分別存儲成一個(gè) Collection,然后用他們的_id進(jìn)行關(guān)聯(lián),_id是 MongoDB 文檔中一個(gè)比較特殊的字段,他會被 MongoDB 自動生成并且唯一存在在一個(gè) Collection 中。但是,在使用引用的時(shí)候需要注意一下幾點(diǎn):

在一些復(fù)雜的多對多關(guān)系表中,不要嘗試引用,因?yàn)檫@會加大應(yīng)用程序邏輯上的開發(fā)和維護(hù)。

當(dāng)使用內(nèi)嵌結(jié)構(gòu)產(chǎn)生過多重復(fù)數(shù)據(jù)的時(shí)候,可以考慮使用引用。

雖然 MongoDB 不支持 JOIN 操作,但是可以通過 Aggregation 中的$lookup指令來完成連接多表的操作請求。

應(yīng)用集成

有了數(shù)據(jù)模型的定義,我們就可以開始進(jìn)行應(yīng)用集成。集成的方法可以使用 MongoDB 的 Driver,它支持了幾乎常用的各種計(jì)算機(jī)語言。使用簡單和開發(fā)效率高是 MongoDB 的兩大特點(diǎn)。于 SQL 語句不同的是,MongoDB 采用了 API 的方法提供接口,開發(fā)人員可以選擇支持自己熟悉語言的 Driver,DBA 可以直接使用 Mongo Shell 腳本。幸運(yùn)的是,MongoDB 提供了 API 和 SQL 語句的對照表供大家參考,SQL to MongoDB Mapping Chart。

另一個(gè)強(qiáng)大的功能不能不提的是 Aggregation Framework(聚合)。并不是所有 NoSQL 數(shù)據(jù)庫都支持 Aggregation,簡單理解 Aggregation 可以把它當(dāng)成是 Hadoop 里面的 Map Reduce,或者 SQL 里面的 Left Join。在沒有 Aggregation 的情況下,開發(fā)人員進(jìn)行數(shù)據(jù)遷移不得不進(jìn)行如下操作:

  • 在應(yīng)用程序?qū)娱_發(fā)類似 Aggregation 的功能,將數(shù)據(jù)聚合在一起并寫進(jìn)數(shù)據(jù)庫。這樣做加大了應(yīng)用程序的復(fù)雜度,并且很難適應(yīng)各種不同數(shù)據(jù)的組合情況。沒遇到一個(gè)新的需求都需要進(jìn)行一定量的開發(fā)工作。
  • 有些人會把數(shù)據(jù)到如今 Hadoop,然后在上面運(yùn)行 MapReduce 生成結(jié)果,之后將結(jié)果倒進(jìn) NoSQL 中。這是一個(gè)折中的方法,但是他并不支持實(shí)時(shí)數(shù)據(jù)遷移,只能進(jìn)行線下操作。

MongoDB 支持原生 Aggregation 操作,你可以把需要遷移的數(shù)據(jù)進(jìn)行聚合操作,每一次操作可以想象成一個(gè)流水線上的環(huán)節(jié),將所有的操作連接起來可以構(gòu)成一條 Aggregation Pipeline。在 Pipeline 上面的每一個(gè)節(jié)點(diǎn)都有自己的輸入輸出,前一個(gè)節(jié)點(diǎn)的輸出是下一個(gè)節(jié)點(diǎn)的輸入。有興趣的同學(xué)可以在這個(gè)連接上找到更多的關(guān)于 Aggregation 操作,它列出了每一個(gè) Aggregation 命令和 SQL 語句的對應(yīng)關(guān)系,SQL to Aggregation Mapping Chart

 數(shù)據(jù)完整性

在關(guān)系型數(shù)據(jù)庫中,有很多支持 ACID 事務(wù)操作的方法和應(yīng)用,DBA 并不希望在數(shù)據(jù)遷移的過程中有任何閃失,例如損失數(shù)據(jù)完整性。MongoDB 在這方面具有不同形式的支持。在 3.0 以上版本中,MongoDB 支持了 WiredTiger Storage Engine,他支持了 Document 級別上的鎖操作。也就是說,在進(jìn)行數(shù)據(jù)庫寫操作時(shí),MongoDB 可以保證針對一個(gè) Document 操作的原子性,這個(gè)操作可以和其他操作完全分隔開來。除了對單個(gè) Dcoument 的原子操作支持外,MongoDB 還支持多 Document 的事務(wù),比如,findAndModify方法允許你在進(jìn)行多個(gè)文檔操作的時(shí)保持事務(wù)完整。再比如,可以通過Perform Two Phase Commits實(shí)現(xiàn)更新多個(gè)文檔的原子操作,更多信息請?jiān)L問 Perform Two Phase Commits。

 數(shù)據(jù)一致性

在數(shù)據(jù)一致性方面,MongoDB 通過 Read Preference 來調(diào)節(jié)一致性的程度。默認(rèn)情況下,在一個(gè) MongoDB Replica Set 中,所有的數(shù)據(jù)庫讀操作都會發(fā)到 Primary 服務(wù)器上,Replica Set 中的所有 Secondary 保證數(shù)據(jù)最終一致性。同時(shí),MongoDB 提供了修改這種一致性的行為方式。數(shù)據(jù)庫管理員可以通過修改 Read Preference 參數(shù)達(dá)到對一致性不同要求的場景。數(shù)據(jù)一致性可以有下面集中方案:

  • primary: 默認(rèn)模式,所有請求都會發(fā)送到 Primary 上。
  • primaryPreferred:大部分讀請求都會發(fā)送到 Primary,但是當(dāng) Primary 無法訪問時(shí),改請求會被轉(zhuǎn)發(fā)到 Secondary 上。
  • secondary: 所有請求都會發(fā)送到 Secondary 上。
  • secondaryPreferred: 大部分情況下,讀請求被發(fā)送到 Secondary 中,但是如果 Replica 中沒有 Secondary,請求會發(fā)送到 Primary 上。
  • nearest: 請求會被發(fā)送到網(wǎng)絡(luò)最近的服務(wù)器上。該模式在多數(shù)據(jù)中心上非常有效。

 數(shù)據(jù)遷移

進(jìn)行完上面的設(shè)計(jì)和思考以后,數(shù)據(jù)遷移就會變得想對容易。將數(shù)據(jù)導(dǎo)入進(jìn) MongoDB 有幾個(gè)不同的選擇,可以使用 mongoimport 將 JSON 數(shù)據(jù)進(jìn)行導(dǎo)入,也可以通過 ETL(Extract Transform Load) 工具完成。很多項(xiàng)目允許在當(dāng)前應(yīng)用程序運(yùn)行的情況下并行遷移關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù),并且支持增量更新,具體操作如下:

  • 當(dāng)一條記錄從關(guān)系型數(shù)據(jù)庫讀出后,應(yīng)用程序會將這條記錄按照先前定義的 JONS 格式插入到 MongoDB 中。
  • 一致性檢查,可以通過 MD5 等方法進(jìn)行數(shù)據(jù)一致性檢查。
  • 新的插入操作和數(shù)據(jù)修改操作全部轉(zhuǎn)到 MongoDB 中完成。

小結(jié)

按照本文提供的方法和步驟,項(xiàng)目團(tuán)隊(duì)可以在數(shù)據(jù)遷移中減少不必要的時(shí)間和錯(cuò)誤的操作。當(dāng)然,數(shù)據(jù)永遠(yuǎn)是應(yīng)用系統(tǒng)中的核心內(nèi)容,任何數(shù)據(jù)遷移都需要支持錯(cuò)誤恢復(fù),如果失敗也要能夠快速恢復(fù)到以前的版本上。在這方面,MongoDB 做到了更靈活的支持,具體內(nèi)容可以參考

MongoDB Webnar。

參考文獻(xiàn)

[Data Modeling]

(https://docs.mongodb.com/manual/core/data-modeling-introduction/)

[SQL to MongoDB Mapping Chart]

(https://docs.mongodb.com/manual/reference/sql-comparison/)

[SQL to Aggregation Mapping Chart]

(https://docs.mongodb.com/manual/reference/sql-aggregation-comparison/)

[WiredTiger Storage Engine]

(https://docs.mongodb.com/manual/core/wiredtiger/)

[Perform Two Phase Commits]

(https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/)


網(wǎng)站標(biāo)題:如何將關(guān)系型數(shù)據(jù)導(dǎo)入MongoDB?
轉(zhuǎn)載來源:http://www.5511xx.com/article/ccdspig.html