国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - MongoDB - NoSQL反模式 - 文檔數(shù)據(jù)庫篇

NoSQL反模式 - 文檔數(shù)據(jù)庫篇

2020-04-28 15:01hebedich MongoDB

我們設(shè)計(jì)關(guān)系數(shù)據(jù)庫Schema的都有一套完整的方案,而NoSQL卻沒有這些。半年前筆者讀了本《SQL反模式》的書,覺得非常好。就開始留意,對于NoSQL是否也有反模式?好的反模式可以在我們設(shè)計(jì)Schema告訴哪里是陷阱和懸崖。

我們設(shè)計(jì)關(guān)系數(shù)據(jù)庫Schema的都有一套完整的方案,而NoSQL卻沒有這些。半年前筆者讀了本《SQL反模式》的書,覺得非常好。就開始留意,對于NoSQL是否也有反模式?好的反模式可以在我們設(shè)計(jì)Schema告訴哪里是陷阱和懸崖。NoSQL宣傳的時(shí)候往往宣稱是SchemaLess的,這會讓人誤解其不需要設(shè)計(jì)Schema。但如果不意識到設(shè)計(jì)Schema的必要,陷阱就在一直在黑暗中等著我們。這篇文章就總結(jié)一些別人的,也有自己犯過的深痛的設(shè)計(jì)Schema錯(cuò)誤。

NoSQL數(shù)據(jù)庫最主流的有文檔數(shù)據(jù)庫,列存數(shù)據(jù)庫,鍵值數(shù)據(jù)庫。三者分別有代表作MongoDB,HBase和Redis。如果將NoSQL比作兵器的話,可以這樣(MySQL是典型的關(guān)系型數(shù)據(jù)庫,一樣參與比較):

NoSQL反模式 - 文檔數(shù)據(jù)庫篇

MySQL產(chǎn)生年代較早,而且隨著LAMP大潮得以成熟。盡管其沒有什么大的改進(jìn),但是新興的互聯(lián)網(wǎng)使用的最多的數(shù)據(jù)庫。就像傳統(tǒng)的菜刀,結(jié)構(gòu)簡單,幾百年沒有改進(jìn)。但是不妨礙產(chǎn)生各式各樣的刀法,只要有一把,就能勝任廚房里的大部分事務(wù)。MySQL也是一樣,核心已經(jīng)穩(wěn)定。但是切庫,分表,備份,監(jiān)控,等等手段一應(yīng)俱全。MongoDB是個(gè)新生事物,提供更靈活的Schema,Capped Collection,異步提交,地理位置索引等五花十色的功能。就像瑞士軍刀,不但可以當(dāng)?shù)队茫€可以開瓶蓋,剪指甲。但是他也不比MySQL強(qiáng),因?yàn)檫€缺乏時(shí)間的磨礪。一是系統(tǒng)本身的穩(wěn)定性,二是開發(fā),運(yùn)維需要更多經(jīng)驗(yàn)才能流行。HBase是個(gè)仗勢欺人的大象兵。依仗著Hadoop的生態(tài)環(huán)境,可以有很好的擴(kuò)展性。但是就像象兵一樣,使用者需要養(yǎng)一頭大象(Hadoop),才能驅(qū)使他。Redis是鍵值存儲的代表,功能最簡單。提供隨機(jī)數(shù)據(jù)存儲。就像一根棒子一樣,沒有多余的構(gòu)造。但是也正是因此,他的伸縮性特別好。就像悟空手里的金箍棒,大可捅破天,小能成縮成針。文檔數(shù)據(jù)庫的得失

關(guān)系模型試圖將數(shù)據(jù)庫模型和數(shù)據(jù)庫實(shí)現(xiàn)分開,讓開發(fā)者可以脫離底層很好的操作數(shù)據(jù)。但筆者以為關(guān)系模型在一些應(yīng)用場景下有弱點(diǎn),現(xiàn)在已經(jīng)不得不面對。

SQL弱點(diǎn)一:必須支持Join。因?yàn)閿?shù)據(jù)不能夠有重復(fù)。所以使用范式的關(guān)系模型會不可避免的大量Join。如果參與Join的是一張比內(nèi)存小的表還好。但是如果大表Join或者表分布在多臺機(jī)器上的話,Join就是性能的噩夢。SQL弱點(diǎn)二:計(jì)算和存儲耦合。關(guān)系模型作為統(tǒng)一的數(shù)據(jù)模型既可以用于數(shù)據(jù)分析,也可以用于在線業(yè)務(wù)。但這兩者一個(gè)強(qiáng)調(diào)高吞吐,一個(gè)強(qiáng)調(diào)低延時(shí),已經(jīng)演化出完全不同的架構(gòu)。用同一套模型來抽象顯然是不合適的。Hadoop針對的就是計(jì)算的部分。MongoDB,Redis等針對在線業(yè)務(wù)。兩者都拋棄了關(guān)系模型。

針對這兩個(gè)夢魘。文檔數(shù)據(jù)庫如MongoDB的的主要目的是 提供更豐富的數(shù)據(jù)結(jié)構(gòu)來拋棄Join來適應(yīng)在線業(yè)務(wù)。當(dāng)然也不是MongoDB完全不能用Join,不能拿來做數(shù)據(jù)分析,討論這個(gè)只是見仁見智的問題。所以文檔數(shù)據(jù)庫并不比關(guān)系數(shù)據(jù)庫強(qiáng)大,由于對Join的弱支持,功能會弱許多。設(shè)計(jì)關(guān)系模型的時(shí)候,通常只需要考慮好數(shù)據(jù)直接的關(guān)系,定義數(shù)據(jù)模型。而設(shè)計(jì)文檔數(shù)據(jù)庫模型的時(shí)候,還需要考慮應(yīng)用如何使用。因此設(shè)計(jì)好一個(gè)的文檔數(shù)據(jù)庫Schema比設(shè)計(jì)關(guān)系模型更加的困難。除此之外,由于文檔數(shù)據(jù)庫事務(wù)的支持也是比較弱,一般NoSQL只會提供一個(gè)行鎖。這也給設(shè)計(jì)Schema更加增加了難度。對于文檔數(shù)據(jù)庫的使用有很多需要注意的地方,本文只關(guān)注模型設(shè)計(jì)的部分。

反模式一:慣性思維/沿用關(guān)系模型

關(guān)系模型是數(shù)據(jù)存儲的經(jīng)典模型,使用數(shù)據(jù)模型范式的好處非常的明顯。但是由于文檔數(shù)據(jù)庫不支持Join(包括和外鍵息息相關(guān)的外鍵約束)等特性,習(xí)慣性的沿用關(guān)系模型有的時(shí)候會出現(xiàn)問題。需要利用起文檔數(shù)據(jù)庫提供的豐富的數(shù)據(jù)模型來應(yīng)對。

值得一提的是文檔數(shù)據(jù)庫的設(shè)計(jì)和關(guān)系模型不同,是靈活多樣的。對于同一個(gè)情形,可以設(shè)計(jì)出有多種能夠工作的模型,沒有絕對意義上最好的模型。

下圖是關(guān)系模型和文檔模型的對比。

NoSQL反模式 - 文檔數(shù)據(jù)庫篇

關(guān)系模型 VS 文檔模型

這個(gè)一個(gè)博客的數(shù)據(jù)模型,有Blog,User等表。左側(cè)是關(guān)系模型,右側(cè)是文檔模型。這個(gè)文檔模型并不是完全合理,可以作為“正反兩面教材”在下文不斷闡述。

問題一:存在描述多對多的關(guān)系表癥狀:文檔數(shù)據(jù)庫中存儲在有純粹的關(guān)系表,例如:

 

id

user_id

blog_id

0

0

0

1

0

1

這樣的表就算在關(guān)系模型中也是不妥的,因?yàn)檫@個(gè)ID非常的多余,可以用聯(lián)合主鍵來解決。但是在文檔數(shù)據(jù)庫中,由于必須強(qiáng)制單主鍵,不得不采取這樣的設(shè)計(jì)。

 

壞處:

破壞數(shù)據(jù)完備性。由于ID是主鍵,在數(shù)據(jù)模型上沒有約束來保證不出現(xiàn)重復(fù)的user_id,blog_id對。一旦數(shù)據(jù)出現(xiàn)重復(fù),更新刪除都是問題。索引過多。由于是關(guān)系表,必須在user_id和blog_id上面分別建一個(gè)索引。影響性能。

解決方案:使用文檔數(shù)據(jù)庫典型的處理多對多的辦法。不是建立一張關(guān)系表,而是在其中一個(gè)文檔(如User)中,加入一個(gè)List字段。

 

user_id

user_name

blog_id[]

……

0

Jake

0,1

……

1

Rose

1,2

……

 

問題二:沒有區(qū)分"一對多關(guān)系"和“多對一關(guān)系”癥狀:關(guān)系模型不區(qū)分“一對多”和“多對一”,對于文檔數(shù)據(jù)庫來講,關(guān)系模型只有“多對一”。就像這張Comment表:

 

comment_id

user_id

content

……

0

0

“NoSQL反模式是好文章”

……

1

0

“是啊”

……

 

如果整個(gè)模型都是這樣的“多對一”關(guān)系就需要反思了。

壞處:

額外索引。如果客戶端已知user_id,需要獲得User信息和Comment信息,需要執(zhí)行兩次查詢。其中一次查詢需要使用索引。并且要在客戶端自己Join。這樣可能有潛在性能問題。

解決方案:問題的核心在于是已知user_id查詢兩張表,還是已知comment_id查詢兩張表。如果是已知comment_id這樣的設(shè)計(jì)就是合理的,但是如果是已知user_id來查詢,把關(guān)系放在user表里的設(shè)計(jì)更合理一些。

 

user_id

user_name

comment_id[]

……

0

Jake

0,1

……

1

Rose

1,2

……

 

這樣的設(shè)計(jì),就可以避免一個(gè)索引。同理,對于多對多也是一樣的,通過合理的安排字段的位置可以避免索引。

正確使用的場合:

關(guān)系型模型是非常成功的數(shù)據(jù)模型,合理的沿用是非常好的。但是由于文檔數(shù)據(jù)庫的特點(diǎn),需要適當(dāng)?shù)恼{(diào)整,這樣得出的數(shù)據(jù)模型,盡管性能不是最優(yōu),但是有最好的靈活性。并且也有利于和關(guān)系數(shù)據(jù)庫轉(zhuǎn)換。

反模式二:處處引用客戶端Join

癥狀:數(shù)據(jù)庫設(shè)計(jì)中充滿了xx_id的字端,在查詢的時(shí)候需要大量的手動(dòng)Join操作。就涉及到了這個(gè)反模式。正如上面提到的博客的關(guān)系模型,如果已知blog_id查詢comments,需要至少執(zhí)行3次查詢,并且手動(dòng)Join。

壞處:

手動(dòng)Join,麻煩且易出錯(cuò)。文檔數(shù)據(jù)庫不支持Join且沒有外鍵保證。因此需要在客戶端Join,這樣的操作對于軟件開發(fā)來講是比較繁瑣的。由于沒有外鍵保證,因此不能保證取得的ID在數(shù)據(jù)庫里面是有數(shù)據(jù)的。在處理的時(shí)候需要不斷判斷,容易出錯(cuò)。多次查詢。如果引用過多,查詢的時(shí)候需要多次查詢才能查到足夠的數(shù)據(jù)。本來文檔數(shù)據(jù)庫是很快的,但是由于多次查詢,給數(shù)據(jù)庫增加了壓力,獲取全部數(shù)據(jù)的時(shí)間也會增加。事務(wù)處理繁瑣。文檔數(shù)據(jù)庫一般不支持一般意義上事務(wù),只支持行鎖。如果文檔數(shù)據(jù)庫有給多個(gè)連接。在插入的時(shí)候,事務(wù)的處理就是噩夢。在文檔數(shù)據(jù)庫中使用事務(wù),需要使用行鎖,在進(jìn)行大量的處理。太過繁瑣,感興趣的讀者可以搜一下。

解決方案:適當(dāng)使用內(nèi)聯(lián)數(shù)據(jù)結(jié)構(gòu)。由于文檔數(shù)據(jù)庫支持更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)可以將引用轉(zhuǎn)換為內(nèi)聯(lián)的數(shù)據(jù),而不用新建一張表。這樣做可以解決上面的一些問題,是一個(gè)推薦的方案。就像上面博客的例子一樣。將五張表簡化成了兩張表。那什么時(shí)候使用內(nèi)聯(lián)呢?一般認(rèn)為

使用內(nèi)聯(lián)可以解決讀性能問題,明顯減少Q(mào)uery的次數(shù)的時(shí)候。可以簡化數(shù)據(jù)模型,化簡表之間的關(guān)系,而同時(shí)不會影響靈活性的時(shí)候。事務(wù)可以得到簡化為單行事務(wù)的時(shí)候正確使用的場合:

范式化的使用場景,文檔數(shù)據(jù)庫會被多個(gè)應(yīng)用使用。由于數(shù)據(jù)庫設(shè)計(jì)無法估計(jì)多個(gè)應(yīng)用現(xiàn)在及將來的查詢情況,需要極大的靈活性。在這個(gè)時(shí)候,使用引用比內(nèi)聯(lián)靠譜。

反模式三 濫用內(nèi)聯(lián)后患無窮

問題一 妨礙到查詢的內(nèi)聯(lián)癥狀:頻繁查詢一些內(nèi)聯(lián)字段,丟棄其他字段。

壞處:

無ID約束:使用內(nèi)聯(lián)字段和引用不同,是沒有ID約束的。因此不能通過ID(主鍵)來管理,如果經(jīng)常需要單獨(dú)操作內(nèi)聯(lián)對象會非常不便。索引泛濫:如果以內(nèi)聯(lián)字段為條件進(jìn)行查詢,需要建立索引。有可能造成索引泛濫。性能浪費(fèi):大部分文檔數(shù)據(jù)庫的實(shí)現(xiàn)是按行存儲的,也就意味著,盡管只查詢一個(gè)字段,但是DB需要將整行從磁盤中取出。如果字段夠小,文檔夠大,是很不合算的。

解決方案:如果出現(xiàn)以上的癥結(jié),就可以考慮使用引用代替內(nèi)聯(lián)了。內(nèi)聯(lián)特性主要的用途在于提高性能,如果出現(xiàn)性能不升反降,那就沒有意義了。如果對性能有很強(qiáng)烈的要求,可以考慮使用重復(fù)數(shù)據(jù),同樣的數(shù)據(jù)即在內(nèi)聯(lián)字段中也在引用的表里面。這樣可以結(jié)合內(nèi)聯(lián)和引用的性能優(yōu)勢。缺點(diǎn)是數(shù)據(jù)出現(xiàn)重復(fù),維護(hù)會比較麻煩。

問題二 無限膨脹的內(nèi)聯(lián)癥狀:List,Map類型的內(nèi)聯(lián)字段不斷膨脹,而且沒有限制。就像前面提到的Blog的內(nèi)聯(lián)字段Comment。如果對每一篇Blog的Comment數(shù)量沒有限制的話,Comment會無限膨脹。輕則影響性能,重則插入失敗。

 

Blog_id

content

Comment[]

……

0

“…”

“NoSQL反模式是好文章”, “是啊”,”無限增長中”…

……

壞處:

 

插入失敗。文檔數(shù)據(jù)庫的每條記錄都有最大大小,并且也有推薦最佳的大小。一般不會超過4M。就像剛剛提到的例子,如果是篇熱門的博文的話,評論的大小很容易就超過4M。屆時(shí)文檔將無法更新,新的評論無法插入。性能拖油瓶。由于內(nèi)聯(lián)字段膨脹,其大小將遠(yuǎn)遠(yuǎn)超過其他部分,影響其他部分的性能表現(xiàn)。并且因此導(dǎo)致該記錄大小頻繁變化,對檔數(shù)據(jù)庫的數(shù)據(jù)文件內(nèi)部可能因此產(chǎn)生很多碎片。

解決方案:設(shè)定最大數(shù)目或者使用引用。還是Blog和Comment的例子,可以將Comment從Blog中剝離出成一張表。如果考慮到性能,可以在Blog表中新建一個(gè)字段如最近的評論。這樣既保證了性能,又能夠預(yù)防膨脹。

 

Blog_id

content

last_five_comment[]

……

0

“…”

“NoSQL反模式是好文章”, “是啊”,”最多5條”…

……

問題三 無法維護(hù)的內(nèi)聯(lián)癥狀:DBA想單獨(dú)維護(hù)內(nèi)聯(lián)字段,但無法做到。

 

壞處:

權(quán)限管理難。數(shù)據(jù)庫的權(quán)限管理的最小粒度是表。如果使用內(nèi)聯(lián)技術(shù),就意味著內(nèi)聯(lián)部分必須和其他字段用同一個(gè)權(quán)限來管理。沒有辦法在DB級別隱藏。切表難。如果發(fā)現(xiàn)一張表的龐大需要切表。這個(gè)時(shí)候就比較糾結(jié)了。如果一刀切,partion Key的選擇;索引的失效都會成為問題。如果覺得拆為兩張表,就會很好操作的話,就是內(nèi)聯(lián)的過度使用了 。備份難。關(guān)系數(shù)據(jù)庫中每張表可以有不同的備份策略。但是如果內(nèi)聯(lián)起來,這樣的備份就做不到了。解決辦法:設(shè)計(jì)數(shù)據(jù)庫模型的時(shí)候需要考量之后的維護(hù)操作,尤其是內(nèi)聯(lián)的字段需不需要單獨(dú)的維護(hù)。需要和運(yùn)維商量。如果對內(nèi)聯(lián)的字段有單獨(dú)維護(hù)的要求,可以拆分出來作為引用。

問題四 盯死應(yīng)用的內(nèi)聯(lián)癥狀:應(yīng)用可以非常好的運(yùn)行在數(shù)據(jù)庫上。但是當(dāng)新的應(yīng)用接入的時(shí)候會很麻煩。因?yàn)樵O(shè)計(jì)數(shù)據(jù)模型的時(shí)候考慮到了查詢。所以當(dāng)有新應(yīng)用,新查詢接入的時(shí)候,就會難于使用原有的模型。

壞處:

新應(yīng)用接入難。當(dāng)新的應(yīng)用試圖使用同一個(gè)數(shù)據(jù)庫的時(shí)候,接入比較困難。因?yàn)椴樵儠r(shí)不同的,需要調(diào)整數(shù)據(jù)模型才能適應(yīng)。但是調(diào)整模型又會影響原有應(yīng)用。集成難。不同的關(guān)系型數(shù)據(jù)庫可以集成在一起,共同使用。但是對于文檔數(shù)據(jù)庫,雖然功能上可以互補(bǔ),但是由于內(nèi)聯(lián)數(shù)據(jù)結(jié)構(gòu)的差異,也比較難于集成。ETL難。現(xiàn)在大部分的數(shù)據(jù)分析系統(tǒng)使用的是關(guān)系模型,就連Hadoop雖然不用關(guān)系模型,但是其上的Hive的常用工具也是按關(guān)系模型設(shè)計(jì)的。

解決方案:

使用范式設(shè)計(jì)數(shù)據(jù)庫,即用引用代替內(nèi)聯(lián)。或者在使用內(nèi)聯(lián)的時(shí)候,給每個(gè)內(nèi)聯(lián)對象一個(gè)全局唯一的Key,保證其和關(guān)系模型直接可以存在映射關(guān)系,這樣可以提高數(shù)據(jù)模型的靈活性。如Blog表:

 

Blog_id

content

Comment[]

……

0

“…”

[{"id"=1,"content"=“NoSQL反模式是好文章”}, {"id"=2,"content"=“是啊”}…]

……

 

這樣的設(shè)計(jì)既可以利用到內(nèi)聯(lián)的好處,又能將其和關(guān)系模型映射起來。確定是需要手動(dòng)維護(hù)comment_id,保證其全局唯一性。

 

反模式四:在線計(jì)算

癥狀:有一些運(yùn)行時(shí)間很長的Query,由于有聚合計(jì)算,索引也不能解決。隨著數(shù)據(jù)量的增長,逐漸成為性能瓶頸。

壞處:

影響用戶體驗(yàn)。在線業(yè)務(wù)中,如果一個(gè)查詢大于4s,用戶體驗(yàn)會急劇下降。按主鍵和按索引的查詢都能滿足要求。但是聚合操作往往需要掃描全表或者大量的數(shù)據(jù),隨著數(shù)據(jù)量的增加,查詢時(shí)間會變長,用戶不可容忍。影響數(shù)據(jù)庫性能。長查詢的壞處數(shù)不清。在線上應(yīng)用中,如果出現(xiàn)長查詢,可能會霸占數(shù)據(jù)的大部分資源,包括IO,連接,CPU等等。導(dǎo)致其他很好的查詢,輕則性能也下降,重者無法使用數(shù)據(jù)庫。長查詢可以稱之為DB殺手。

解決方案:首先要權(quán)衡,這個(gè)聚合操作是不是必要的,必須實(shí)時(shí)完成。如果沒有必要實(shí)時(shí)完成的話,可以采取離線操作的方案。在夜深人靜的時(shí)候,跑一個(gè)長查詢,將結(jié)果緩存起來,給第二天使用。如果必須實(shí)時(shí)完成,則可以新建一個(gè)字段,用“incr”這樣的操作,在運(yùn)行的時(shí)候,實(shí)時(shí)聚合結(jié)果。而不是查詢的時(shí)候執(zhí)行一次長查詢。如果邏輯比較復(fù)雜,或者覺得大量“incr”操作給數(shù)據(jù)庫系統(tǒng)帶來了壓力,可以使用Storm之類的實(shí)時(shí)數(shù)據(jù)處理框架。總之,要慎用長查詢。

反模式五:把內(nèi)聯(lián)Map對象的Key當(dāng)作ID用

癥狀:文檔數(shù)據(jù)庫支持內(nèi)聯(lián)Map類型。將其中Map的Key當(dāng)作數(shù)據(jù)庫的主鍵來用。

 

Blog_id

content

Comment{}

……

0

“…”

{"1"=“NoSQL反模式是好文章”, "2"=“是啊”}

……

這個(gè)反模式很容易犯,因?yàn)樵诰幊陶Z言中Map數(shù)據(jù)結(jié)構(gòu)就是這么用的。但是對于數(shù)據(jù)庫模型來說,這是不折不扣的反模式。

 

壞處:

無法通過數(shù)據(jù)庫做各種(><=)查詢。對于關(guān)系型數(shù)據(jù)庫來說,雖然數(shù)據(jù)結(jié)構(gòu)可以很靈活,但查詢的時(shí)候都是按層次的。比如comment.id,comment.content。也就是說其Map類型中的Key可以理解為屬性名的,而不是用作ID。因此一旦這樣使用,就脫離的數(shù)據(jù)庫管制,無法使用各種查詢功能。無法通過索引查詢。文檔數(shù)據(jù)可建立索引是需要列名的。比如comment.id。而這樣的數(shù)據(jù)結(jié)構(gòu)沒有固定的列名,因此無法建立索引。

解決方案:使用數(shù)組+Map來解決。如:

 

Blog_id

content

Comment[]

……

0

“…”

[{"id"=1,"content"=“NoSQL反模式是好文章”}, {"id"=2,"content"=“是啊”}…]

……

這樣,就可以使用comment.id作為索引,也可以使用數(shù)據(jù)庫的查詢功能。簡單有效。Map類型中的Key是屬性名,Value是屬性值。這樣的用法是文檔數(shù)據(jù)庫數(shù)據(jù)模型的本意,因此其提供的各種功能才能利用上。否則就無法使用。

 

 

反模式六:不合理的ID

癥狀:使用String甚至更復(fù)雜數(shù)據(jù)結(jié)構(gòu)作為的ID,或者全部使用數(shù)據(jù)庫提供的自生成ID。如:

 

id(該ID系系統(tǒng)自生成)

Blog_id

content

……

0

0

...

……

壞處:

 

ID混亂。如果使用數(shù)據(jù)庫提供的自生成ID,同時(shí)表中還有一個(gè)類似有主鍵含義的Blog_id,這樣很不好,容易造成邏輯混亂。由于文檔數(shù)據(jù)庫不支持ID的重命名,習(xí)慣關(guān)系數(shù)據(jù)庫做法的人可能會再建立一個(gè)自己的邏輯ID字段。這是沒有必要的。索引龐大,性能低下。ID是數(shù)據(jù)庫的非常重要的部分。ID的長度將決定索引(包括主鍵的索引)的大小,直接影響到數(shù)據(jù)庫性能。如果索引比內(nèi)存小,性能會很好。但一旦索引大小超過內(nèi)存,出現(xiàn)數(shù)據(jù)交換,性能會急劇下降。一個(gè)Long占8字節(jié),一個(gè)20個(gè)字符的UTF8 String占用約60個(gè)字節(jié)。相差10倍之巨,不能不考慮。

解決方案:盡量使用有一定意義的字段做ID,并且不在其他字段中重復(fù)出現(xiàn)。不使用復(fù)雜的數(shù)據(jù)類型做ID,只使用int,long或者系統(tǒng)提供的主鍵類型做ID。

文檔數(shù)據(jù)庫的反模式總結(jié)

闡述了這么多的反模式,下面有個(gè)一覽表,涵蓋了上面所有的反模式。這個(gè)一覽表,是按照文檔數(shù)據(jù)庫模型建立的。是個(gè)文檔數(shù)據(jù)庫模型的例子。

 

ID

反模式名

問題

0

存在描述多對多的關(guān)系表

[{ID:00
癥狀:文檔數(shù)據(jù)庫中存儲在有純粹的關(guān)系表
壞處:[破壞數(shù)據(jù)完備性,索引過多]
解決方案:加入一個(gè)List字段
},{
ID:01
癥狀:關(guān)系模型不區(qū)分“一對多”和“多對一”
壞處:額外索引
解決方案:合理的安排字段的位置
}]

1

處處引用客戶端Join

[{
ID:10
癥狀:查詢的時(shí)候需要大量的手動(dòng)Join操作
壞處:[手動(dòng)Join,多次查詢, 事務(wù)處理繁瑣]
解決方案:適當(dāng)使用內(nèi)聯(lián)數(shù)據(jù)結(jié)構(gòu)。
}]

2

濫用內(nèi)聯(lián)后患無窮

[{
ID:20
癥狀:頻繁查詢一些內(nèi)聯(lián)字段,丟棄其他字段
壞處:[無ID約束,索引泛濫, 性能浪費(fèi)]
解決方案:使用引用代替內(nèi)聯(lián)了,允許重復(fù)數(shù)據(jù)
},{
ID:21
癥狀:List,Map類型的內(nèi)聯(lián)字段不斷膨脹,而且沒有限制
壞處:[插入失敗, 性能拖油瓶]
解決方案:設(shè)定最大數(shù)目或者使用引用。
},{
ID:22
癥狀:DBA想單獨(dú)維護(hù)內(nèi)聯(lián)字段,但無法做到
壞處:[權(quán)限管理難, 切表難, 備份難]
解決方案:設(shè)計(jì)數(shù)據(jù)庫模型的時(shí)候需要考量之后的維護(hù)操作
},{
ID:23
癥狀:應(yīng)用可以非常好的運(yùn)行在數(shù)據(jù)庫上。但是當(dāng)新的應(yīng)用接入的時(shí)候會很麻煩。內(nèi)聯(lián)盯死了應(yīng)用
壞處:[新應(yīng)用接入難, 集成難, ETL難]
解決方案:使用范式設(shè)計(jì)數(shù)據(jù)庫,即用引用代替內(nèi)聯(lián)。保證其和關(guān)系模型直接可以存在映射關(guān)系
}]

3

在線計(jì)算

[{
ID:30
癥狀:有一些運(yùn)行時(shí)間很長的Query, 逐漸成為性能瓶頸。
壞處:[影響用戶體驗(yàn),影響數(shù)據(jù)庫性能]
解決方案:取消不必要的聚合操作. 運(yùn)行的時(shí)候,實(shí)時(shí)聚合結(jié)果.使用第三方實(shí)時(shí)或非實(shí)時(shí)工具。如Hadoop,Storm.
}]

4

把內(nèi)聯(lián)Map對象的Key當(dāng)作ID用

[{
ID:40
癥狀:文檔數(shù)據(jù)庫支持內(nèi)聯(lián)Map類型。將其中Map的Key當(dāng)作數(shù)據(jù)庫的主鍵來用。
壞處:[無法通過數(shù)據(jù)庫做各種(><""" =)查詢,無法通過索引查詢]
解決方案:使用數(shù)組+Map來解決。
}]

5

不合理的ID

[{
ID:50
癥狀:用String甚至更復(fù)雜數(shù)據(jù)結(jié)構(gòu)作為的ID,或者全部使用數(shù)據(jù)庫提供的自生成ID。
壞處:[ID混亂,索引龐大]
解決方案:盡量使用有一定意義的字段做ID。不使用復(fù)雜的數(shù)據(jù)類型做ID。
}]

 

本文試圖總結(jié)了筆者知道的重要的文檔數(shù)據(jù)庫的反模式。現(xiàn)在關(guān)于NoSQL數(shù)據(jù)模型設(shè)計(jì)模式的討論才剛剛起步,將來也許會逐漸自成體系。對于列數(shù)據(jù)庫和Key-Value的反模式,筆者等到有了足夠積累的時(shí)候,再和大家分享。

延伸 · 閱讀

精彩推薦
  • MongoDBMongodb實(shí)現(xiàn)定時(shí)備份與恢復(fù)的方法教程

    Mongodb實(shí)現(xiàn)定時(shí)備份與恢復(fù)的方法教程

    這篇文章主要給大家介紹了Mongodb實(shí)現(xiàn)定時(shí)備份與恢復(fù)的方法教程,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面...

    chenjsh364522020-05-13
  • MongoDBmongodb基本命令實(shí)例小結(jié)

    mongodb基本命令實(shí)例小結(jié)

    這篇文章主要介紹了mongodb基本命令,結(jié)合實(shí)例形式總結(jié)分析了MongoDB數(shù)據(jù)庫切換、查看、刪除、查詢等基本命令用法與操作注意事項(xiàng),需要的朋友可以參考下...

    dawn-liu3652020-05-26
  • MongoDBMongoDB 內(nèi)存使用情況分析

    MongoDB 內(nèi)存使用情況分析

    都說 MongoDB 是個(gè)內(nèi)存大戶,但是怎么知道它到底用了多少內(nèi)存呢...

    MongoDB教程網(wǎng)10002020-09-29
  • MongoDBMongoDB憑什么躋身數(shù)據(jù)庫排行前五

    MongoDB憑什么躋身數(shù)據(jù)庫排行前五

    MongoDB以比去年同期超出65.96分的成績繼續(xù)雄踞榜單前五,這個(gè)增幅在全榜僅次于PostgreSQL的77.99,而其相對于4月份的6.10分的增長也是僅次于微軟SQL Server排名...

    孫浩峰3892020-05-22
  • MongoDBMongoDB中javascript腳本編程簡介和入門實(shí)例

    MongoDB中javascript腳本編程簡介和入門實(shí)例

    作為一個(gè)數(shù)據(jù)庫,MongoDB有一個(gè)很大的優(yōu)勢——它使用js管理數(shù)據(jù)庫,所以也能夠使用js腳本進(jìn)行復(fù)雜的管理——這種方法非常靈活 ...

    MongoDB教程網(wǎng)6982020-04-24
  • MongoDB分布式文檔存儲數(shù)據(jù)庫之MongoDB分片集群的問題

    分布式文檔存儲數(shù)據(jù)庫之MongoDB分片集群的問題

    這篇文章主要介紹了分布式文檔存儲數(shù)據(jù)庫之MongoDB分片集群的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋...

    Linux-18743072020-12-20
  • MongoDB遷移sqlserver數(shù)據(jù)到MongoDb的方法

    遷移sqlserver數(shù)據(jù)到MongoDb的方法

    這篇文章主要介紹了遷移sqlserver數(shù)據(jù)到MongoDb的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下...

    聽楓xl9682021-01-03
  • MongoDBMongoDB安裝圖文教程

    MongoDB安裝圖文教程

    這篇文章主要為大家詳細(xì)介紹了MongoDB安裝圖文教程,分為兩大部分為大家介紹下載MongoDB和安裝MongoDB的方法,感興趣的小伙伴們可以參考一下 ...

    Yangyi.He6132020-05-07
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产午夜一区二区三区 | 欧美视频免费 | 久久福利电影 | av免费网| 婷婷激情五月 | 激情五月激情综合网 | 黄色片在线 | 欧美成人精品一区二区男人看 | 色综合88| 国产精品一区二区三区免费 | 久久毛片 | 日本三级中文在线电影 | 中文字幕一区二区三区乱码图片 | 亚洲一区二区三区四区五区中文 | 成年人在线看片 | 国产精品一区二区视频 | 中文字幕精品视频 | 电影在线观看免费 | 中文字幕亚洲欧美日韩在线不卡 | 毛片免费在线播放 | 一区二区三区在线播放 | 国产成人黄色 | 噜噜噜在线 | 自拍偷拍欧美 | 一级做a爰片久久毛片免费陪 | 亚洲精品乱码久久久久久蜜桃不爽 | 亚洲精品视频在线观看网站 | 日韩成人免费 | 久久合 | 天天干夜夜操 | 久草成人网 | 欧美日韩国产在线播放 | 日韩中文字幕无码一区二区三区 | av在线一区二区三区 | 日本天天操 | 成人精品在线视频 | 中文字幕乱码视频32 | 久久精品久久综合 | av在线电影网站 | 国产剧情一区二区 | 无码日韩精品一区二区免费 |